Merge branch 'wip/otte/for-main' into 'main'

2 GDK GL XWayland improvements

See merge request GNOME/gtk!6014
This commit is contained in:
Benjamin Otte 2023-05-24 22:22:48 +00:00
commit d912628583
4 changed files with 76 additions and 54 deletions

View 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;
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)
{
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]);
}
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:
;
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);

View 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 4
#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

View File

@ -144,7 +144,8 @@ struct _GdkX11Display
guint server_time_is_monotonic_time : 1;
/* GLX extensions we check */
guint has_glx_swap_interval : 1;
guint has_glx_sgi_swap_control : 1;
guint has_glx_swap_control : 1;
guint has_glx_create_context : 1;
guint has_glx_texture_from_pixmap : 1;
guint has_glx_video_sync : 1;

View File

@ -162,7 +162,7 @@ gdk_x11_gl_context_glx_end_frame (GdkDrawContext *draw_context,
if (display_x11->has_glx_video_sync)
glXGetVideoSyncSGI (&end_frame_counter);
if (self->do_frame_sync && !display_x11->has_glx_swap_interval)
if (self->do_frame_sync && !display_x11->has_glx_sgi_swap_control && !display_x11->has_glx_swap_control)
{
glFinish ();
@ -249,7 +249,7 @@ gdk_x11_gl_context_glx_make_current (GdkGLContext *context,
if (!glXMakeContextCurrent (dpy, drawable, drawable, self->glx_context))
return FALSE;
if (!surfaceless && GDK_X11_DISPLAY (display)->has_glx_swap_interval)
if (!surfaceless)
{
/* If the WM is compositing there is no particular need to delay
* the swap when drawing on the offscreen, rendering to the screen
@ -257,14 +257,35 @@ gdk_x11_gl_context_glx_make_current (GdkGLContext *context,
* to the vblank. */
do_frame_sync = ! gdk_display_is_composited (display);
if (do_frame_sync != self->do_frame_sync)
if (GDK_X11_DISPLAY (display)->has_glx_swap_control)
{
self->do_frame_sync = do_frame_sync;
if (do_frame_sync != self->do_frame_sync)
{
self->do_frame_sync = do_frame_sync;
if (do_frame_sync)
glXSwapIntervalSGI (1);
else
glXSwapIntervalSGI (0);
if (do_frame_sync)
glXSwapIntervalEXT (dpy, drawable, 1);
else
glXSwapIntervalEXT (dpy, drawable, 0);
}
}
else if (GDK_X11_DISPLAY (display)->has_glx_sgi_swap_control)
{
/* If the WM is compositing there is no particular need to delay
* the swap when drawing on the offscreen, rendering to the screen
* happens later anyway, and its up to the compositor to sync that
* to the vblank. */
do_frame_sync = ! gdk_display_is_composited (display);
if (do_frame_sync != self->do_frame_sync)
{
self->do_frame_sync = do_frame_sync;
if (do_frame_sync)
glXSwapIntervalSGI (1);
else
glXSwapIntervalSGI (0);
}
}
}
@ -287,29 +308,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;
}
}
@ -945,8 +957,10 @@ gdk_x11_display_init_glx (GdkX11Display *display_x11,
epoxy_has_glx_extension (dpy, screen_num, "GLX_ARB_create_context_profile");
display_x11->has_glx_create_es2_context =
epoxy_has_glx_extension (dpy, screen_num, "GLX_EXT_create_context_es2_profile");
display_x11->has_glx_swap_interval =
display_x11->has_glx_sgi_swap_control =
epoxy_has_glx_extension (dpy, screen_num, "GLX_SGI_swap_control");
display_x11->has_glx_swap_control =
epoxy_has_glx_extension (dpy, screen_num, "GLX_EXT_swap_control");
display_x11->has_glx_texture_from_pixmap =
epoxy_has_glx_extension (dpy, screen_num, "GLX_EXT_texture_from_pixmap");
display_x11->has_glx_video_sync =
@ -1007,6 +1021,7 @@ gdk_x11_display_init_glx (GdkX11Display *display_x11,
"\t* GLX_ARB_create_context_profile: %s\n"
"\t* GLX_EXT_create_context_es2_profile: %s\n"
"\t* GLX_SGI_swap_control: %s\n"
"\t* GLX_EXT_swap_control: %s\n"
"\t* GLX_EXT_texture_from_pixmap: %s\n"
"\t* GLX_SGI_video_sync: %s\n"
"\t* GLX_EXT_buffer_age: %s\n"
@ -1018,7 +1033,8 @@ gdk_x11_display_init_glx (GdkX11Display *display_x11,
glXGetClientString (dpy, GLX_VENDOR),
display_x11->has_glx_create_context ? "yes" : "no",
display_x11->has_glx_create_es2_context ? "yes" : "no",
display_x11->has_glx_swap_interval ? "yes" : "no",
display_x11->has_glx_sgi_swap_control ? "yes" : "no",
display_x11->has_glx_swap_control ? "yes" : "no",
display_x11->has_glx_texture_from_pixmap ? "yes" : "no",
display_x11->has_glx_video_sync ? "yes" : "no",
display_x11->has_glx_buffer_age ? "yes" : "no",