[mutter] Usability of SGI_video_sync is per-display not per-renderer



commit 1b03dd6704abfc0182de61ef86c91c9e2a2639cf
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Thu Feb 11 17:04:08 2016 -0500

    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.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=779039

 cogl/cogl/cogl-glx-display-private.h  |    3 ++
 cogl/cogl/cogl-glx-renderer-private.h |    2 -
 cogl/cogl/winsys/cogl-winsys-glx.c    |   52 +++++++++++++++++---------------
 3 files changed, 31 insertions(+), 26 deletions(-)
---
diff --git a/cogl/cogl/cogl-glx-display-private.h b/cogl/cogl/cogl-glx-display-private.h
index 133c118..1d1afc0 100644
--- a/cogl/cogl/cogl-glx-display-private.h
+++ b/cogl/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/cogl-glx-renderer-private.h b/cogl/cogl/cogl-glx-renderer-private.h
index cb8ff97..061f2cc 100644
--- a/cogl/cogl/cogl-glx-renderer-private.h
+++ b/cogl/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/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
index 379658e..5a27001 100644
--- a/cogl/cogl/winsys/cogl-winsys-glx.c
+++ b/cogl/cogl/winsys/cogl-winsys-glx.c
@@ -715,23 +715,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);
@@ -864,7 +866,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);
 
@@ -1142,11 +1144,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
@@ -1658,12 +1662,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);
 
@@ -1759,6 +1764,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 =
@@ -1815,9 +1821,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
     {
@@ -1974,6 +1979,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;
@@ -1993,8 +1999,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
@@ -2004,8 +2009,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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]