[gtk+/wip/otte/vulkan: 31/59] gdk: Large GL refactoring



commit 3d295a74d1e2e32ee45b93baf542bfb107491c1c
Author: Benjamin Otte <otte redhat com>
Date:   Wed Nov 23 03:32:22 2016 +0100

    gdk: Large GL refactoring
    
    No visible changes as GL rendering is disabled at the moment.
    
    What was done:
    
    1. Move window->invalidate_for_new_frame to glcontext->begin_frame
    This moves the code to where it is used (the GLContext) and prepares it
    for being called where it is used when actually beginning to draw the
    frame.
    
    2. Get rid of buffer-age usage
    We want to let the application render directly to the backbuffer.
    Because of that, we cannot make any assumptions about the contents the
    application renders outside the clip area.
    In particular GskGLRenderer renders random stuff there but not actual
    contents.
    
    3. Pass the actual GL context
    Previously, we passed the shared context to end_frame, now we pass the
    actual GL context that the application uses for rendering. This is so
    that the vfuncs could prepare the actual contexts for rendering (they
    don't currently).
    
    4. Simplify the code
    The previous code set up the final drawing method in begin_frame.
    Instead, we now just ensure the clip area is something we can render
    and decide on the actual method in end_frame.
    This is both more robust (we can change the clip area in between if we
    want to) and less code.

 gdk/gdkglcontextprivate.h          |    2 +
 gdk/gdkwindow.c                    |    8 ---
 gdk/gdkwindowimpl.h                |    2 -
 gdk/mir/gdkmirglcontext.c          |   20 ++++++
 gdk/mir/gdkmirwindowimpl.c         |   62 --------------------
 gdk/wayland/gdkglcontext-wayland.c |   81 ++++++--------------------
 gdk/wayland/gdkglcontext-wayland.h |    2 -
 gdk/wayland/gdkwindow-wayland.c    |    1 -
 gdk/win32/gdkglcontext-win32.c     |  104 +++++++++++++++------------------
 gdk/win32/gdkglcontext-win32.h     |   14 -----
 gdk/win32/gdkwindow-win32.c        |    1 -
 gdk/x11/gdkglcontext-x11.c         |  112 +++++++++++-------------------------
 gdk/x11/gdkglcontext-x11.h         |    4 -
 gdk/x11/gdkwindow-x11.c            |    1 -
 14 files changed, 119 insertions(+), 295 deletions(-)
---
diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h
index 1d0b9ff..24fd80e 100644
--- a/gdk/gdkglcontextprivate.h
+++ b/gdk/gdkglcontextprivate.h
@@ -43,6 +43,8 @@ struct _GdkGLContextClass
   gboolean (* realize) (GdkGLContext *context,
                         GError **error);
 
+  void (* begin_frame)  (GdkGLContext *context,
+                         cairo_region_t *update_area);
   void (* end_frame)    (GdkGLContext *context,
                          cairo_region_t *painted,
                          cairo_region_t *damage);
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index a135449..d8b3960 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -3335,14 +3335,6 @@ gdk_window_process_updates_internal (GdkWindow *window)
 
          impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
 
-          /* Sometimes we can't just paint only the new area, as the windowing system
-           * requires more to be repainted. For instance, with OpenGL you typically
-           * repaint all of each frame each time and then swap the buffer, although
-           * there are extensions that allow us to reuse part of an old frame.
-           */
-          if (impl_class->invalidate_for_new_frame)
-            impl_class->invalidate_for_new_frame (window, expose_region);
-
          /* Clip to part visible in impl window */
          cairo_region_intersect (expose_region, window->clip_region);
 
diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h
index 82f7de9..e4539ab 100644
--- a/gdk/gdkwindowimpl.h
+++ b/gdk/gdkwindowimpl.h
@@ -299,8 +299,6 @@ struct _GdkWindowImplClass
                                           gboolean        attached,
                                            GdkGLContext   *share,
                                            GError        **error);
-  void         (*invalidate_for_new_frame)(GdkWindow      *window,
-                                           cairo_region_t *update_area);
 };
 
 /* Interface Functions */
diff --git a/gdk/mir/gdkmirglcontext.c b/gdk/mir/gdkmirglcontext.c
index 9506461..a4c00c2 100644
--- a/gdk/mir/gdkmirglcontext.c
+++ b/gdk/mir/gdkmirglcontext.c
@@ -98,6 +98,25 @@ gdk_mir_gl_context_realize (GdkGLContext *context,
 }
 
 static void
+gdk_mir_gl_context_begin_frame (GdkGLContext   *context,
+                                cairo_region_t *update_area)
+{
+  GdkDisplay *display = gdk_gl_context_get_display (window);
+  GdkWindow *window;
+
+  if (_gdk_mir_display_have_egl_swap_buffers_with_damage (display))
+    return;
+
+  /* If nothing else is known, repaint everything so that the back
+     buffer is fully up-to-date for the swapbuffer */
+  window = gdk_gl_context_get_window (context);
+  cairo_region_union_rectangle (update_area, &(GdkRectangle) {
+                                                 0, 0,
+                                                 gdk_window_get_width (window),
+                                                 gdk_window_get_height (window) });
+}
+
+static void
 gdk_mir_gl_context_end_frame (GdkGLContext *context,
                               cairo_region_t *painted,
                               cairo_region_t *damage)
@@ -168,6 +187,7 @@ gdk_mir_gl_context_class_init (GdkMirGLContextClass *klass)
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
   context_class->realize = gdk_mir_gl_context_realize;
+  context_class->begin_frame = gdk_mir_gl_context_begin_frame;
   context_class->end_frame = gdk_mir_gl_context_end_frame;
   gobject_class->dispose = gdk_mir_gl_context_dispose;
 }
diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
index 7fc9376..87c77e9 100644
--- a/gdk/mir/gdkmirwindowimpl.c
+++ b/gdk/mir/gdkmirwindowimpl.c
@@ -1595,67 +1595,6 @@ gdk_mir_window_impl_create_gl_context (GdkWindow     *window,
   return GDK_GL_CONTEXT (context);
 }
 
-static void
-gdk_mir_window_impl_invalidate_for_new_frame (GdkWindow *window,
-                                              cairo_region_t *update_area)
-{
-  cairo_rectangle_int_t window_rect;
-  GdkDisplay *display = gdk_window_get_display (window);
-  GdkMirGLContext *context_mir;
-  int buffer_age;
-  gboolean invalidate_all;
-  EGLSurface egl_surface;
-
-  /* Minimal update is ok if we're not drawing with gl */
-  if (window->gl_paint_context == NULL)
-    return;
-
-  context_mir = GDK_MIR_GL_CONTEXT (window->gl_paint_context);
-  buffer_age = 0;
-
-  egl_surface = _gdk_mir_window_get_egl_surface (window, context_mir->egl_config);
-
-  if (_gdk_mir_display_have_egl_buffer_age (display))
-    {
-      gdk_gl_context_make_current (window->gl_paint_context);
-      eglQuerySurface (_gdk_mir_display_get_egl_display (display), egl_surface,
-                       EGL_BUFFER_AGE_EXT, &buffer_age);
-    }
-
-  invalidate_all = FALSE;
-  if (buffer_age == 0 || buffer_age >= 4)
-    invalidate_all = TRUE;
-  else
-    {
-      if (buffer_age >= 2)
-        {
-          if (window->old_updated_area[0])
-            cairo_region_union (update_area, window->old_updated_area[0]);
-          else
-            invalidate_all = TRUE;
-        }
-      if (buffer_age >= 3)
-        {
-          if (window->old_updated_area[1])
-            cairo_region_union (update_area, window->old_updated_area[1]);
-          else
-            invalidate_all = TRUE;
-        }
-    }
-
-  if (invalidate_all)
-    {
-      window_rect.x = 0;
-      window_rect.y = 0;
-      window_rect.width = gdk_window_get_width (window);
-      window_rect.height = gdk_window_get_height (window);
-
-      /* If nothing else is known, repaint everything so that the back
-         buffer is fully up-to-date for the swapbuffer */
-      cairo_region_union_rectangle (update_area, &window_rect);
-    }
-}
-
 EGLSurface
 _gdk_mir_window_get_egl_surface (GdkWindow *window,
                                  EGLConfig config)
@@ -1830,5 +1769,4 @@ gdk_mir_window_impl_class_init (GdkMirWindowImplClass *klass)
   impl_class->set_opaque_region = gdk_mir_window_impl_set_opaque_region;
   impl_class->set_shadow_width = gdk_mir_window_impl_set_shadow_width;
   impl_class->create_gl_context = gdk_mir_window_impl_create_gl_context;
-  impl_class->invalidate_for_new_frame = gdk_mir_window_impl_invalidate_for_new_frame;
 }
diff --git a/gdk/wayland/gdkglcontext-wayland.c b/gdk/wayland/gdkglcontext-wayland.c
index 05043d1..c55e307 100644
--- a/gdk/wayland/gdkglcontext-wayland.c
+++ b/gdk/wayland/gdkglcontext-wayland.c
@@ -37,68 +37,19 @@ G_DEFINE_TYPE (GdkWaylandGLContext, gdk_wayland_gl_context, GDK_TYPE_GL_CONTEXT)
 
 static void gdk_x11_gl_context_dispose (GObject *gobject);
 
-void
-gdk_wayland_window_invalidate_for_new_frame (GdkWindow      *window,
-                                             cairo_region_t *update_area)
+static void
+gdk_wayland_gl_context_begin_frame (GdkGLContext   *context,
+                                    cairo_region_t *update_area)
 {
-  cairo_rectangle_int_t window_rect;
-  GdkDisplay *display = gdk_window_get_display (window);
-  GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
-  GdkWaylandGLContext *context_wayland;
-  int buffer_age;
-  gboolean invalidate_all;
-  EGLSurface egl_surface;
-
-  /* Minimal update is ok if we're not drawing with gl */
-  if (window->gl_paint_context == NULL)
-    return;
-
-  context_wayland = GDK_WAYLAND_GL_CONTEXT (window->gl_paint_context);
-  buffer_age = 0;
-
-  egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window,
-                                                    context_wayland->egl_config);
-
-  if (display_wayland->have_egl_buffer_age)
-    {
-      gdk_gl_context_make_current (window->gl_paint_context);
-      eglQuerySurface (display_wayland->egl_display, egl_surface,
-                      EGL_BUFFER_AGE_EXT, &buffer_age);
-    }
-
-  invalidate_all = FALSE;
-  if (buffer_age == 0 || buffer_age >= 4)
-    invalidate_all = TRUE;
-  else
-    {
-      if (buffer_age >= 2)
-        {
-          if (window->old_updated_area[0])
-            cairo_region_union (update_area, window->old_updated_area[0]);
-          else
-            invalidate_all = TRUE;
-        }
-      if (buffer_age >= 3)
-        {
-          if (window->old_updated_area[1])
-            cairo_region_union (update_area, window->old_updated_area[1]);
-          else
-            invalidate_all = TRUE;
-        }
-    }
+  GdkWindow *window;
 
-  if (invalidate_all)
-    {
-      window_rect.x = 0;
-      window_rect.y = 0;
-      window_rect.width = gdk_window_get_width (window);
-      window_rect.height = gdk_window_get_height (window);
-
-      /* If nothing else is known, repaint everything so that the back
-       * buffer is fully up-to-date for the swapbuffer
-       */
-      cairo_region_union_rectangle (update_area, &window_rect);
-    }
+  /* If nothing else is known, repaint everything so that the back
+     buffer is fully up-to-date for the swapbuffer */
+  window = gdk_gl_context_get_window (context);
+  cairo_region_union_rectangle (update_area, &(GdkRectangle) {
+                                                 0, 0,
+                                                 gdk_window_get_width (window),
+                                                 gdk_window_get_height (window) });
 }
 
 #define N_EGL_ATTRS     16
@@ -227,13 +178,14 @@ gdk_wayland_gl_context_end_frame (GdkGLContext   *context,
   GdkWindow *window = gdk_gl_context_get_window (context);
   GdkDisplay *display = gdk_window_get_display (window);
   GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
-  GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
+  GdkGLContext *shared = gdk_gl_context_get_shared_context (context);
+  GdkWaylandGLContext *shared_wayland = GDK_WAYLAND_GL_CONTEXT (shared);
   EGLSurface egl_surface;
 
-  gdk_gl_context_make_current (context);
+  gdk_gl_context_make_current (shared);
 
   egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window,
-                                                    context_wayland->egl_config);
+                                                    shared_wayland->egl_config);
 
   if (display_wayland->have_egl_swap_buffers_with_damage)
     {
@@ -266,6 +218,7 @@ gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
   gobject_class->dispose = gdk_x11_gl_context_dispose;
 
   context_class->realize = gdk_wayland_gl_context_realize;
+  context_class->begin_frame = gdk_wayland_gl_context_begin_frame;
   context_class->end_frame = gdk_wayland_gl_context_end_frame;
 }
 
diff --git a/gdk/wayland/gdkglcontext-wayland.h b/gdk/wayland/gdkglcontext-wayland.h
index 4908ba7..44a9510 100644
--- a/gdk/wayland/gdkglcontext-wayland.h
+++ b/gdk/wayland/gdkglcontext-wayland.h
@@ -51,8 +51,6 @@ GdkGLContext *  gdk_wayland_window_create_gl_context                (GdkWindow
                                                                     gboolean           attach,
                                                                      GdkGLContext      *share,
                                                                      GError           **error);
-void            gdk_wayland_window_invalidate_for_new_frame         (GdkWindow         *window,
-                                                                     cairo_region_t    *update_area);
 gboolean        gdk_wayland_display_make_gl_context_current         (GdkDisplay        *display,
                                                                      GdkGLContext      *context);
 
diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c
index 4d12015..603a027 100644
--- a/gdk/wayland/gdkwindow-wayland.c
+++ b/gdk/wayland/gdkwindow-wayland.c
@@ -3656,7 +3656,6 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
   impl_class->set_shadow_width = gdk_wayland_window_set_shadow_width;
   impl_class->show_window_menu = gdk_wayland_window_show_window_menu;
   impl_class->create_gl_context = gdk_wayland_window_create_gl_context;
-  impl_class->invalidate_for_new_frame = gdk_wayland_window_invalidate_for_new_frame;
 
   signals[COMMITTED] = g_signal_new ("committed",
                                      G_TYPE_FROM_CLASS (object_class),
diff --git a/gdk/win32/gdkglcontext-win32.c b/gdk/win32/gdkglcontext-win32.c
index ee80e0d..8da90a3 100644
--- a/gdk/win32/gdkglcontext-win32.c
+++ b/gdk/win32/gdkglcontext-win32.c
@@ -82,23 +82,6 @@ _gdk_win32_gl_context_dispose (GObject *gobject)
 }
 
 static void
-gdk_win32_gl_context_class_init (GdkWin32GLContextClass *klass)
-{
-  GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
-  context_class->end_frame = _gdk_win32_gl_context_end_frame;
-  context_class->realize = _gdk_win32_gl_context_realize;
-
-  gobject_class->dispose = _gdk_win32_gl_context_dispose;
-}
-
-static void
-gdk_win32_gl_context_init (GdkWin32GLContext *self)
-{
-}
-
-static void
 gdk_gl_blit_region (GdkWindow *window, cairo_region_t *region)
 {
   int n_rects, i;
@@ -117,10 +100,10 @@ gdk_gl_blit_region (GdkWindow *window, cairo_region_t *region)
     }
 }
 
-void
-_gdk_win32_gl_context_end_frame (GdkGLContext *context,
-                                 cairo_region_t *painted,
-                                 cairo_region_t *damage)
+static void
+gdk_win32_gl_context_end_frame (GdkGLContext *context,
+                                cairo_region_t *painted,
+                                cairo_region_t *damage)
 {
   GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
   GdkWindow *window = gdk_gl_context_get_window (context);
@@ -149,7 +132,12 @@ _gdk_win32_gl_context_end_frame (GdkGLContext *context,
         }
     }
 
-  if (context_win32->do_blit_swap)
+  whole_window = (GdkRectangle) { 0, 0, gdk_window_get_width (window), gdk_window_get_height (window) };
+  if (cairo_region_contains_rectangle (painted, &whole_window) == CAIRO_REGION_OVERLAP_IN)
+    {
+      SwapBuffers (context_win32->gl_hdc);
+    }
+  else if (gdk_gl_context_has_framebuffer_blit (context))
     {
       glDrawBuffer(GL_FRONT);
       glReadBuffer(GL_BACK);
@@ -161,44 +149,28 @@ _gdk_win32_gl_context_end_frame (GdkGLContext *context,
         glFrameTerminatorGREMEDY ();
     }
   else
-    SwapBuffers (context_win32->gl_hdc);
+    {
+      g_warning ("Need to swap whole buffer even thouigh not everything was redrawn. Expect artifacts.");
+      SwapBuffers (context_win32->gl_hdc);
+    }
 }
 
-void
-_gdk_win32_window_invalidate_for_new_frame (GdkWindow *window,
-                                            cairo_region_t *update_area)
+static void
+gdk_win32_gl_context_begin_frame (GdkGLContext   *context,
+                                  cairo_region_t *update_area)
 {
-  cairo_rectangle_int_t window_rect;
-  gboolean invalidate_all = FALSE;
-  GdkWin32GLContext *context_win32;
-  cairo_rectangle_int_t whole_window = { 0, 0, gdk_window_get_width (window), gdk_window_get_height (window) 
};
+  GdkWindow *window;
 
-  /* Minimal update is ok if we're not drawing with gl */
-  if (window->gl_paint_context == NULL)
+  if (gdk_gl_context_has_framebuffer_blit (context))
     return;
 
-  context_win32 = GDK_WIN32_GL_CONTEXT (window->gl_paint_context);
-  context_win32->do_blit_swap = FALSE;
-
-  if (gdk_gl_context_has_framebuffer_blit (window->gl_paint_context) &&
-      cairo_region_contains_rectangle (update_area, &whole_window) != CAIRO_REGION_OVERLAP_IN)
-    {
-      context_win32->do_blit_swap = TRUE;
-    }
-  else
-    invalidate_all = TRUE;
-
-  if (invalidate_all)
-    {
-      window_rect.x = 0;
-      window_rect.y = 0;
-      window_rect.width = gdk_window_get_width (window);
-      window_rect.height = gdk_window_get_height (window);
-
-      /* If nothing else is known, repaint everything so that the back
-         buffer is fully up-to-date for the swapbuffer */
-      cairo_region_union_rectangle (update_area, &window_rect);
-    }
+  /* If nothing else is known, repaint everything so that the back
+     buffer is fully up-to-date for the swapbuffer */
+  window = gdk_gl_context_get_window (context);
+  cairo_region_union_rectangle (update_area, &(GdkRectangle) {
+                                                 0, 0,
+                                                 gdk_window_get_width (window),
+                                                 gdk_window_get_height (window) });
 }
 
 typedef struct
@@ -630,9 +602,9 @@ _set_pixformat_for_hdc (HDC              hdc,
   return TRUE;
 }
 
-gboolean
-_gdk_win32_gl_context_realize (GdkGLContext *context,
-                               GError **error)
+static gboolean
+gdk_win32_gl_context_realize (GdkGLContext *context,
+                              GError **error)
 {
   GdkGLContext *share = gdk_gl_context_get_shared_context (context);
   GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
@@ -730,6 +702,24 @@ _gdk_win32_gl_context_realize (GdkGLContext *context,
   return TRUE;
 }
 
+static void
+gdk_win32_gl_context_class_init (GdkWin32GLContextClass *klass)
+{
+  GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  context_class->begin_frame = gdk_win32_gl_context_begin_frame;
+  context_class->end_frame = gdk_win32_gl_context_end_frame;
+  context_class->realize = _gdk_win32_gl_context_realize;
+
+  gobject_class->dispose = _gdk_win32_gl_context_dispose;
+}
+
+static void
+gdk_win32_gl_context_init (GdkWin32GLContext *self)
+{
+}
+
 GdkGLContext *
 _gdk_win32_window_create_gl_context (GdkWindow *window,
                                      gboolean attached,
diff --git a/gdk/win32/gdkglcontext-win32.h b/gdk/win32/gdkglcontext-win32.h
index 6470b92..328f54a 100644
--- a/gdk/win32/gdkglcontext-win32.h
+++ b/gdk/win32/gdkglcontext-win32.h
@@ -44,7 +44,6 @@ struct _GdkWin32GLContext
   /* other items */
   guint is_attached : 1;
   guint do_frame_sync : 1;
-  guint do_blit_swap : 1;
 };
 
 struct _GdkWin32GLContextClass
@@ -58,23 +57,10 @@ _gdk_win32_window_create_gl_context (GdkWindow *window,
                                      GdkGLContext *share,
                                      GError **error);
 
-void
-_gdk_win32_window_invalidate_for_new_frame (GdkWindow *window,
-                                            cairo_region_t *update_area);
-
-void
-_gdk_win32_gl_context_end_frame (GdkGLContext *context,
-                                 cairo_region_t *painted,
-                                 cairo_region_t *damage);
-
 gboolean
 _gdk_win32_display_make_gl_context_current (GdkDisplay *display,
                                             GdkGLContext *context);
 
-gboolean
-_gdk_win32_gl_context_realize (GdkGLContext *context,
-                               GError **error);
-
 G_END_DECLS
 
 #endif /* __GDK_WIN32_GL_CONTEXT__ */
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index cddd9ef..f6fdbf2 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -6114,7 +6114,6 @@ gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
   impl_class->change_property = _gdk_win32_window_change_property;
   impl_class->delete_property = _gdk_win32_window_delete_property;
   impl_class->create_gl_context = _gdk_win32_window_create_gl_context;
-  impl_class->invalidate_for_new_frame = _gdk_win32_window_invalidate_for_new_frame;
   impl_class->get_scale_factor = _gdk_win32_window_get_scale_factor;
   impl_class->get_unscaled_size = _gdk_win32_window_get_unscaled_size;
 }
diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c
index 77103b5..16ebb42 100644
--- a/gdk/x11/gdkglcontext-x11.c
+++ b/gdk/x11/gdkglcontext-x11.c
@@ -119,79 +119,22 @@ maybe_wait_for_vblank (GdkDisplay  *display,
     }
 }
 
-void
-gdk_x11_window_invalidate_for_new_frame (GdkWindow      *window,
-                                         cairo_region_t *update_area)
+static void
+gdk_x11_gl_context_begin_frame (GdkGLContext   *context,
+                                cairo_region_t *update_area)
 {
-  cairo_rectangle_int_t window_rect;
-  GdkDisplay *display = gdk_window_get_display (window);
-  GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
-  Display *dpy = gdk_x11_display_get_xdisplay (display);
-  GdkX11GLContext *context_x11;
-  unsigned int buffer_age;
-  gboolean invalidate_all;
+  GdkWindow *window;
 
-  /* Minimal update is ok if we're not drawing with gl */
-  if (window->gl_paint_context == NULL)
+  if (gdk_gl_context_has_framebuffer_blit (context))
     return;
 
-  context_x11 = GDK_X11_GL_CONTEXT (window->gl_paint_context);
-
-  buffer_age = 0;
-
-  context_x11->do_blit_swap = FALSE;
-
-  if (display_x11->has_glx_buffer_age)
-    {
-      gdk_gl_context_make_current (window->gl_paint_context);
-      glXQueryDrawable(dpy, context_x11->drawable,
-                      GLX_BACK_BUFFER_AGE_EXT, &buffer_age);
-    }
-
-
-  invalidate_all = FALSE;
-  if (buffer_age == 0 || buffer_age >= 4)
-    {
-      cairo_rectangle_int_t whole_window = { 0, 0, gdk_window_get_width (window), gdk_window_get_height 
(window) };
-
-      if (gdk_gl_context_has_framebuffer_blit (window->gl_paint_context) &&
-          cairo_region_contains_rectangle (update_area, &whole_window) != CAIRO_REGION_OVERLAP_IN)
-        {
-          context_x11->do_blit_swap = TRUE;
-        }
-      else
-        invalidate_all = TRUE;
-    }
-  else
-    {
-      if (buffer_age >= 2)
-        {
-          if (window->old_updated_area[0])
-            cairo_region_union (update_area, window->old_updated_area[0]);
-          else
-            invalidate_all = TRUE;
-        }
-      if (buffer_age >= 3)
-        {
-          if (window->old_updated_area[1])
-            cairo_region_union (update_area, window->old_updated_area[1]);
-          else
-            invalidate_all = TRUE;
-        }
-    }
-
-  if (invalidate_all)
-    {
-      window_rect.x = 0;
-      window_rect.y = 0;
-      window_rect.width = gdk_window_get_width (window);
-      window_rect.height = gdk_window_get_height (window);
-
-      /* If nothing else is known, repaint everything so that the back
-         buffer is fully up-to-date for the swapbuffer */
-      cairo_region_union_rectangle (update_area, &window_rect);
-    }
-
+  window = gdk_gl_context_get_window (context);
+  /* If nothing else is known, repaint everything so that the back
+     buffer is fully up-to-date for the swapbuffer */
+  cairo_region_union_rectangle (update_area, &(GdkRectangle) {
+                                                 0, 0,
+                                                 gdk_window_get_width (window),
+                                                 gdk_window_get_height (window) });
 }
 
 static void
@@ -218,25 +161,27 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
                               cairo_region_t *painted,
                               cairo_region_t *damage)
 {
-  GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
+  GdkGLContext *shared = gdk_gl_context_get_shared_context (context);
+  GdkX11GLContext *shared_x11 = GDK_X11_GL_CONTEXT (shared);
   GdkWindow *window = gdk_gl_context_get_window (context);
   GdkDisplay *display = gdk_gl_context_get_display (context);
   Display *dpy = gdk_x11_display_get_xdisplay (display);
   GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
+  GdkRectangle whole_window;
   DrawableInfo *info;
   GLXDrawable drawable;
 
-  gdk_gl_context_make_current (context);
+  gdk_gl_context_make_current (shared);
 
   info = get_glx_drawable_info (window);
 
-  drawable = context_x11->drawable;
+  drawable = shared_x11->drawable;
 
   GDK_NOTE (OPENGL,
             g_message ("Flushing GLX buffers for drawable %lu (window: %lu), frame sync: %s",
                        (unsigned long) drawable,
                        (unsigned long) gdk_x11_window_get_xid (window),
-                       context_x11->do_frame_sync ? "yes" : "no"));
+                       shared_x11->do_frame_sync ? "yes" : "no"));
 
   /* if we are going to wait for the vertical refresh manually
    * we need to flush pending redraws, and we also need to wait
@@ -246,7 +191,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
    * GLX_SGI_swap_control, and we ask the driver to do the right
    * thing.
    */
-  if (context_x11->do_frame_sync)
+  if (shared_x11->do_frame_sync)
     {
       guint32 end_frame_counter = 0;
       gboolean has_counter = display_x11->has_glx_video_sync;
@@ -255,7 +200,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
       if (display_x11->has_glx_video_sync)
         glXGetVideoSyncSGI (&end_frame_counter);
 
-      if (context_x11->do_frame_sync && !display_x11->has_glx_swap_interval)
+      if (shared_x11->do_frame_sync && !display_x11->has_glx_swap_interval)
         {
           glFinish ();
 
@@ -271,7 +216,12 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
         }
     }
 
-  if (context_x11->do_blit_swap)
+  whole_window = (GdkRectangle) { 0, 0, gdk_window_get_width (window), gdk_window_get_height (window) };
+  if (cairo_region_contains_rectangle (painted, &whole_window) == CAIRO_REGION_OVERLAP_IN)
+    {
+      glXSwapBuffers (dpy, drawable);
+    }
+  else if (gdk_gl_context_has_framebuffer_blit (shared))
     {
       glDrawBuffer(GL_FRONT);
       glReadBuffer(GL_BACK);
@@ -279,13 +229,16 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
       glDrawBuffer(GL_BACK);
       glFlush();
 
-      if (gdk_gl_context_has_frame_terminator (context))
+      if (gdk_gl_context_has_frame_terminator (shared))
         glFrameTerminatorGREMEDY ();
     }
   else
-    glXSwapBuffers (dpy, drawable);
+    {
+      g_warning ("Need to swap whole buffer even thouigh not everything was redrawn. Expect artifacts.");
+      glXSwapBuffers (dpy, drawable);
+    }
 
-  if (context_x11->do_frame_sync && info != NULL && display_x11->has_glx_video_sync)
+  if (shared_x11->do_frame_sync && info != NULL && display_x11->has_glx_video_sync)
     glXGetVideoSyncSGI (&info->last_frame_counter);
 }
 
@@ -828,6 +781,7 @@ gdk_x11_gl_context_class_init (GdkX11GLContextClass *klass)
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
   context_class->realize = gdk_x11_gl_context_realize;
+  context_class->begin_frame = gdk_x11_gl_context_begin_frame;
   context_class->end_frame = gdk_x11_gl_context_end_frame;
   context_class->texture_from_surface = gdk_x11_gl_context_texture_from_surface;
 
diff --git a/gdk/x11/gdkglcontext-x11.h b/gdk/x11/gdkglcontext-x11.h
index 44cb0d5..c00834f 100644
--- a/gdk/x11/gdkglcontext-x11.h
+++ b/gdk/x11/gdkglcontext-x11.h
@@ -47,8 +47,6 @@ struct _GdkX11GLContext
   guint is_attached : 1;
   guint is_direct : 1;
   guint do_frame_sync : 1;
-
-  guint do_blit_swap : 1;
 };
 
 struct _GdkX11GLContextClass
@@ -61,8 +59,6 @@ GdkGLContext *  gdk_x11_window_create_gl_context                (GdkWindow
                                                                 gboolean           attached,
                                                                  GdkGLContext      *share,
                                                                  GError           **error);
-void            gdk_x11_window_invalidate_for_new_frame         (GdkWindow         *window,
-                                                                 cairo_region_t    *update_area);
 gboolean        gdk_x11_display_make_gl_context_current         (GdkDisplay        *display,
                                                                  GdkGLContext      *context);
 
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index 09de9b2..c339a9d 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -5393,6 +5393,5 @@ gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
   impl_class->set_shadow_width = gdk_x11_window_set_shadow_width;
   impl_class->show_window_menu = gdk_x11_window_show_window_menu;
   impl_class->create_gl_context = gdk_x11_window_create_gl_context;
-  impl_class->invalidate_for_new_frame = gdk_x11_window_invalidate_for_new_frame;
   impl_class->get_unscaled_size = gdk_x11_window_get_unscaled_size;
 }


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