[quartz] Manage implementation surface lifetime.

To prevent leaking cairo surfaces while persisting the parts that
don't need to be redrawn.
This commit is contained in:
John Ralls 2022-05-13 12:59:09 -07:00
parent df94d0168d
commit b94ed34f9c
3 changed files with 27 additions and 2 deletions

View File

@ -448,6 +448,7 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source,
copy_rectangle_argb32 (cvpb_surface, impl->cairo_surface, &extents);
cairo_surface_destroy (cvpb_surface);
_gdk_quartz_unref_cairo_surface (gdk_window);
CVPixelBufferUnlockBaseAddress (pixels, 0);
--impl->in_paint_rect_count;
self.layer.contents = NULL;
@ -522,6 +523,8 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source,
kCVPixelFormatType_32BGRA,
cfpb_props, &pixels);
//Force a new cairo_surface for drawing
_gdk_quartz_unref_cairo_surface (gdk_window);
[super setFrame: frame];
if ([self window])

View File

@ -33,5 +33,7 @@
GdkDisplay * _gdk_quartz_display_open (const gchar *name);
/* Window Impl */
void _gdk_quartz_unref_cairo_surface (GdkWindow *window);
#endif /* __GDK_PRIVATE_QUARTZ_H__ */

View File

@ -238,7 +238,9 @@ static void
gdk_quartz_cairo_surface_destroy (void *data)
{
GdkQuartzCairoSurfaceData *surface_data = data;
cairo_surface_t *surface = surface_data->window_impl->cairo_surface;
if (!cairo_surface_get_reference_count (surface))
surface_data->window_impl->cairo_surface = NULL;
g_free (surface_data);
@ -258,7 +260,6 @@ gdk_quartz_create_cairo_surface (GdkWindowImplQuartz *impl,
surface_data->cg_context = NULL;
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo_surface_set_user_data (surface, &gdk_quartz_cairo_key,
surface_data,
gdk_quartz_cairo_surface_destroy);
@ -291,11 +292,29 @@ gdk_quartz_ref_cairo_surface (GdkWindow *window)
cairo_surface_reference (impl->cairo_surface); // The caller will destroy the returned one.
}
else
cairo_surface_reference (impl->cairo_surface);
{
cairo_surface_reference (impl->cairo_surface);
}
return impl->cairo_surface;
}
void
_gdk_quartz_unref_cairo_surface (GdkWindow *window)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
if (GDK_WINDOW_DESTROYED (window))
return;
if (impl->cairo_surface)
{
cairo_surface_destroy (impl->cairo_surface);
if (impl->cairo_surface &&
!cairo_surface_get_reference_count (impl->cairo_surface))
impl->cairo_surface = NULL;
}
}
static void
gdk_window_impl_quartz_init (GdkWindowImplQuartz *impl)
{
@ -1312,6 +1331,7 @@ move_resize_window_internal (GdkWindow *window,
frame_rect = [impl->toplevel frameRectForContentRect:content_rect];
[impl->toplevel setFrame:frame_rect display:YES];
impl->cairo_surface = gdk_quartz_ref_cairo_surface (window);
}
else
{