Occasionally, I’m seeing the SDL message pump is taking a little under or a little over 16ms, which is taking up most of or more than the target update time when running at at 60 FPS, and it’s making movement appear a little jittery because it’s causing me to miss a render when it occurs. I made a minimalist project that does nothing but initialize SDL, run the message pump, and measure the time it takes. In this example it happens infrequently, but it still does happen. In my actual project which creates a window and handles input, it happens more frequently. It doesn’t seem to even have any events to process, so I’m wondering why it’s taking this much time sometimes. Is this something that others have dealt with before? And if so, how? I’ve tried running the message pump in a separate thread, but it didn’t quite work and I found in this thread that it’s not a great idea: Can I use sdl in a new thread not the main thread?
I ran the following code for a short amount of time before stopping it, and it produced this output :
Event 4352 occurred in frame 0
Event 4352 occurred in frame 0
Event 4352 occurred in frame 0
Event 4352 occurred in frame 0
Event 4352 occurred in frame 0
Event 4352 occurred in frame 0
Message pump took 14.1873ms in frame 5593754
Message pump took 14.534ms in frame 10138807
Message pump took 14.6506ms in frame 14347071
Message pump took 18.0639ms in frame 18368433
Message pump took 15.0153ms in frame 19822911
Message pump took 17.4009ms in frame 45332387
Message pump took 17.9429ms in frame 54562594
#include <iostream>
#include “SDL.h”
#include “Windows.h”
int main(int argc, char* args) {
int sdlErrorCode = SDL_Init(SDL_INIT_EVERYTHING);
if (sdlErrorCode < 0) {
std::cout << "SDL Initialization failed."
<< std::endl
<< "Error: " << SDL_GetError() << std::endl;
return -1;
}
SDL_Event event;
uint32_t frameCounter = 0;
bool quit = false;
uint64_t ticksPerSecond;
QueryPerformanceFrequency((LARGE_INTEGER*)&ticksPerSecond);
while (quit == false) {
uint64_t start;
QueryPerformanceCounter((LARGE_INTEGER*)&start);
while (SDL_PollEvent(&event)) {
std::cout << "Event " << event.type
<< " occurred in frame " << frameCounter << std::endl;
switch (event.type) {
case SDL_QUIT:
quit = true;
break;
}
}
// Measure the message pump time.
uint64_t end;
QueryPerformanceCounter((LARGE_INTEGER*)&end);
uint64_t duration = end - start;
// Convert duration to milliseconds
uint64_t seconds = duration / ticksPerSecond;
uint64_t remainder = duration % ticksPerSecond;
double durationMsec = (((double)remainder / (double)ticksPerSecond) * 1000L) + (seconds * 1000L);
// Print outliers that take up at least half of the target time
if (durationMsec > 8.0) {
std::cout << "Message pump took " << durationMsec
<< "ms in frame " << frameCounter << std::endl;
}
frameCounter++;
}
return 0;
}