gl: Rewrite update area tracking code
authorBenjamin Otte <otte@redhat.com>
Wed, 24 May 2023 19:40:20 +0000 (21:40 +0200)
committerBenjamin Otte <otte@redhat.com>
Wed, 24 May 2023 19:44:29 +0000 (21:44 +0200)
Make it more generic. That way we could dynamically change the number of
buffers we track.

We don't do that yet though.

gdk/gdkglcontext.c
gdk/gdkglcontextprivate.h
gdk/x11/gdkglcontext-glx.c

index 7f8cf27abd137416476e5b20959643750b37d049..f9dd8128bbb942dc6752312a69dd0e5c7ed357a1 100644 (file)
@@ -466,29 +466,26 @@ gdk_gl_context_real_get_damage (GdkGLContext *context)
       eglQuerySurface (gdk_display_get_egl_display (display), egl_surface,
                        EGL_BUFFER_AGE_EXT, &buffer_age);
 
-      switch (buffer_age)
+      if (buffer_age > 0 && buffer_age <= GDK_GL_MAX_TRACKED_BUFFERS)
         {
-          case 1:
-            return cairo_region_create ();
-            break;
-
-          case 2:
-            if (context->old_updated_area[0])
-              return cairo_region_copy (context->old_updated_area[0]);
-            break;
-
-          case 3:
-            if (context->old_updated_area[0] &&
-                context->old_updated_area[1])
-              {
-                cairo_region_t *damage = cairo_region_copy (context->old_updated_area[0]);
-                cairo_region_union (damage, context->old_updated_area[1]);
-                return damage;
-              }
-            break;
-
-          default:
-            ;
+          cairo_region_t *damage = cairo_region_create ();
+          int i;
+
+          for (i = 0; i < buffer_age - 1; i++)
+            {
+              if (context->old_updated_area[i] == NULL)
+                {
+                  cairo_region_create_rectangle (&(GdkRectangle) {
+                                                     0, 0,
+                                                     gdk_surface_get_width (surface),
+                                                     gdk_surface_get_height (surface)
+                                                 });
+                  break;
+                }
+              cairo_region_union (damage, context->old_updated_area[i]);
+            }
+
+          return damage;
         }
     }
 #endif
@@ -597,6 +594,7 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
   cairo_region_t *damage;
   double scale;
   int ww, wh;
+  int i;
 
   surface = gdk_draw_context_get_surface (draw_context);
   scale = gdk_gl_context_get_scale (context);
@@ -608,9 +606,11 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
 
   damage = GDK_GL_CONTEXT_GET_CLASS (context)->get_damage (context);
 
-  if (context->old_updated_area[1])
-    cairo_region_destroy (context->old_updated_area[1]);
-  context->old_updated_area[1] = context->old_updated_area[0];
+  g_clear_pointer (&context->old_updated_area[GDK_GL_MAX_TRACKED_BUFFERS - 1], cairo_region_destroy);
+  for (i = GDK_GL_MAX_TRACKED_BUFFERS - 1; i > 0; i--)
+    {
+      context->old_updated_area[i] = context->old_updated_area[i - 1];
+    }
   context->old_updated_area[0] = cairo_region_copy (region);
 
   cairo_region_union (region, damage);
index f09d5756b12f9697d60260112f052aef6de010e4..cd28d48a7a9c6a283b9e3bedae8ea82245c21b58 100644 (file)
@@ -34,6 +34,11 @@ typedef enum {
   GDK_GL_CGL
 } GdkGLBackend;
 
+/* The maximum amount of buffers we track update regions for.
+ * Note that this is equal to the max buffer age value we
+ * can provide a damage region for */
+#define GDK_GL_MAX_TRACKED_BUFFERS 2
+
 #define GDK_GL_CONTEXT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GL_CONTEXT, GdkGLContextClass))
 #define GDK_IS_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_GL_CONTEXT))
 #define GDK_GL_CONTEXT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_GL_CONTEXT, GdkGLContextClass))
@@ -45,7 +50,7 @@ struct _GdkGLContext
   GdkDrawContext parent_instance;
 
   /* We store the old drawn areas to support buffer-age optimizations */
-  cairo_region_t *old_updated_area[2];
+  cairo_region_t *old_updated_area[GDK_GL_MAX_TRACKED_BUFFERS];
 };
 
 struct _GdkGLContextClass
index f6cdedbd1f6123b31ea9f688504408a470b3ca64..805dae1c14b8ee5e12497add78d2f2afd85d196b 100644 (file)
@@ -287,29 +287,20 @@ gdk_x11_gl_context_glx_get_damage (GdkGLContext *context)
       glXQueryDrawable (dpy, gdk_x11_gl_context_glx_get_drawable (self),
                         GLX_BACK_BUFFER_AGE_EXT, &buffer_age);
 
-      switch (buffer_age)
+      if (buffer_age > 0 && buffer_age <= GDK_GL_MAX_TRACKED_BUFFERS)
         {
-          case 1:
-            return cairo_region_create ();
-            break;
+          cairo_region_t *damage = cairo_region_create ();
+          int i;
 
-          case 2:
-            if (context->old_updated_area[0])
-              return cairo_region_copy (context->old_updated_area[0]);
-            break;
+          for (i = 0; i < buffer_age - 1; i++)
+            {
+              if (context->old_updated_area[i] == NULL)
+                return GDK_GL_CONTEXT_CLASS (gdk_x11_gl_context_glx_parent_class)->get_damage (context);
 
-          case 3:
-            if (context->old_updated_area[0] &&
-                context->old_updated_area[1])
-              {
-                cairo_region_t *damage = cairo_region_copy (context->old_updated_area[0]);
-                cairo_region_union (damage, context->old_updated_area[1]);
-                return damage;
-              }
-            break;
+              cairo_region_union (damage, context->old_updated_area[i]);
+            }
 
-          default:
-            ;
+          return damage;
         }
     }