macos: make OpenGL context opaque when possible

If our opaque region is the entire surface, then we can make the OpenGL
context opaque like we do for decorated windows. This improves performance
as the compositor does not need to blend the surface with the contents
behind the window.
This commit is contained in:
Christian Hergert 2021-02-19 13:18:42 -08:00
parent 5797c72e9c
commit b2fd09625c
3 changed files with 42 additions and 1 deletions

View File

@ -267,6 +267,34 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
return TRUE;
}
static gboolean
opaque_region_covers_surface (GdkMacosGLContext *self)
{
GdkSurface *surface;
cairo_region_t *region;
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self));
region = GDK_MACOS_SURFACE (surface)->opaque_region;
if (region != NULL &&
cairo_region_num_rectangles (region) == 1)
{
cairo_rectangle_int_t extents;
cairo_region_get_extents (region, &extents);
if (extents.x == 0 &&
extents.y == 0 &&
extents.width == surface->width &&
extents.height == surface->height)
return TRUE;
}
return FALSE;
}
static void
gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
cairo_region_t *painted)
@ -315,6 +343,10 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
else
opaque = FALSE;
/* If we are maximized, we might be able to make it opaque */
if (opaque == FALSE)
opaque = opaque_region_covers_surface (self);
CGLSetParameter (cgl_context, kCGLCPSurfaceOpacity, &opaque);
[self->gl_context update];

View File

@ -48,6 +48,7 @@ struct _GdkMacosSurface
GdkMacosWindow *window;
GPtrArray *monitors;
cairo_region_t *input_region;
cairo_region_t *opaque_region;
char *title;
int root_x;

View File

@ -98,9 +98,16 @@ static void
gdk_macos_surface_set_opaque_region (GdkSurface *surface,
cairo_region_t *region)
{
GdkMacosSurface *self = (GdkMacosSurface *)surface;
NSView *nsview;
g_assert (GDK_IS_MACOS_SURFACE (surface));
g_assert (GDK_IS_MACOS_SURFACE (self));
if (region != self->opaque_region)
{
g_clear_pointer (&self->opaque_region, cairo_region_destroy);
self->opaque_region = cairo_region_copy (region);
}
if ((nsview = _gdk_macos_surface_get_view (GDK_MACOS_SURFACE (surface))) &&
GDK_IS_MACOS_CAIRO_VIEW (nsview))
@ -386,6 +393,7 @@ gdk_macos_surface_destroy (GdkSurface *surface,
}
g_clear_pointer (&self->title, g_free);
g_clear_pointer (&self->opaque_region, cairo_region_destroy);
if (window != NULL)
[window close];