winsys-glx: Fix synchronisation behaviour in _cogl_winsys_onscreen_swap_region

This patch basically restores the logic from 1.6.  There we assumed that
glXCopySubBuffer won't tear and thus only needs to be throttled to the
framerate, while glBlitFramebuffer needs to always wait to avoid
tearing.

With Nvidia drivers specifically we have seen that glBlitFramebuffer is
not synchronized. Eventually the plan is that Cogl will actually take
into consideration the underlying driver/hw vendor and driver version
and we may want to only mark glBlitFramebuffer un-synchronized on
Nvidia.

https://bugzilla.gnome.org/show_bug.cgi?id=659360

Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
Adel Gadllah 2011-09-18 00:46:07 +02:00 committed by Robert Bragg
parent 3c82fd056c
commit 671a4dfb34
3 changed files with 16 additions and 2 deletions

View File

@ -668,6 +668,10 @@ typedef enum _CoglWinsysFeature
* to the vblank frequency. */
COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE,
/* Available if the swap region implementation won't tear and thus
* only needs to be throttled to the framerate */
COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED,
COGL_WINSYS_FEATURE_N_FEATURES
} CoglWinsysFeature;

View File

@ -89,7 +89,7 @@ COGL_WINSYS_FEATURE_BEGIN (copy_sub_buffer,
"copy_sub_buffer\0",
0,
0,
0)
COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED)
COGL_WINSYS_FEATURE_FUNCTION (void, glXCopySubBuffer,
(Display *dpy,
GLXDrawable drawable,

View File

@ -1127,6 +1127,16 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
guint32 end_frame_vsync_counter = 0;
gboolean have_counter;
gboolean can_wait;
/*
* We assume that glXCopySubBuffer is synchronized which means it won't prevent multiple
* blits per retrace if they can all be performed in the blanking period. If that's the
* case then we still want to use the vblank sync menchanism but
* we only need it to throttle redraws.
*/
gboolean blit_sub_buffer_is_synchronized =
_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED);
int framebuffer_height = cogl_framebuffer_get_height (framebuffer);
int *rectangles = g_alloca (sizeof (int) * n_rectangles * 4);
int i;
@ -1194,7 +1204,7 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
*/
context->glFinish ();
if (have_counter && can_wait)
if (blit_sub_buffer_is_synchronized && have_counter && can_wait)
{
end_frame_vsync_counter = _cogl_winsys_get_vsync_counter ();