[gtk/wip/chergert/quartz4u] macos: keep full backing surface for drawing



commit 80b56cff8a69519b7f2c3265055892e0c7bb2fec
Author: Christian Hergert <chergert redhat com>
Date:   Wed May 6 10:46:27 2020 -0700

    macos: keep full backing surface for drawing

 gdk/macos/GdkMacosCairoView.c    | 21 +++++++++++++++------
 gdk/macos/GdkMacosCairoView.h    |  3 ++-
 gdk/macos/gdkmacoscairocontext.c | 34 ++++++++++++++++++++++++----------
 gdk/macos/gdkmacossurface.c      | 10 ++++++----
 4 files changed, 47 insertions(+), 21 deletions(-)
---
diff --git a/gdk/macos/GdkMacosCairoView.c b/gdk/macos/GdkMacosCairoView.c
index 6efac3b130..311be1802d 100644
--- a/gdk/macos/GdkMacosCairoView.c
+++ b/gdk/macos/GdkMacosCairoView.c
@@ -54,10 +54,7 @@
   guint n_rects;
 
   g_clear_pointer (&self->surface, cairo_surface_destroy);
-  g_clear_pointer (&self->region, cairo_region_destroy);
-
-  self->surface = cairoSurface;
-  self->region = cairoRegion;
+  self->surface = cairo_surface_reference (cairoSurface);
 
   n_rects = cairo_region_num_rectangles (cairoRegion);
 
@@ -75,10 +72,12 @@
   GdkMacosSurface *gdkSurface;
   CGContextRef cg_context;
   cairo_surface_t *dest;
+  const NSRect *rects = NULL;
+  NSInteger n_rects = 0;
   cairo_t *cr;
   int scale_factor;
 
-  if (self->surface == NULL || self->region == NULL)
+  if (self->surface == NULL)
     return;
 
   gdkSurface = [self getGdkSurface];
@@ -93,7 +92,17 @@
   cr = cairo_create (dest);
 
   cairo_set_source_surface (cr, self->surface, 0, 0);
-  gdk_cairo_region (cr, self->region);
+
+  [self getRectsBeingDrawn:&rects count:&n_rects];
+  for (NSInteger i = 0; i < n_rects; i++)
+    {
+      const NSRect *r = &rects[i];
+      cairo_rectangle (cr,
+                       r->origin.x,
+                       r->origin.y,
+                       r->size.width,
+                       r->size.height);
+    }
   cairo_clip (cr);
 
   cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
diff --git a/gdk/macos/GdkMacosCairoView.h b/gdk/macos/GdkMacosCairoView.h
index c65de74eb0..c66e8b730a 100644
--- a/gdk/macos/GdkMacosCairoView.h
+++ b/gdk/macos/GdkMacosCairoView.h
@@ -23,10 +23,11 @@
 
 #import "GdkMacosBaseView.h"
 
+#define GDK_IS_MACOS_CAIRO_VIEW(obj) ([obj isKindOfClass:[GdkMacosCairoView class]])
+
 @interface GdkMacosCairoView : GdkMacosBaseView
 {
   cairo_surface_t *surface;
-  cairo_region_t  *region;
 }
 
 -(void)setCairoSurfaceWithRegion:(cairo_surface_t *)cairoSurface
diff --git a/gdk/macos/gdkmacoscairocontext.c b/gdk/macos/gdkmacoscairocontext.c
index 4852159614..21d05dc6fc 100644
--- a/gdk/macos/gdkmacoscairocontext.c
+++ b/gdk/macos/gdkmacoscairocontext.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright © 2016 Benjamin Otte
  * Copyright © 2020 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
@@ -83,19 +84,22 @@ _gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
   GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
   GdkRectangle clip_box;
   GdkSurface *surface;
-  double sx, sy;
+  double sx = 1.0;
+  double sy = 1.0;
 
   g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
+  g_assert (self->paint_surface == NULL);
 
   surface = gdk_draw_context_get_surface (draw_context);
-  cairo_region_get_extents (region, &clip_box);
 
-  self->window_surface = create_cairo_surface_for_surface (surface);
+  if (self->window_surface == NULL)
+    self->window_surface = create_cairo_surface_for_surface (surface);
+
+  cairo_region_get_extents (region, &clip_box);
   self->paint_surface = gdk_surface_create_similar_surface (surface,
                                                             cairo_surface_get_content (self->window_surface),
                                                             MAX (clip_box.width, 1),
                                                             MAX (clip_box.height, 1));
-
   sx = sy = 1;
   cairo_surface_get_device_scale (self->paint_surface, &sx, &sy);
   cairo_surface_set_device_offset (self->paint_surface, -clip_box.x*sx, -clip_box.y*sy);
@@ -110,6 +114,8 @@ _gdk_macos_cairo_context_end_frame (GdkDrawContext *draw_context,
   cairo_t *cr;
 
   g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
+  g_assert (self->paint_surface != NULL);
+  g_assert (self->window_surface != NULL);
 
   cr = cairo_create (self->window_surface);
 
@@ -121,17 +127,24 @@ _gdk_macos_cairo_context_end_frame (GdkDrawContext *draw_context,
   cairo_paint (cr);
 
   cairo_destroy (cr);
-
   cairo_surface_flush (self->window_surface);
 
   surface = gdk_draw_context_get_surface (draw_context);
-  if (GDK_IS_MACOS_SURFACE (surface))
-    _gdk_macos_surface_damage_cairo (GDK_MACOS_SURFACE (surface),
-                                     g_steal_pointer (&self->window_surface),
-                                     cairo_region_reference (painted));
-
+  _gdk_macos_surface_damage_cairo (GDK_MACOS_SURFACE (surface),
+                                   self->window_surface,
+                                   painted);
   g_clear_pointer (&self->paint_surface, cairo_surface_destroy);
+}
+
+static void
+_gdk_macos_cairo_context_surface_resized (GdkDrawContext *draw_context)
+{
+  GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
+
+  g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
+
   g_clear_pointer (&self->window_surface, cairo_surface_destroy);
+  g_clear_pointer (&self->paint_surface, cairo_surface_destroy);
 }
 
 static void
@@ -142,6 +155,7 @@ _gdk_macos_cairo_context_class_init (GdkMacosCairoContextClass *klass)
 
   draw_context_class->begin_frame = _gdk_macos_cairo_context_begin_frame;
   draw_context_class->end_frame = _gdk_macos_cairo_context_end_frame;
+  draw_context_class->surface_resized = _gdk_macos_cairo_context_surface_resized;
 
   cairo_context_class->cairo_create = _gdk_macos_cairo_context_cairo_create;
 }
diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c
index fd532986ba..7c20a3d7c1 100644
--- a/gdk/macos/gdkmacossurface.c
+++ b/gdk/macos/gdkmacossurface.c
@@ -689,14 +689,16 @@ _gdk_macos_surface_damage_cairo (GdkMacosSurface *self,
                                  cairo_region_t  *painted)
 {
   GdkMacosSurfacePrivate *priv = gdk_macos_surface_get_instance_private (self);
-  GdkMacosCairoView *view;
+  NSView *view;
 
   g_return_if_fail (GDK_IS_MACOS_SURFACE (self));
   g_return_if_fail (surface != NULL);
 
-  view = (GdkMacosCairoView *)[priv->window contentView];
-  [view setCairoSurfaceWithRegion:surface
-                      cairoRegion:painted];
+  view = [priv->window contentView];
+
+  if (GDK_IS_MACOS_CAIRO_VIEW (view))
+    [(GdkMacosCairoView *)view setCairoSurfaceWithRegion:surface
+                                             cairoRegion:painted];
 }
 
 void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]