[gtk+/wip/gdk-gl: 3/31] gdk: Make GdkGLPixelFormat less smart



commit a5da2eff7de0911afa33c3e520b495dfd3165951
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Mon Aug 11 20:09:41 2014 +0100

    gdk: Make GdkGLPixelFormat less smart
    
    We use GdkGLPixelFormat only as a storage for GL configuration options.
    The validation is only made when creating a GdkGLContext.
    
    Validation for feature discovery and fallback code paths can be done
    directly using gdk_display_validate_gl_pixel_format() instead.

 gdk/gdkdisplay.c              |   30 +++++---
 gdk/gdkdisplay.h              |   11 ++-
 gdk/gdkdisplayprivate.h       |    6 +-
 gdk/gdkglcontext.c            |   31 ++++----
 gdk/gdkglcontext.h            |    3 +-
 gdk/gdkglcontextprivate.h     |    2 +-
 gdk/gdkglpixelformat.c        |  122 ++-----------------------------
 gdk/gdkglpixelformat.h        |    6 +-
 gdk/gdkglpixelformatprivate.h |    5 -
 gdk/x11/gdkglcontext-x11.c    |  163 ++++++++++++++++++++++++++++-------------
 gdk/x11/gdkglcontext-x11.h    |    3 +-
 11 files changed, 173 insertions(+), 209 deletions(-)
---
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index 2797803..0b564b5 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -2230,7 +2230,8 @@ gdk_error_trap_pop (void)
  * gdk_display_create_gl_context:
  * @display: a #GdkDisplay
  * @format: a #GdkGLPixelFormat
- * @share: (optional): an optional shared #GdkGLContext 
+ * @share: (optional): an optional shared #GdkGLContext
+ * @error: return location for a #GError
  *
  * Creates a new platform-specific #GdkGLContext for the
  * given @display and @format.
@@ -2238,11 +2239,12 @@ gdk_error_trap_pop (void)
  * Returns: (transfer full): the newly created #GdkGLContext
  */
 GdkGLContext *
-gdk_display_create_gl_context (GdkDisplay       *display,
-                               GdkGLPixelFormat *format,
-                               GdkGLContext     *share)
+gdk_display_create_gl_context (GdkDisplay        *display,
+                               GdkGLPixelFormat  *format,
+                               GdkGLContext      *share,
+                               GError           **error)
 {
-  return GDK_DISPLAY_GET_CLASS (display)->create_gl_context (display, format, share);
+  return GDK_DISPLAY_GET_CLASS (display)->create_gl_context (display, format, share, error);
 }
 
 /*< private >
@@ -2307,7 +2309,7 @@ gdk_display_get_current_gl_context (GdkDisplay *display)
   return g_object_get_data (G_OBJECT (display), "-gdk-gl-current-context");
 }
 
-/*< private >
+/**
  * gdk_display_validate_gl_pixel_format:
  * @display: a #GdkDisplay
  * @format: a #GdkGLPixelFormat
@@ -2318,6 +2320,8 @@ gdk_display_get_current_gl_context (GdkDisplay *display)
  * If the pixel format is invalid, @error will be set.
  *
  * Returns: %TRUE if the pixel format is valid
+ *
+ * Since: 3.14
  */
 gboolean
 gdk_display_validate_gl_pixel_format (GdkDisplay        *display,
@@ -2332,6 +2336,7 @@ gdk_display_validate_gl_pixel_format (GdkDisplay        *display,
  * @display: a #GdkDisplay
  * @format: a #GdkGLPixelFormat
  * @share: (optional): a shared #GdkGLContext, or %NULL
+ * @error: return location for a #GError
  *
  * Creates a new #GdkGLContext for the given display, with the given
  * pixel format.
@@ -2339,19 +2344,24 @@ gdk_display_validate_gl_pixel_format (GdkDisplay        *display,
  * If @share is not %NULL then the newly created #GdkGLContext will
  * share resources with it.
  *
+ * If the @format is invalid, or in case the creation of the #GdkGLContext
+ * failed, @error will be set.
+ *
  * Returns: (transfer full): the newly created #GdkGLContext, or
  *   %NULL on error
  *
  * Since: 3.14
  */
 GdkGLContext *
-gdk_display_get_gl_context (GdkDisplay       *display,
-                            GdkGLPixelFormat *format,
-                            GdkGLContext     *share)
+gdk_display_get_gl_context (GdkDisplay        *display,
+                            GdkGLPixelFormat  *format,
+                            GdkGLContext      *share,
+                            GError           **error)
 {
   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
   g_return_val_if_fail (GDK_IS_GL_PIXEL_FORMAT (format), NULL);
   g_return_val_if_fail (share == NULL || GDK_IS_GL_CONTEXT (share), NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  return gdk_display_create_gl_context (display, format, share);
+  return gdk_display_create_gl_context (display, format, share, error);
 }
diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h
index a457d89..290c881 100644
--- a/gdk/gdkdisplay.h
+++ b/gdk/gdkdisplay.h
@@ -172,9 +172,14 @@ GDK_AVAILABLE_IN_ALL
 GdkAppLaunchContext *gdk_display_get_app_launch_context (GdkDisplay *display);
 
 GDK_AVAILABLE_IN_3_14
-GdkGLContext *gdk_display_get_gl_context (GdkDisplay       *display,
-                                          GdkGLPixelFormat *format,
-                                          GdkGLContext     *share);
+gboolean        gdk_display_validate_gl_pixel_format    (GdkDisplay        *display,
+                                                         GdkGLPixelFormat  *format,
+                                                         GError           **error);
+GDK_AVAILABLE_IN_3_14
+GdkGLContext *  gdk_display_get_gl_context              (GdkDisplay        *display,
+                                                         GdkGLPixelFormat  *format,
+                                                         GdkGLContext      *share,
+                                                         GError           **error);
 
 G_END_DECLS
 
diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h
index c7fdb71..01e1f4a 100644
--- a/gdk/gdkdisplayprivate.h
+++ b/gdk/gdkdisplayprivate.h
@@ -227,7 +227,8 @@ struct _GdkDisplayClass
 
   GdkGLContext *        (*create_gl_context)        (GdkDisplay        *display,
                                                      GdkGLPixelFormat  *format,
-                                                     GdkGLContext      *share);
+                                                     GdkGLContext      *share,
+                                                     GError           **error);
   gboolean              (*make_gl_context_current)  (GdkDisplay        *display,
                                                      GdkGLContext      *context,
                                                      GdkWindow         *drawable);
@@ -320,7 +321,8 @@ gboolean            gdk_display_validate_gl_pixel_format (GdkDisplay        *dis
                                                           GError           **error);
 GdkGLContext *      gdk_display_create_gl_context        (GdkDisplay        *display,
                                                           GdkGLPixelFormat  *format,
-                                                          GdkGLContext      *share);
+                                                          GdkGLContext      *share,
+                                                          GError           **error);
 void                gdk_display_destroy_gl_context       (GdkDisplay        *display,
                                                           GdkGLContext      *context);
 gboolean            gdk_display_make_gl_context_current  (GdkDisplay        *display,
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 014e7fa..f5e543c 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -47,7 +47,7 @@ typedef struct {
   GdkWindow *window;
   GdkVisual *visual;
 
-  guint swap_interval;
+  gboolean swap_interval;
 } GdkGLContextPrivate;
 
 enum {
@@ -120,7 +120,7 @@ gdk_gl_context_set_property (GObject      *gobject,
       break;
 
     case PROP_SWAP_INTERVAL:
-      priv->swap_interval = g_value_get_uint (value);
+      priv->swap_interval = g_value_get_boolean (value);
       break;
 
     default:
@@ -155,7 +155,7 @@ gdk_gl_context_get_property (GObject    *gobject,
       break;
 
     case PROP_SWAP_INTERVAL:
-      g_value_set_uint (value, priv->swap_interval);
+      g_value_set_boolean (value, priv->swap_interval);
       break;
 
     default:
@@ -239,21 +239,21 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
    *
    * The swap interval of the GL context.
    *
-   * If set to 0 (the default), gdk_gl_context_flush_buffer() will execute
-   * the buffer flush as soon as possible.
+   * If set to %TRUE (the default), buffers will be flushed only during
+   * the vertical refresh of the display.
    *
-   * If set to 1, calls buffers will be flushed only during the vertical
-   * refresh of the display.
+   * If set to %FALSE, gdk_gl_context_flush_buffer() will execute
+   * the buffer flush as soon as possible.
    *
    * Since: 3.14
    */
   obj_pspecs[PROP_SWAP_INTERVAL] =
-    g_param_spec_uint ("swap-interval",
-                       P_("Swap Interval"),
-                       P_("The swap interval of the GL context"),
-                       0, G_MAXUINT, 0,
-                       G_PARAM_READWRITE |
-                       G_PARAM_STATIC_STRINGS);
+    g_param_spec_boolean ("swap-interval",
+                          P_("Swap Interval"),
+                          P_("The swap interval of the GL context"),
+                          TRUE,
+                          G_PARAM_READWRITE |
+                          G_PARAM_STATIC_STRINGS);
 
   gobject_class->set_property = gdk_gl_context_set_property;
   gobject_class->get_property = gdk_gl_context_get_property;
@@ -265,6 +265,9 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
 static void
 gdk_gl_context_init (GdkGLContext *self)
 {
+  GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
+
+  priv->swap_interval = TRUE;
 }
 
 /**
@@ -480,7 +483,7 @@ gdk_gl_context_get_current (void)
  *
  * Returns: the swap interval
  */
-guint
+gboolean
 gdk_gl_context_get_swap_interval (GdkGLContext *context)
 {
   GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
diff --git a/gdk/gdkglcontext.h b/gdk/gdkglcontext.h
index ff8853d..972eef9 100644
--- a/gdk/gdkglcontext.h
+++ b/gdk/gdkglcontext.h
@@ -39,9 +39,10 @@ GType gdk_gl_context_get_type (void) G_GNUC_CONST;
 
 GDK_AVAILABLE_IN_3_14
 GdkDisplay *            gdk_gl_context_get_display      (GdkGLContext *context);
-
 GDK_AVAILABLE_IN_3_14
 GdkGLPixelFormat *      gdk_gl_context_get_pixel_format (GdkGLContext *context);
+GDK_AVAILABLE_IN_3_14
+GdkVisual *             gdk_gl_context_get_visual       (GdkGLContext *context);
 
 GDK_AVAILABLE_IN_3_14
 void                    gdk_gl_context_clear_window     (GdkGLContext *context);
diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h
index 6551adb..74450b2 100644
--- a/gdk/gdkglcontextprivate.h
+++ b/gdk/gdkglcontextprivate.h
@@ -46,7 +46,7 @@ struct _GdkGLContextClass
   void (* flush_buffer) (GdkGLContext *context);
 };
 
-guint   gdk_gl_context_get_swap_interval        (GdkGLContext *context);
+gboolean        gdk_gl_context_get_swap_interval        (GdkGLContext *context);
 
 G_END_DECLS
 
diff --git a/gdk/gdkglpixelformat.c b/gdk/gdkglpixelformat.c
index 10986e2..f2a937b 100644
--- a/gdk/gdkglpixelformat.c
+++ b/gdk/gdkglpixelformat.c
@@ -26,29 +26,6 @@
  * The #GdkGLPixelFormat class is used to specify the types and sizes of
  * buffers to be used by a #GdkGLContext, as well as other configuration
  * parameters.
- *
- * You should typically try to create a #GdkGLPixelFormat for a given
- * configuration, and if the creation fails, you can either opt to
- * show an error, or change the configuration until you find a suitable
- * pixel format.
- *
- * For instance, the following example creates a #GdkGLPixelFormat with
- * double buffering enabled, and a 32-bit depth buffer:
- *
- * |[<!-- language="C" -->
- *   GdkGLPixelFormat *format;
- *   GError *error = NULL;
- *
- *   format = gdk_gl_pixel_format_new (&error,
- *                                     "double-buffer", TRUE,
- *                                     "depth-size", 32,
- *                                     NULL);
- *   if (format == NULL)
- *     {
- *       // creation failed; try again with a different set
- *       // of attributes
- *     }
- * ]|
  */
 
 #include "config.h"
@@ -65,8 +42,6 @@
 enum {
   PROP_0,
 
-  PROP_DISPLAY,
-
   /* bool */
   PROP_DOUBLE_BUFFER,
   PROP_MULTI_SAMPLE,
@@ -89,46 +64,9 @@ enum {
 
 static GParamSpec *obj_props[LAST_PROP] = { NULL, };
 
-static void initable_iface_init (GInitableIface *init);
-
 G_DEFINE_QUARK (gdk-gl-pixel-format-error-quark, gdk_gl_pixel_format_error)
 
-G_DEFINE_TYPE_WITH_CODE (GdkGLPixelFormat, gdk_gl_pixel_format, G_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
-                                                initable_iface_init))
-
-static gboolean
-gdk_gl_pixel_format_init_internal (GInitable     *initable,
-                                   GCancellable  *cancellable,
-                                   GError       **error)
-{
-  GdkGLPixelFormat *self = GDK_GL_PIXEL_FORMAT (initable);
-
-  /* use the default display */
-  if (self->display == NULL)
-    self->display = g_object_ref (gdk_display_get_default ());
-
-  self->is_valid = gdk_display_validate_gl_pixel_format (self->display, self, error);
-  self->is_validated = TRUE;
-
-  return self->is_valid;
-}
-
-static void
-initable_iface_init (GInitableIface *iface)
-{
-  iface->init = gdk_gl_pixel_format_init_internal;
-}
-
-static void
-gdk_gl_pixel_format_dispose (GObject *gobject)
-{
-  GdkGLPixelFormat *self = GDK_GL_PIXEL_FORMAT (gobject);
-
-  g_clear_object (&self->display);
-
-  G_OBJECT_CLASS (gdk_gl_pixel_format_parent_class)->dispose (gobject);
-}
+G_DEFINE_TYPE (GdkGLPixelFormat, gdk_gl_pixel_format, G_TYPE_OBJECT)
 
 static void
 gdk_gl_pixel_format_set_property (GObject      *gobject,
@@ -140,15 +78,6 @@ gdk_gl_pixel_format_set_property (GObject      *gobject,
 
   switch (prop_id)
     {
-    case PROP_DISPLAY:
-      {
-        GdkDisplay *display = g_value_get_object (value);
-
-        if (display != NULL)
-          self->display = g_object_ref (display);
-      }
-      break;
-
     case PROP_DOUBLE_BUFFER:
       self->double_buffer = g_value_get_boolean (value);
       break;
@@ -208,10 +137,6 @@ gdk_gl_pixel_format_get_property (GObject    *gobject,
 
   switch (prop_id)
     {
-    case PROP_DISPLAY:
-      g_value_set_object (value, self->display);
-      break;
-
     case PROP_DOUBLE_BUFFER:
       g_value_set_boolean (value, self->double_buffer);
       break;
@@ -268,16 +193,6 @@ gdk_gl_pixel_format_class_init (GdkGLPixelFormatClass *klass)
 
   gobject_class->set_property = gdk_gl_pixel_format_set_property;
   gobject_class->get_property = gdk_gl_pixel_format_get_property;
-  gobject_class->dispose = gdk_gl_pixel_format_dispose;
-
-  obj_props[PROP_DISPLAY] =
-    g_param_spec_object ("display",
-                         P_("Display"),
-                         P_("The GDK display associated with the pixel format"),
-                         GDK_TYPE_DISPLAY,
-                         G_PARAM_READWRITE |
-                         G_PARAM_CONSTRUCT_ONLY |
-                         G_PARAM_STATIC_STRINGS);
 
   obj_props[PROP_DOUBLE_BUFFER] =
     g_param_spec_boolean ("double-buffer",
@@ -389,51 +304,28 @@ gdk_gl_pixel_format_init (GdkGLPixelFormat *self)
 
 /**
  * gdk_gl_pixel_format_new:
- * @error: return location for a #GError, or %NULL
  * @first_property: the first property to set
  * @...: the value of the @first_property, followed by a %NULL terminated
  *   set of property, value pairs
  *
  * Creates a new #GdkGLPixelFormat with the given list of properties.
  *
- * If the pixel format is not valid, then this function will return
- * a %NULL value, and @error will be set.
- *
- * Returns: the newly created #GdkGLPixelFormat, or %NULL
+ * Returns: the newly created #GdkGLPixelFormat
  *
  * Since: 3.14
  */
 GdkGLPixelFormat *
-gdk_gl_pixel_format_new (GError     **error,
-                         const char  *first_property,
+gdk_gl_pixel_format_new (const char *first_property,
                          ...)
 {
-  gpointer res;
+  GdkGLPixelFormat *res;
   va_list args;
 
-  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
   va_start (args, first_property);
-  res = g_initable_new_valist (GDK_TYPE_GL_PIXEL_FORMAT, first_property, args, NULL, error);
-  va_end (args);
 
-  return res;
-}
+  res = (GdkGLPixelFormat *) g_object_new_valist (GDK_TYPE_GL_PIXEL_FORMAT, first_property, args);
 
-/**
- * gdk_gl_pixel_format_get_display:
- * @format: a #GdkGLPixelFormat
- *
- * Retrieves the #GdkDisplay used to validate the pixel format.
- *
- * Returns: (transfer none): the #GdkDisplay
- *
- * Since: 3.14
- */
-GdkDisplay *
-gdk_gl_pixel_format_get_display (GdkGLPixelFormat *format)
-{
-  g_return_val_if_fail (GDK_IS_GL_PIXEL_FORMAT (format), NULL);
+  va_end (args);
 
-  return format->display;
+  return res;
 }
diff --git a/gdk/gdkglpixelformat.h b/gdk/gdkglpixelformat.h
index 9aa9882..7b03f68 100644
--- a/gdk/gdkglpixelformat.h
+++ b/gdk/gdkglpixelformat.h
@@ -44,12 +44,8 @@ GDK_AVAILABLE_IN_3_14
 GQuark gdk_gl_pixel_format_error_quark (void);
 
 GDK_AVAILABLE_IN_3_14
-GdkGLPixelFormat *      gdk_gl_pixel_format_new         (GError **error,
-                                                         const char *first_property,
+GdkGLPixelFormat *      gdk_gl_pixel_format_new         (const char *first_property,
                                                          ...);
-GDK_AVAILABLE_IN_3_14
-GdkDisplay *            gdk_gl_pixel_format_get_display (GdkGLPixelFormat *format);
-
 G_END_DECLS
 
 #endif /* __GDK_GL_PIXEL_FORMAT_H__ */
diff --git a/gdk/gdkglpixelformatprivate.h b/gdk/gdkglpixelformatprivate.h
index fd9e614..7999bfd 100644
--- a/gdk/gdkglpixelformatprivate.h
+++ b/gdk/gdkglpixelformatprivate.h
@@ -13,11 +13,6 @@ struct _GdkGLPixelFormat
 {
   GObject parent_instance;
 
-  gboolean is_validated;
-  gboolean is_valid;
-
-  GdkDisplay *display;
-
   gboolean double_buffer;
   gboolean multi_sample;
 
diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c
index aee0bf8..48fe93c 100644
--- a/gdk/x11/gdkglcontext-x11.c
+++ b/gdk/x11/gdkglcontext-x11.c
@@ -22,6 +22,8 @@ typedef struct {
   GdkDisplay *display;
   GdkGLContext *context;
   GdkWindow *window;
+
+  guint32 last_frame_counter;
 } DrawableInfo;
 
 static void
@@ -111,10 +113,37 @@ gdk_x11_gl_context_update (GdkGLContext *context)
 }
 
 static void
+maybe_wait_for_vblank (GdkDisplay  *display,
+                       GLXDrawable  drawable)
+{
+  GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
+  Display *dpy = gdk_x11_display_get_xdisplay (display);
+
+  if (display_x11->has_glx_sync_control)
+    {
+      gint64 ust, msc, sbc;
+
+      glXGetSyncValuesOML (dpy, drawable, &ust, &msc, &sbc);
+      glXWaitForMscOML (dpy, drawable,
+                        0, 2, (msc + 1) % 2,
+                        &ust, &msc, &sbc);
+    }
+  else if (display_x11->has_glx_video_sync)
+    {
+      guint32 current_count;
+
+      glXGetVideoSyncSGI (&current_count);
+      glXWaitVideoSyncSGI (2, (current_count + 1) % 2, &current_count);
+    }
+}
+
+static void
 gdk_x11_gl_context_flush_buffer (GdkGLContext *context)
 {
   GdkDisplay *display = gdk_gl_context_get_display (context);
   GdkWindow *window = gdk_gl_context_get_window (context);
+  Display *dpy = gdk_x11_display_get_xdisplay (display);
+  GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
   DrawableInfo *info;
   GLXDrawable drawable;
 
@@ -129,9 +158,43 @@ gdk_x11_gl_context_flush_buffer (GdkGLContext *context)
 
   GDK_NOTE (OPENGL, g_print ("Flushing GLX buffers for %lu\n", (unsigned long) drawable));
 
-  glFinish ();
-
-  glXSwapBuffers (gdk_x11_display_get_xdisplay (display), drawable);
+  /* if we are going to wait for the vertical refresh manually
+   * we need to flush pending redraws, and we also need to wait
+   * for that to finish, otherwise we are going to tear.
+   *
+   * obviously, this condition should not be hit if we have
+   * GLX_SGI_swap_control, and we ask the driver to do the right
+   * thing.
+   */
+  {
+    guint32 end_frame_counter = 0;
+    gboolean has_counter = display_x11->has_glx_video_sync;
+    gboolean can_wait = display_x11->has_glx_video_sync ||
+                        display_x11->has_glx_sync_control;
+
+    if (display_x11->has_glx_video_sync)
+      glXGetVideoSyncSGI (&end_frame_counter);
+
+    if (!display_x11->has_glx_swap_interval)
+      {
+        glFinish ();
+
+        if (has_counter && can_wait)
+          {
+            guint32 last_counter = info != NULL ? info->last_frame_counter : 0;
+
+            if (last_counter == end_frame_counter)
+              maybe_wait_for_vblank (display, drawable);
+          }
+        else if (can_wait)
+          maybe_wait_for_vblank (display, drawable);
+      }
+  }
+
+  glXSwapBuffers (dpy, drawable);
+
+  if (info != NULL && display_x11->has_glx_video_sync)
+    glXGetVideoSyncSGI (&info->last_frame_counter);
 }
 
 static void
@@ -214,7 +277,8 @@ gdk_x11_display_init_gl (GdkDisplay *display)
 #define MAX_GLX_ATTRS   30
 
 static void
-get_glx_attributes_for_pixel_format (GdkGLPixelFormat *format,
+get_glx_attributes_for_pixel_format (GdkDisplay       *display,
+                                     GdkGLPixelFormat *format,
                                      int              *attrs)
 {
   GdkX11Display *display_x11;
@@ -291,7 +355,7 @@ get_glx_attributes_for_pixel_format (GdkGLPixelFormat *format,
       attrs[i++] = format->stencil_size;
     }
 
-  display_x11 = GDK_X11_DISPLAY (format->display);
+  display_x11 = GDK_X11_DISPLAY (display);
   if (display_x11->glx_version >= 14 && format->multi_sample)
     {
       attrs[i++] = GLX_SAMPLE_BUFFERS;
@@ -321,10 +385,7 @@ find_fbconfig_for_pixel_format (GdkDisplay        *display,
   gboolean use_rgba;
   gboolean retval = FALSE;
 
-  if (format->display == NULL)
-    return retval;
-
-  get_glx_attributes_for_pixel_format (format, attrs);
+  get_glx_attributes_for_pixel_format (display, format, attrs);
 
   use_rgba = format->alpha_size != 0;
 
@@ -427,9 +488,10 @@ create_gl_context (GdkDisplay   *display,
 }
 
 GdkGLContext *
-gdk_x11_display_create_gl_context (GdkDisplay       *display,
-                                   GdkGLPixelFormat *format,
-                                   GdkGLContext     *share)
+gdk_x11_display_create_gl_context (GdkDisplay        *display,
+                                   GdkGLPixelFormat  *format,
+                                   GdkGLContext      *share,
+                                   GError           **error)
 {
   GdkX11GLContext *context;
   GdkVisual *gdk_visual;
@@ -443,46 +505,35 @@ gdk_x11_display_create_gl_context (GdkDisplay       *display,
   XSetWindowAttributes attrs;
   unsigned long mask;
   Display *dpy;
-  GError *error;
 
-  if (!gdk_x11_display_init_gl (display))
+  if (!gdk_x11_display_validate_gl_pixel_format (display, format, error))
     return NULL;
 
-  if (G_UNLIKELY (!format->is_validated))
-    {
-      /* force a validation */
-      format->is_valid = gdk_x11_display_validate_gl_pixel_format (display, format, NULL);
-      format->is_validated = TRUE;
-    }
-
-  if (!format->is_valid)
-    {
-      g_critical ("The GdkGLPixelFormat is not valid.");
-      return NULL;
-    }
+  /* if validation succeeded, then we don't need to check for the result
+   * here
+   */
+  find_fbconfig_for_pixel_format (display, format, &config, &xvisinfo, NULL);
 
   dpy = gdk_x11_display_get_xdisplay (display);
 
-  error = NULL;
-  find_fbconfig_for_pixel_format (display, format, &config, &xvisinfo, &error);
-  if (error != NULL)
-    {
-      g_critical ("%s", error->message);
-      g_error_free (error);
-      return NULL;
-    }
-
   /* we check for the GLX_ARB_create_context_profile extension
-   * while validating the PixelFormat
+   * while validating the PixelFormat.
    */
   if (format->profile == GDK_GL_PIXEL_FORMAT_PROFILE_3_2_CORE)
     glx_context = create_gl3_context (display, config, share);
   else
-    glx_context = create_gl_context (display, config, share);
+    {
+      /* GDK_GL_PIXEL_FORMAT_PROFILE_DEFAULT is currently
+       * equivalent to the LEGACY profile
+       */
+      glx_context = create_gl_context (display, config, share);
+    }
 
   if (glx_context == NULL)
     {
-      g_critical ("Unable to create a GLX context");
+      g_set_error_literal (error, GDK_GL_PIXEL_FORMAT_ERROR,
+                           GDK_GL_PIXEL_FORMAT_ERROR_NOT_AVAILABLE,
+                           _("Unable to create a GL context"));
       return NULL;
     }
 
@@ -529,7 +580,20 @@ gdk_x11_display_create_gl_context (GdkDisplay       *display,
   XFree (xvisinfo);
 
   if (gdk_x11_display_error_trap_pop (display))
-    return NULL;
+    {
+      g_set_error_literal (error, GDK_GL_PIXEL_FORMAT_ERROR,
+                           GDK_GL_PIXEL_FORMAT_ERROR_NOT_AVAILABLE,
+                           _("Unable to create a GL context"));
+
+      glXDestroyContext (dpy, glx_context);
+
+      if (dummy_xwin)
+        XDestroyWindow (dpy, dummy_xwin);
+      if (dummy_glx)
+        glXDestroyWindow (dpy, dummy_glx);
+
+      return NULL;
+    }
 
   GDK_NOTE (OPENGL,
             g_print ("Created GLX context[%p], %s, dummy drawable: %lu\n",
@@ -632,6 +696,14 @@ gdk_x11_display_make_gl_context_current (GdkDisplay   *display,
                          drawable, drawable,
                          context_x11->glx_context);
 
+  if (GDK_X11_DISPLAY (display)->has_glx_swap_interval)
+    {
+      if (gdk_gl_context_get_swap_interval (context))
+        glXSwapIntervalSGI (1);
+      else
+        glXSwapIntervalSGI (0);
+    }
+
   XSync (gdk_x11_display_get_xdisplay (display), False);
 
   if (gdk_x11_display_error_trap_pop (display))
@@ -650,19 +722,6 @@ gdk_x11_display_validate_gl_pixel_format (GdkDisplay        *display,
                                           GdkGLPixelFormat  *format,
                                           GError           **error)
 {
-  /* shortcut in case we already validated this PixelFormat */
-  if (format->is_validated)
-    {
-      if (!format->is_valid)
-        {
-          g_set_error_literal (error, GDK_GL_PIXEL_FORMAT_ERROR,
-                               GDK_GL_PIXEL_FORMAT_ERROR_INVALID_FORMAT,
-                               _("Invalid pixel format"));
-        }
-
-      return format->is_valid;
-    }
-
   if (!gdk_x11_display_init_gl (display))
     {
       g_set_error_literal (error, GDK_GL_PIXEL_FORMAT_ERROR,
diff --git a/gdk/x11/gdkglcontext-x11.h b/gdk/x11/gdkglcontext-x11.h
index 3c83548..3b0a71b 100644
--- a/gdk/x11/gdkglcontext-x11.h
+++ b/gdk/x11/gdkglcontext-x11.h
@@ -44,7 +44,8 @@ gboolean        gdk_x11_display_validate_gl_pixel_format        (GdkDisplay
                                                                  GError           **error);
 GdkGLContext *  gdk_x11_display_create_gl_context               (GdkDisplay        *display,
                                                                  GdkGLPixelFormat  *format,
-                                                                 GdkGLContext      *share);
+                                                                 GdkGLContext      *share,
+                                                                 GError           **error);
 void            gdk_x11_display_destroy_gl_context              (GdkDisplay        *display,
                                                                  GdkGLContext      *context);
 gboolean        gdk_x11_display_make_gl_context_current         (GdkDisplay        *display,


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