From 34419e3631d1e7e22441e611f686f6f9ca27b12a Mon Sep 17 00:00:00 2001
From: "Owen W. Taylor" <otaylor@fishsoup.net>
Date: Thu, 11 Feb 2016 17:04:08 -0500
Subject: [PATCH 4/6] Usability of SGI_video_sync is per-display not
per-renderer
As previously commented in the code, SGI_video_sync is per-display, rather
than per-renderer. The is_direct flag for the renderer was tested before
it was initialized (per-display) and that resulted in SGI_video_sync
never being used.
---
cogl/cogl-glx-display-private.h | 3 +++
cogl/cogl-glx-renderer-private.h | 2 --
cogl/winsys/cogl-winsys-glx.c | 52 +++++++++++++++++++++-------------------
3 files changed, 31 insertions(+), 26 deletions(-)
diff --git a/cogl/cogl-glx-display-private.h b/cogl/cogl-glx-display-private.h
index 133c118..1d1afc0 100644
--- a/cogl/cogl-glx-display-private.h
+++ b/cogl/cogl-glx-display-private.h
@@ -51,6 +51,9 @@ typedef struct _CoglGLXDisplay
CoglBool found_fbconfig;
CoglBool fbconfig_has_rgba_visual;
+ CoglBool is_direct;
+ CoglBool have_vblank_counter;
+ CoglBool can_vblank_wait;
GLXFBConfig fbconfig;
/* Single context for all wins */
diff --git a/cogl/cogl-glx-renderer-private.h b/cogl/cogl-glx-renderer-private.h
index cb8ff97..061f2cc 100644
--- a/cogl/cogl-glx-renderer-private.h
+++ b/cogl/cogl-glx-renderer-private.h
@@ -43,8 +43,6 @@ typedef struct _CoglGLXRenderer
int glx_error_base;
int glx_event_base;
- CoglBool is_direct;
-
/* Vblank stuff */
int dri_fd;
diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c
index 4450365..cd0b211 100644
--- a/cogl/winsys/cogl-winsys-glx.c
+++ b/cogl/winsys/cogl-winsys-glx.c
@@ -710,23 +710,25 @@ update_base_winsys_features (CoglRenderer *renderer)
g_strfreev (split_extensions);
- /* Note: the GLX_SGI_video_sync spec explicitly states this extension
- * only works for direct contexts. */
- if (!glx_renderer->is_direct)
- {
- glx_renderer->glXGetVideoSync = NULL;
- glx_renderer->glXWaitVideoSync = NULL;
- COGL_FLAGS_SET (glx_renderer->base_winsys_features,
- COGL_WINSYS_FEATURE_VBLANK_COUNTER,
- FALSE);
- }
+ /* The GLX_SGI_video_sync spec explicitly states this extension
+ * only works for direct contexts; we don't know per-renderer
+ * if the context is direct or not, so we turn off the feature
+ * flag; we still use the extension within this file looking
+ * instead at glx_display->have_vblank_counter.
+ */
+ COGL_FLAGS_SET (glx_renderer->base_winsys_features,
+ COGL_WINSYS_FEATURE_VBLANK_COUNTER,
+ FALSE);
+
COGL_FLAGS_SET (glx_renderer->base_winsys_features,
COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
TRUE);
- if (glx_renderer->glXWaitVideoSync ||
- glx_renderer->glXWaitForMsc)
+ /* Because of the direct-context dependency, the VBLANK_WAIT feature
+ * doesn't reflect the presence of GLX_SGI_video_sync.
+ */
+ if (glx_renderer->glXWaitForMsc)
COGL_FLAGS_SET (glx_renderer->base_winsys_features,
COGL_WINSYS_FEATURE_VBLANK_WAIT,
TRUE);
@@ -859,7 +861,7 @@ update_winsys_features (CoglContext *context, CoglError **error)
* by the SwapInterval so we have to throttle swap_region requests
* manually... */
if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION) &&
- _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT))
+ (glx_display->have_vblank_counter || glx_display->can_vblank_wait))
COGL_FLAGS_SET (context->winsys_features,
COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE);
@@ -1096,11 +1098,13 @@ create_context (CoglDisplay *display, CoglError **error)
return FALSE;
}
- glx_renderer->is_direct =
+ glx_display->is_direct =
glx_renderer->glXIsDirect (xlib_renderer->xdpy, glx_display->glx_context);
+ glx_display->have_vblank_counter = glx_display->is_direct && glx_renderer->glXWaitVideoSync;
+ glx_display->can_vblank_wait = glx_renderer->glXWaitForMsc || glx_display->have_vblank_counter;
COGL_NOTE (WINSYS, "Setting %s context",
- glx_renderer->is_direct ? "direct" : "indirect");
+ glx_display->is_direct ? "direct" : "indirect");
/* XXX: GLX doesn't let us make a context current without a window
* so we create a dummy window that we can use while no CoglOnscreen
@@ -1612,12 +1616,13 @@ _cogl_winsys_wait_for_vblank (CoglOnscreen *onscreen)
CoglContext *ctx = framebuffer->context;
CoglGLXRenderer *glx_renderer;
CoglXlibRenderer *xlib_renderer;
+ CoglGLXDisplay *glx_display;
glx_renderer = ctx->display->renderer->winsys;
xlib_renderer = _cogl_xlib_renderer_get_data (ctx->display->renderer);
+ glx_display = ctx->display->winsys;
- if (glx_renderer->glXWaitForMsc ||
- glx_renderer->glXGetVideoSync)
+ if (glx_display->can_vblank_wait)
{
CoglFrameInfo *info = g_queue_peek_tail (&onscreen->pending_frame_infos);
@@ -1713,6 +1718,7 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (context->display->renderer);
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
+ CoglGLXDisplay *glx_display = context->display->winsys;
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
GLXDrawable drawable =
@@ -1769,9 +1775,8 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
if (framebuffer->config.swap_throttled)
{
- have_counter =
- _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_COUNTER);
- can_wait = _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT);
+ have_counter = glx_display->have_vblank_counter;
+ can_wait = glx_display->can_vblank_wait;
}
else
{
@@ -1928,6 +1933,7 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (context->display->renderer);
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
+ CoglGLXDisplay *glx_display = context->display->winsys;
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
CoglBool have_counter;
@@ -1947,8 +1953,7 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
{
uint32_t end_frame_vsync_counter = 0;
- have_counter =
- _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_COUNTER);
+ have_counter = glx_display->have_vblank_counter;
/* If the swap_region API is also being used then we need to track
* the vsync counter for each swap request so we can manually
@@ -1958,8 +1963,7 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
if (!glx_renderer->glXSwapInterval)
{
- CoglBool can_wait =
- _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT);
+ CoglBool can_wait = glx_display->can_vblank_wait;
/* If we are going to wait for VBLANK manually, we not only
* need to flush out pending drawing to the GPU before we
--
1.8.3.1