From 6016e17a38230165dfb44fcc954f7ded03ea1867 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Mon, 21 Feb 2022 23:53:55 -0800 Subject: [PATCH] macos: double buffer IOSurface It looks like, particularly on the M1, we might need to double buffer the contents of the IOSurface<->OpenGL texture bindings. This doesn't appear to show up on the Intel macbooks I've tried, but I've seen it in the wild on an M1. --- gdk/macos/gdkmacossurface-private.h | 1 + gdk/macos/gdkmacossurface.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/gdk/macos/gdkmacossurface-private.h b/gdk/macos/gdkmacossurface-private.h index 472058da52..2abc199698 100644 --- a/gdk/macos/gdkmacossurface-private.h +++ b/gdk/macos/gdkmacossurface-private.h @@ -47,6 +47,7 @@ struct _GdkMacosSurface GdkMacosWindow *window; GdkMacosBuffer *buffer; + GdkMacosBuffer *front; GPtrArray *monitors; cairo_region_t *opaque_region; char *title; diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c index 5404d1e3b8..b49f4bb333 100644 --- a/gdk/macos/gdkmacossurface.c +++ b/gdk/macos/gdkmacossurface.c @@ -152,6 +152,7 @@ gdk_macos_surface_hide (GdkSurface *surface) _gdk_surface_clear_update_area (surface); g_clear_object (&self->buffer); + g_clear_object (&self->front); if (was_key) { @@ -427,6 +428,9 @@ gdk_macos_surface_destroy (GdkSurface *surface, g_clear_pointer (&self->monitors, g_ptr_array_unref); + g_clear_object (&self->buffer); + g_clear_object (&self->front); + g_assert (self->sorted.prev == NULL); g_assert (self->sorted.next == NULL); g_assert (self->frame.prev == NULL); @@ -781,6 +785,7 @@ _gdk_macos_surface_configure (GdkMacosSurface *self) surface->height = content_rect.size.height; g_clear_object (&self->buffer); + g_clear_object (&self->front); _gdk_surface_update_size (surface); gdk_surface_request_layout (surface); @@ -1032,6 +1037,7 @@ _gdk_macos_surface_monitor_changed (GdkMacosSurface *self) /* We need to create a new IOSurface for this monitor */ g_clear_object (&self->buffer); + g_clear_object (&self->front); _gdk_macos_surface_configure (self); @@ -1156,14 +1162,20 @@ void _gdk_macos_surface_swap_buffers (GdkMacosSurface *self, const cairo_region_t *damage) { + GdkMacosBuffer *swap; + g_return_if_fail (GDK_IS_MACOS_SURFACE (self)); g_return_if_fail (damage != NULL); + swap = self->buffer; + self->buffer = self->front; + self->front = swap; + /* This code looks like it swaps buffers, but since the IOSurfaceRef * appears to be retained on the other side, we really just ask all * of the GdkMacosTile CALayer's to update their contents. */ - [self->window swapBuffer:self->buffer withDamage:damage]; + [self->window swapBuffer:swap withDamage:damage]; /* We might have delayed actually showing the window until the buffer * contents are ready to be displayed. Doing so ensures that we don't -- 2.30.2