diff options
author | David Robillard <d@drobilla.net> | 2021-05-08 13:42:37 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2021-05-08 14:29:42 -0400 |
commit | fcce346e6787875e6526efea89e74055e447f889 (patch) | |
tree | 3fa0589c678e1142bfa9a42ef939ae43c92d0e78 /examples/pugl_shader_demo.c | |
parent | 17ad5fd72bd51c5324b8e52e1f55020d5a97944a (diff) | |
download | pugl-fcce346e6787875e6526efea89e74055e447f889.tar.gz pugl-fcce346e6787875e6526efea89e74055e447f889.tar.bz2 pugl-fcce346e6787875e6526efea89e74055e447f889.zip |
Send unmap/map events when the view is minimized/restored
X11 Window managers set WM_STATE to notify about minimization, often without
sending core X visibility events (which seems odd to me, but that's what Gnome
does anyway). So, implement this protocol and send map/unmap events to the
view, and adjust the Windows implementation to do the same for consistency
across all platforms.
Diffstat (limited to 'examples/pugl_shader_demo.c')
-rw-r--r-- | examples/pugl_shader_demo.c | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/examples/pugl_shader_demo.c b/examples/pugl_shader_demo.c index aa5c38e..2fd9a57 100644 --- a/examples/pugl_shader_demo.c +++ b/examples/pugl_shader_demo.c @@ -398,6 +398,41 @@ teardownGl(PuglTestApp* app) deleteProgram(app->drawRect); } +static double +updateTimeout(const PuglTestApp* const app) +{ + if (!puglGetVisible(app->view)) { + return -1.0; // View is invisible (minimized), wait until something happens + } + + if (!app->opts.sync) { + return 0.0; // VSync explicitly disabled, run as fast as possible + } + + /* To minimize input latency and get smooth performance during window + resizing, we want to poll for events as long as possible before starting + to draw the next frame. This ensures that as many events are consumed as + possible before starting to draw, or, equivalently, that the next rendered + frame represents the latest events possible. This is particularly + important for mouse input and "live" window resizing, where many events + tend to pile up within a frame. + + To do this, we keep track of the time when the last frame was finished + drawing, and how long it took to expose (and assume this is relatively + stable). Then, we can calculate how much time there is from now until the + time when we should start drawing to not miss the deadline, and use that + as the timeout for puglUpdate(). + */ + + const int refreshRate = puglGetViewHint(app->view, PUGL_REFRESH_RATE); + const double now = puglGetTime(app->world); + const double nextFrameEndTime = app->lastFrameEndTime + (1.0 / refreshRate); + const double nextExposeTime = nextFrameEndTime - app->lastDrawDuration; + const double timeUntilNext = nextExposeTime - now; + + return timeUntilNext; +} + int main(int argc, char** argv) { @@ -426,36 +461,11 @@ main(int argc, char** argv) printViewHints(app.view); puglShow(app.view); - // Calculate ideal frame duration to drive the main loop at a good rate - const int refreshRate = puglGetViewHint(app.view, PUGL_REFRESH_RATE); - const double frameDuration = 1.0 / (double)refreshRate; - // Grind away, drawing continuously const double startTime = puglGetTime(app.world); PuglFpsPrinter fpsPrinter = {startTime}; while (!app.quit) { - /* To minimize input latency and get smooth performance during window - resizing, we want to poll for events as long as possible before - starting to draw the next frame. This ensures that as many events - are consumed as possible before starting to draw, or, equivalently, - that the next rendered frame represents the latest events possible. - This is particularly important for mouse input and "live" window - resizing, where many events tend to pile up within a frame. - - To do this, we keep track of the time when the last frame was - finished drawing, and how long it took to expose (and assume this is - relatively stable). Then, we can calculate how much time there is - from now until the time when we should start drawing to not miss the - deadline, and use that as the timeout for puglUpdate(). - */ - - const double now = puglGetTime(app.world); - const double nextFrameEndTime = app.lastFrameEndTime + frameDuration; - const double nextExposeTime = nextFrameEndTime - app.lastDrawDuration; - const double timeUntilNext = nextExposeTime - now; - const double timeout = app.opts.sync ? timeUntilNext : 0.0; - - puglUpdate(app.world, fmax(0.0, timeout)); + puglUpdate(app.world, fmax(0.0, updateTimeout(&app))); puglPrintFps(app.world, &fpsPrinter, &app.framesDrawn); } |