aboutsummaryrefslogtreecommitdiffstats
path: root/examples/pugl_shader_demo.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-05-08 13:42:37 -0400
committerDavid Robillard <d@drobilla.net>2021-05-08 14:29:42 -0400
commitfcce346e6787875e6526efea89e74055e447f889 (patch)
tree3fa0589c678e1142bfa9a42ef939ae43c92d0e78 /examples/pugl_shader_demo.c
parent17ad5fd72bd51c5324b8e52e1f55020d5a97944a (diff)
downloadpugl-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.c62
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);
}