From 8d4c4cdca49ab97a86dac19bc5f1a313c5a16870 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Tue, 31 May 2022 14:43:29 -0700 Subject: [PATCH] [quartz] Handle scale changes using NSView::shouldInheritContentsScale. Includes creating the CVPixelBuffer to supply the layer contents when creating the cairo_image_surface, which reduces the number of them created at the wrong scale. --- gdk/quartz/GdkQuartzView.c | 56 ++++++++++++++++++++--------------- gdk/quartz/GdkQuartzView.h | 3 +- gdk/quartz/gdkwindow-quartz.c | 2 +- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/gdk/quartz/GdkQuartzView.c b/gdk/quartz/GdkQuartzView.c index f7ac47dcc0..3a3bcdee0d 100644 --- a/gdk/quartz/GdkQuartzView.c +++ b/gdk/quartz/GdkQuartzView.c @@ -36,7 +36,6 @@ { if ((self = [super initWithFrame: frameRect])) { - CVReturn rv; pb_props = @{ (id)kCVPixelBufferIOSurfaceCoreAnimationCompatibilityKey: @1, (id)kCVPixelBufferBytesPerRowAlignmentKey: @64, @@ -46,10 +45,6 @@ markedRange = NSMakeRange (NSNotFound, 0); selectedRange = NSMakeRange (0, 0); - rv = CVPixelBufferCreate (NULL, frameRect.size.width, - frameRect.size.height, - kCVPixelFormatType_32ARGB, - cfpb_props, &pixels); } [self setValue: @(YES) forKey: @"postsFrameChangedNotifications"]; @@ -384,8 +379,8 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source, { g_warning ("Failed to map destination image surface, %d %d %d %d on %d %d: %s\n", rect->x, rect->y, rect->width, rect->height, - cairo_image_surface_get_width (source), - cairo_image_surface_get_height (source), + cairo_image_surface_get_width (dest), + cairo_image_surface_get_height (dest), cairo_status_to_string (status)); goto CLEANUP; } @@ -414,15 +409,8 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source, if (GDK_WINDOW_DESTROYED (gdk_window)) return; - ++impl->in_paint_rect_count; - CVPixelBufferLockBaseAddress (pixels, 0); - cvpb_surface = - cairo_image_surface_create_for_data (CVPixelBufferGetBaseAddress (pixels), - CAIRO_FORMAT_ARGB32, - (int)CVPixelBufferGetWidth (pixels), - (int)CVPixelBufferGetHeight (pixels), - (int)CVPixelBufferGetBytesPerRow (pixels)); + ++impl->in_paint_rect_count; cairo_rect_from_nsrect (&extents, &backing_bounds); if (impl->needs_display_region) { @@ -441,10 +429,18 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source, _gdk_window_process_updates_recurse (gdk_window, region); cairo_region_destroy (region); } - + if (!impl || !impl->cairo_surface) return; + CVPixelBufferLockBaseAddress (pixels, 0); + cvpb_surface = + cairo_image_surface_create_for_data (CVPixelBufferGetBaseAddress (pixels), + CAIRO_FORMAT_ARGB32, + (int)CVPixelBufferGetWidth (pixels), + (int)CVPixelBufferGetHeight (pixels), + (int)CVPixelBufferGetBytesPerRow (pixels)); + copy_rectangle_argb32 (cvpb_surface, impl->cairo_surface, &extents); cairo_surface_destroy (cvpb_surface); @@ -508,22 +504,34 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source, } } --(void)setFrame: (NSRect)frame +-(void)createBackingStoreWithWidth: (CGFloat) width andHeight: (CGFloat) height { CVReturn rv; - NSRect rect = self.layer ? self.layer.bounds : frame; - NSRect backing_rect = [self convertRectToBacking: rect]; - if (GDK_WINDOW_DESTROYED (gdk_window)) - return; + g_return_if_fail (width && height); CVPixelBufferRelease (pixels); - rv = CVPixelBufferCreate (NULL, backing_rect.size.width, - backing_rect.size.height, + rv = CVPixelBufferCreate (NULL, width, height, kCVPixelFormatType_32BGRA, cfpb_props, &pixels); - //Force a new cairo_surface for drawing +} + +-(BOOL)layer:(CALayer*) layer shouldInheritContentsScale: (CGFloat)scale fromWindow: (NSWindow *) window +{ + if (layer == self.layer && window == self.window) + { + _gdk_quartz_unref_cairo_surface (gdk_window); + [self setNeedsDisplay: YES]; + } + return YES; +} + +-(void)setFrame: (NSRect)frame +{ + if (GDK_WINDOW_DESTROYED (gdk_window)) + return; + _gdk_quartz_unref_cairo_surface (gdk_window); [super setFrame: frame]; diff --git a/gdk/quartz/GdkQuartzView.h b/gdk/quartz/GdkQuartzView.h index 0c1558a7ec..e1530bdd71 100644 --- a/gdk/quartz/GdkQuartzView.h +++ b/gdk/quartz/GdkQuartzView.h @@ -34,7 +34,7 @@ #define GIC_FILTER_PASSTHRU 0 #define GIC_FILTER_FILTERED 1 -@interface GdkQuartzView : NSView +@interface GdkQuartzView : NSView { GdkWindow *gdk_window; NSTrackingRectTag trackingRect; @@ -50,5 +50,6 @@ - (GdkWindow *)gdkWindow; - (NSTrackingRectTag)trackingRect; - (void)setNeedsInvalidateShadow: (BOOL)invalidate; +- (void)createBackingStoreWithWidth: (CGFloat) width andHeight: (CGFloat) height; @end diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c index a9bc6c6504..1800ca83ea 100644 --- a/gdk/quartz/gdkwindow-quartz.c +++ b/gdk/quartz/gdkwindow-quartz.c @@ -309,11 +309,11 @@ gdk_quartz_create_cairo_surface (GdkWindowImplQuartz *impl, GdkQuartzCairoSurfaceData *surface_data; cairo_surface_t *surface; - surface_data = g_new (GdkQuartzCairoSurfaceData, 1); surface_data->window_impl = impl; surface_data->cg_context = NULL; + [impl->view createBackingStoreWithWidth: width andHeight: height]; surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_surface_set_user_data (surface, &gdk_quartz_cairo_key, surface_data,