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
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);
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);
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))
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
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;
}
}