[mutter] cogl-winsys-glx: Add support for NV_robustness_video_memory_purge



commit 87f9927375bfb34c984975cb6039580a2e99285d
Author: Rui Matos <tiagomatos gmail com>
Date:   Sun May 29 20:29:49 2016 +0200

    cogl-winsys-glx: Add support for NV_robustness_video_memory_purge
    
    This adds API to allow callers to specify that they're interested in
    video memory purge errors.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=739178

 cogl/cogl/cogl-renderer-private.h            |    1 +
 cogl/cogl/cogl-renderer.c                    |   10 ++++++
 cogl/cogl/cogl-xlib-renderer.h               |   41 ++++++++++++++++++++++++
 cogl/cogl/cogl.symbols                       |    1 +
 cogl/cogl/gl-prototypes/cogl-all-functions.h |    8 +++++
 cogl/cogl/winsys/cogl-winsys-glx.c           |   43 ++++++++++++++++++++++++++
 6 files changed, 104 insertions(+), 0 deletions(-)
---
diff --git a/cogl/cogl/cogl-renderer-private.h b/cogl/cogl/cogl-renderer-private.h
index 080bb32..06aa213 100644
--- a/cogl/cogl/cogl-renderer-private.h
+++ b/cogl/cogl/cogl-renderer-private.h
@@ -66,6 +66,7 @@ struct _CoglRenderer
 #ifdef COGL_HAS_XLIB_SUPPORT
   Display *foreign_xdpy;
   CoglBool xlib_enable_event_retrieval;
+  CoglBool xlib_want_reset_on_video_memory_purge;
 #endif
 
   CoglDriver driver;
diff --git a/cogl/cogl/cogl-renderer.c b/cogl/cogl/cogl-renderer.c
index fabaf81..498a00f 100644
--- a/cogl/cogl/cogl-renderer.c
+++ b/cogl/cogl/cogl-renderer.c
@@ -286,6 +286,16 @@ cogl_xlib_renderer_set_event_retrieval_enabled (CoglRenderer *renderer,
 
   renderer->xlib_enable_event_retrieval = enable;
 }
+
+void
+cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer,
+                                                        CoglBool enable)
+{
+  _COGL_RETURN_IF_FAIL (cogl_is_renderer (renderer));
+  _COGL_RETURN_IF_FAIL (!renderer->connected);
+
+  renderer->xlib_want_reset_on_video_memory_purge = enable;
+}
 #endif /* COGL_HAS_XLIB_SUPPORT */
 
 CoglBool
diff --git a/cogl/cogl/cogl-xlib-renderer.h b/cogl/cogl/cogl-xlib-renderer.h
index fdce06b..d33f830 100644
--- a/cogl/cogl/cogl-xlib-renderer.h
+++ b/cogl/cogl/cogl-xlib-renderer.h
@@ -173,6 +173,47 @@ cogl_xlib_renderer_get_display (CoglRenderer *renderer);
 XVisualInfo *
 cogl_xlib_renderer_get_visual_info (CoglRenderer *renderer);
 
+/**
+ * cogl_xlib_renderer_request_reset_on_video_memory_purge:
+ * @renderer: a #CoglRenderer
+ * @enable: The new value
+ *
+ * Sets whether Cogl should make use of the
+ * NV_robustness_video_memory_purge extension, if exposed by the
+ * driver, by initializing the GLX context appropriately.
+ *
+ * The extension is only useful when running on certain versions of
+ * the NVIDIA driver. Quoting from the spec:
+ *
+ * "The NVIDIA OpenGL driver architecture on Linux has a limitation:
+ *  resources located in video memory are not persistent across certain
+ *  events. VT switches, suspend/resume events, and mode switching
+ *  events may erase the contents of video memory. Any resource that
+ *  is located exclusively in video memory, such as framebuffer objects
+ *  (FBOs), will be lost."
+ *
+ * "This extension provides a way for applications to discover when video
+ *  memory content has been lost, so that the application can re-populate
+ *  the video memory content as necessary."
+ *
+ * "Any driver that exposes this extension is a driver that considers
+ *  video memory to be volatile. Once the driver stack has been
+ *  improved, the extension will no longer be exposed."
+ *
+ * cogl_get_graphics_reset_status() needs to be called at least once
+ * every frame to find out if video memory was purged.
+ *
+ * Note that this doesn't cause Cogl to enable robust buffer access
+ * but other context reset errors may still happen and be reported via
+ * cogl_get_graphics_reset_status() if external factors cause the
+ * driver to trigger them.
+ *
+ * This defaults to %FALSE and is effective only if called before
+ * cogl_display_setup() .
+ */
+void
+cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer,
+                                                        CoglBool enable);
 COGL_END_DECLS
 
 /* The gobject introspection scanner seems to parse public headers in
diff --git a/cogl/cogl/cogl.symbols b/cogl/cogl/cogl.symbols
index ad42407..cdac572 100644
--- a/cogl/cogl/cogl.symbols
+++ b/cogl/cogl/cogl.symbols
@@ -1042,6 +1042,7 @@ cogl_xlib_renderer_get_foreign_display
 cogl_xlib_renderer_get_visual_info
 cogl_xlib_renderer_handle_event
 cogl_xlib_renderer_remove_filter
+cogl_xlib_renderer_request_reset_on_video_memory_purge
 cogl_xlib_renderer_set_event_retrieval_enabled
 cogl_xlib_renderer_set_foreign_display
 cogl_xlib_set_display
diff --git a/cogl/cogl/gl-prototypes/cogl-all-functions.h b/cogl/cogl/gl-prototypes/cogl-all-functions.h
index 7ac9022..0c80fbc 100644
--- a/cogl/cogl/gl-prototypes/cogl-all-functions.h
+++ b/cogl/cogl/gl-prototypes/cogl-all-functions.h
@@ -326,3 +326,11 @@ COGL_EXT_BEGIN (draw_buffers, 2, 0,
 COGL_EXT_FUNCTION (void, glDrawBuffers,
                    (GLsizei n, const GLenum *bufs))
 COGL_EXT_END ()
+
+COGL_EXT_BEGIN (robustness, 255, 255,
+                0,
+                "ARB\0",
+                "robustness\0")
+COGL_EXT_FUNCTION (GLenum, glGetGraphicsResetStatus,
+                   (void))
+COGL_EXT_END ()
diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
index 72d9e56..f88ee37 100644
--- a/cogl/cogl/winsys/cogl-winsys-glx.c
+++ b/cogl/cogl/winsys/cogl-winsys-glx.c
@@ -71,6 +71,11 @@
 #include <GL/glx.h>
 #include <X11/Xlib.h>
 
+/* This is a relatively new extension */
+#ifndef GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV
+#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7
+#endif
+
 #define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask)
 #define MAX_GLX_CONFIG_ATTRIBS 30
 
@@ -1025,12 +1030,50 @@ create_gl3_context (CoglDisplay *display,
       GLX_CONTEXT_FLAGS_ARB,         GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
       None
     };
+  /* NV_robustness_video_memory_purge relies on GLX_ARB_create_context
+     and in part on ARB_robustness. Namely, it needs the notification
+     strategy to be set to GLX_LOSE_CONTEXT_ON_RESET_ARB and that the
+     driver exposes the GetGraphicsResetStatusARB function. This means
+     we don't actually enable robust buffer access. */
+  static const int attrib_list_reset_on_purge[] =
+    {
+      GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+      GLX_CONTEXT_MINOR_VERSION_ARB, 1,
+      GLX_CONTEXT_PROFILE_MASK_ARB,  GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
+      GLX_CONTEXT_FLAGS_ARB,         GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+      GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV,
+                                     GL_TRUE,
+      GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
+                                     GLX_LOSE_CONTEXT_ON_RESET_ARB,
+      None
+    };
 
   /* Make sure that the display supports the GLX_ARB_create_context
      extension */
   if (glx_renderer->glXCreateContextAttribs == NULL)
     return NULL;
 
+  /* We can't check the presence of this extension with the usual
+     COGL_WINSYS_FEATURE machinery because that only gets initialized
+     later when the CoglContext is created. */
+  if (display->renderer->xlib_want_reset_on_video_memory_purge &&
+      strstr (glx_renderer->glXQueryExtensionsString (xlib_renderer->xdpy,
+                                                      DefaultScreen (xlib_renderer->xdpy)),
+              "GLX_NV_robustness_video_memory_purge"))
+    {
+      CoglXlibTrapState old_state;
+      GLXContext ctx;
+
+      _cogl_xlib_renderer_trap_errors (display->renderer, &old_state);
+      ctx = glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy,
+                                                   fb_config,
+                                                   NULL /* share_context */,
+                                                   True, /* direct */
+                                                   attrib_list_reset_on_purge);
+      if (!_cogl_xlib_renderer_untrap_errors (display->renderer, &old_state) && ctx)
+        return ctx;
+    }
+
   return glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy,
                                                 fb_config,
                                                 NULL /* share_context */,


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