[gtk/wip/chergert/macos-gl-opaque-context: 5/5] macos: make OpenGL context opaque when possible
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/macos-gl-opaque-context: 5/5] macos: make OpenGL context opaque when possible
- Date: Fri, 19 Feb 2021 21:10:22 +0000 (UTC)
commit b2fd09625c772008af7225b5f71ca172b3445daa
Author: Christian Hergert <chergert redhat com>
Date: Fri Feb 19 13:18:42 2021 -0800
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.
gdk/macos/gdkmacosglcontext.c | 32 ++++++++++++++++++++++++++++++++
gdk/macos/gdkmacossurface-private.h | 1 +
gdk/macos/gdkmacossurface.c | 10 +++++++++-
3 files changed, 42 insertions(+), 1 deletion(-)
---
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];
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]