test/testautomation_timer.c
author Cameron Gutman <cameron.gutman@gmail.com>
Sat, 03 Nov 2018 15:46:42 -0700
changeset 13122 830cadcdc1a2
parent 11272 d60ede5a0c2e
permissions -rw-r--r--
Reduce delay to 1 ms in SDL_WaitEventTimeout() and SDL_WaitEvent()

The 10 ms delay effectively caps input polling at 100 Hz and rendering
at 100 FPS if applications use these functions in their event loop. The
delay may also lead to dropped frames even at 60 FPS due if they are
unlucky enough to hit the delay and rendering takes longer than 6 ms.
     1 /**
     2  * Timer test suite
     3  */
     4 
     5 #include <stdio.h>
     6 
     7 #include "SDL.h"
     8 #include "SDL_test.h"
     9 
    10 /* Flag indicating if the param should be checked */
    11 int _paramCheck = 0;
    12 
    13 /* Userdata value to check */
    14 int _paramValue = 0;
    15 
    16 /* Flag indicating that the callback was called */
    17 int _timerCallbackCalled = 0;
    18 
    19 /* Fixture */
    20 
    21 void
    22 _timerSetUp(void *arg)
    23 {
    24     /* Start SDL timer subsystem */
    25     int ret = SDL_InitSubSystem( SDL_INIT_TIMER );
    26         SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_TIMER)");
    27     SDLTest_AssertCheck(ret==0, "Check result from SDL_InitSubSystem(SDL_INIT_TIMER)");
    28     if (ret != 0) {
    29            SDLTest_LogError("%s", SDL_GetError());
    30         }
    31 }
    32 
    33 /* Test case functions */
    34 
    35 /**
    36  * @brief Call to SDL_GetPerformanceCounter
    37  */
    38 int
    39 timer_getPerformanceCounter(void *arg)
    40 {
    41   Uint64 result;
    42 
    43   result = SDL_GetPerformanceCounter();
    44   SDLTest_AssertPass("Call to SDL_GetPerformanceCounter()");
    45   SDLTest_AssertCheck(result > 0, "Check result value, expected: >0, got: %"SDL_PRIu64, result);
    46 
    47   return TEST_COMPLETED;
    48 }
    49 
    50 /**
    51  * @brief Call to SDL_GetPerformanceFrequency
    52  */
    53 int
    54 timer_getPerformanceFrequency(void *arg)
    55 {
    56   Uint64 result;
    57 
    58   result = SDL_GetPerformanceFrequency();
    59   SDLTest_AssertPass("Call to SDL_GetPerformanceFrequency()");
    60   SDLTest_AssertCheck(result > 0, "Check result value, expected: >0, got: %"SDL_PRIu64, result);
    61 
    62   return TEST_COMPLETED;
    63 }
    64 
    65 /**
    66  * @brief Call to SDL_Delay and SDL_GetTicks
    67  */
    68 int
    69 timer_delayAndGetTicks(void *arg)
    70 {
    71   const Uint32 testDelay = 100;
    72   const Uint32 marginOfError = 25;
    73   Uint32 result;
    74   Uint32 result2;
    75   Uint32 difference;
    76 
    77   /* Zero delay */
    78   SDL_Delay(0);
    79   SDLTest_AssertPass("Call to SDL_Delay(0)");
    80 
    81   /* Non-zero delay */
    82   SDL_Delay(1);
    83   SDLTest_AssertPass("Call to SDL_Delay(1)");
    84 
    85   SDL_Delay(SDLTest_RandomIntegerInRange(5, 15));
    86   SDLTest_AssertPass("Call to SDL_Delay()");
    87 
    88   /* Get ticks count - should be non-zero by now */
    89   result = SDL_GetTicks();
    90   SDLTest_AssertPass("Call to SDL_GetTicks()");
    91   SDLTest_AssertCheck(result > 0, "Check result value, expected: >0, got: %d", result);
    92 
    93   /* Delay a bit longer and measure ticks and verify difference */
    94   SDL_Delay(testDelay);
    95   SDLTest_AssertPass("Call to SDL_Delay(%d)", testDelay);
    96   result2 = SDL_GetTicks();
    97   SDLTest_AssertPass("Call to SDL_GetTicks()");
    98   SDLTest_AssertCheck(result2 > 0, "Check result value, expected: >0, got: %d", result2);
    99   difference = result2 - result;
   100   SDLTest_AssertCheck(difference > (testDelay - marginOfError), "Check difference, expected: >%d, got: %d", testDelay - marginOfError, difference);
   101   SDLTest_AssertCheck(difference < (testDelay + marginOfError), "Check difference, expected: <%d, got: %d", testDelay + marginOfError, difference);
   102 
   103   return TEST_COMPLETED;
   104 }
   105 
   106 /* Test callback */
   107 Uint32 SDLCALL _timerTestCallback(Uint32 interval, void *param)
   108 {
   109    _timerCallbackCalled = 1;
   110 
   111    if (_paramCheck != 0) {
   112        SDLTest_AssertCheck(param != NULL, "Check param pointer, expected: non-NULL, got: %s", (param != NULL) ? "non-NULL" : "NULL");
   113        if (param != NULL) {
   114           SDLTest_AssertCheck(*(int *)param == _paramValue, "Check param value, expected: %i, got: %i", _paramValue, *(int *)param);
   115        }
   116    }
   117 
   118    return 0;
   119 }
   120 
   121 /**
   122  * @brief Call to SDL_AddTimer and SDL_RemoveTimer
   123  */
   124 int
   125 timer_addRemoveTimer(void *arg)
   126 {
   127   SDL_TimerID id;
   128   SDL_bool result;
   129   int param;
   130 
   131   /* Reset state */
   132   _paramCheck = 0;
   133   _timerCallbackCalled = 0;
   134 
   135   /* Set timer with a long delay */
   136   id = SDL_AddTimer(10000, _timerTestCallback, NULL);
   137   SDLTest_AssertPass("Call to SDL_AddTimer(10000,...)");
   138   SDLTest_AssertCheck(id > 0, "Check result value, expected: >0, got: %d", id);
   139 
   140   /* Remove timer again and check that callback was not called */
   141   result = SDL_RemoveTimer(id);
   142   SDLTest_AssertPass("Call to SDL_RemoveTimer()");
   143   SDLTest_AssertCheck(result == SDL_TRUE, "Check result value, expected: %i, got: %i", SDL_TRUE, result);
   144   SDLTest_AssertCheck(_timerCallbackCalled == 0, "Check callback WAS NOT called, expected: 0, got: %i", _timerCallbackCalled);
   145 
   146   /* Try to remove timer again (should be a NOOP) */
   147   result = SDL_RemoveTimer(id);
   148   SDLTest_AssertPass("Call to SDL_RemoveTimer()");
   149   SDLTest_AssertCheck(result == SDL_FALSE, "Check result value, expected: %i, got: %i", SDL_FALSE, result);
   150 
   151   /* Reset state */
   152   param = SDLTest_RandomIntegerInRange(-1024, 1024);
   153   _paramCheck = 1;
   154   _paramValue = param;
   155   _timerCallbackCalled = 0;
   156 
   157   /* Set timer with a short delay */
   158   id = SDL_AddTimer(10, _timerTestCallback, (void *)&param);
   159   SDLTest_AssertPass("Call to SDL_AddTimer(10, param)");
   160   SDLTest_AssertCheck(id > 0, "Check result value, expected: >0, got: %d", id);
   161 
   162   /* Wait to let timer trigger callback */
   163   SDL_Delay(100);
   164   SDLTest_AssertPass("Call to SDL_Delay(100)");
   165 
   166   /* Remove timer again and check that callback was called */
   167   result = SDL_RemoveTimer(id);
   168   SDLTest_AssertPass("Call to SDL_RemoveTimer()");
   169   SDLTest_AssertCheck(result == SDL_FALSE, "Check result value, expected: %i, got: %i", SDL_FALSE, result);
   170   SDLTest_AssertCheck(_timerCallbackCalled == 1, "Check callback WAS called, expected: 1, got: %i", _timerCallbackCalled);
   171 
   172   return TEST_COMPLETED;
   173 }
   174 
   175 /* ================= Test References ================== */
   176 
   177 /* Timer test cases */
   178 static const SDLTest_TestCaseReference timerTest1 =
   179         { (SDLTest_TestCaseFp)timer_getPerformanceCounter, "timer_getPerformanceCounter", "Call to SDL_GetPerformanceCounter", TEST_ENABLED };
   180 
   181 static const SDLTest_TestCaseReference timerTest2 =
   182         { (SDLTest_TestCaseFp)timer_getPerformanceFrequency, "timer_getPerformanceFrequency", "Call to SDL_GetPerformanceFrequency", TEST_ENABLED };
   183 
   184 static const SDLTest_TestCaseReference timerTest3 =
   185         { (SDLTest_TestCaseFp)timer_delayAndGetTicks, "timer_delayAndGetTicks", "Call to SDL_Delay and SDL_GetTicks", TEST_ENABLED };
   186 
   187 static const SDLTest_TestCaseReference timerTest4 =
   188         { (SDLTest_TestCaseFp)timer_addRemoveTimer, "timer_addRemoveTimer", "Call to SDL_AddTimer and SDL_RemoveTimer", TEST_ENABLED };
   189 
   190 /* Sequence of Timer test cases */
   191 static const SDLTest_TestCaseReference *timerTests[] =  {
   192     &timerTest1, &timerTest2, &timerTest3, &timerTest4, NULL
   193 };
   194 
   195 /* Timer test suite (global) */
   196 SDLTest_TestSuiteReference timerTestSuite = {
   197     "Timer",
   198     _timerSetUp,
   199     timerTests,
   200     NULL
   201 };