summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Hergert <chergert@redhat.com>2021-02-19 13:18:42 -0800
committerChristian Hergert <chergert@redhat.com>2021-02-19 13:23:26 -0800
commitb2fd09625c772008af7225b5f71ca172b3445daa (patch)
tree07c4bc6343edf5e59165564eef49f2483a64253d
parent5797c72e9c2c17b52c4f7969eae0994636babba6 (diff)
downloadgtk+-b2fd09625c772008af7225b5f71ca172b3445daa.tar.gz
macos: make OpenGL context opaque when possiblewip/chergert/macos-gl-opaque-context
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.
-rw-r--r--gdk/macos/gdkmacosglcontext.c32
-rw-r--r--gdk/macos/gdkmacossurface-private.h1
-rw-r--r--gdk/macos/gdkmacossurface.c10
3 files changed, 42 insertions, 1 deletions
diff --git a/gdk/macos/gdkmacosglcontext.c b/gdk/macos/gdkmacosglcontext.c
index f50e837465..a8b28b05be 100644
--- a/gdk/macos/gdkmacosglcontext.c
+++ b/gdk/macos/gdkmacosglcontext.c
@@ -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];
diff --git a/gdk/macos/gdkmacossurface-private.h b/gdk/macos/gdkmacossurface-private.h
index c366c0b4e6..8a5ee526fa 100644
--- a/gdk/macos/gdkmacossurface-private.h
+++ b/gdk/macos/gdkmacossurface-private.h
@@ -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;
diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c
index 61e249497e..5fe5bb38e7 100644
--- a/gdk/macos/gdkmacossurface.c
+++ b/gdk/macos/gdkmacossurface.c
@@ -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];