Re: [patch] boilerplate/gl: use glFlush instead of glFinish
Matt Sealey <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <CAHCPf3tgLEKxgrvL3=7F5RHPOZszn=tev9eCDg7j_t89i3dafQ@mail.gmail.com> |
On Thu, Aug 29, 2013 at 3:41 PM, Henry (Yu) Song - SISA <[email protected]> wrote: > From 73c77248ed95b3f9f6a777d86c368e464f3b49bb Mon Sep 17 00:00:00 2001 > From: Henry Song <[email protected]> > Date: Thu, 29 Aug 2013 13:35:11 -0700 > Subject: [PATCH] boilerplate/gl: use glFlush instead of glFinish for > synchronization > > Use glFlush () is a proper way to indicate a surface/frame finish > instead of a glFinish. Applications very rarely use glFinish (). > For offscreen, a glFlush () should be used to indicate finish drawings > onto a surface. For onscreen, an eglSwapBuffers/glXSwapBuffers should > be used (internal, it calls glFlush). > > Using glFlush () computes performance more accurately folllowing app > usage model. That entire commit message is contrary to the OpenGL specification; glFlush() can return at any time, it is a hint to the graphics driver to empty/flush/commit buffers, command streams and so on - but it does not guarantee that these commands and buffers are 'complete' and in fact can return immediately. If you perform any actions which use a different GPU or the CPU on those buffers, there is no guarantee at the glFlush() call return that the rendered data is even in your target surface. Just that the GPU has been told that it should get there. What you get with glFlush() vs. glFinish() is 9 billion frames which seem perfect and the '9 billion and one'th frame will not be fully rendered offscreen before the next actor wants to use it. You don't notice this most of the time in a microbenchmark or so, and the effects would be essentially hidden until you implement it on a system where there is a lot more going on. The only correct way to perform a synchronization event - which is what the functions below are doing - is glFinish(). The 'official' and most effective performance solution to the lack of guarantee of glFlush vs. the performance penalty of glFinish is extensions such as fences (i.e. GL_NV_fence) to ensure completion of rendering without the penalty of a full flush or finish. Fences are, by that extension spec, mostly the same functionality at much lower overhead (although, at the expense of having to micromanage fences) http://www.opengl.org/registry/specs/NV/fence.txt The overview of the extension exactly describes your issue and why using glFlush instead of glFinish is not correct behavior :) > --- a/boilerplate/cairo-boilerplate-glx.c > +++ b/boilerplate/cairo-boilerplate-glx.c > @@ -353,7 +353,7 @@ _cairo_boilerplate_gl_synchronize (void *closure) > if (cairo_device_acquire (gltc->device)) > return; > > - glFinish (); > + glFlush (); -- cairo mailing list [email protected] http://lists.cairographics.org/mailman/listinfo/cairo