[gtk/mask-nodes: 11/11] Apply scale for the path cache




commit 47cce470fe3da22faa70a0cf1ff459234dc460cc
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Dec 18 00:47:13 2020 -0500

    Apply scale for the path cache
    
    Take scale into account when generating path masks,
    and make them part of the cache keys. This keeps
    our path rendering smooth as the zoom level is
    increased. This can be seen in action in the curve2
    test.

 gsk/gl/gskglpathcache.c        | 15 +++++++++++++++
 gsk/gl/gskglpathcacheprivate.h |  4 ++++
 gsk/gl/gskglrenderer.c         | 21 +++++++++++++++------
 3 files changed, 34 insertions(+), 6 deletions(-)
---
diff --git a/gsk/gl/gskglpathcache.c b/gsk/gl/gskglpathcache.c
index 1dcb0c33d8..13f159e7c1 100644
--- a/gsk/gl/gskglpathcache.c
+++ b/gsk/gl/gskglpathcache.c
@@ -10,6 +10,8 @@ typedef struct
   GskPath *path;
   GskFillRule fill_rule;
   const GskStroke *stroke;
+  float scale_x;
+  float scale_y;
   guint hash;
 
   GskStroke stroke_copy;
@@ -27,6 +29,8 @@ compute_hash (CacheItem *item)
   hash += item->fill_rule;
   if (item->stroke)
     hash += gsk_stroke_hash (item->stroke);
+  hash += (int)(item->scale_x * 100);
+  hash += (int)(item->scale_y * 200);
 
   return hash;
 }
@@ -48,6 +52,8 @@ cache_key_equal (gconstpointer v1,
 
   return item1->path == item2->path &&
          item1->fill_rule == item2->fill_rule &&
+         item1->scale_x == item2->scale_x &&
+         item1->scale_y == item2->scale_y &&
          (item1->stroke == item2->stroke ||
           (item1->stroke && item2->stroke &&
            gsk_stroke_equal (item1->stroke, item2->stroke)));
@@ -102,6 +108,8 @@ gsk_gl_path_cache_get_texture_id (GskGLPathCache  *self,
                                   GskPath         *path,
                                   GskFillRule      fill_rule,
                                   const GskStroke *stroke,
+                                  float            scale_x,
+                                  float            scale_y,
                                   graphene_rect_t *out_bounds)
 {
   CacheItem key;
@@ -110,6 +118,8 @@ gsk_gl_path_cache_get_texture_id (GskGLPathCache  *self,
   key.path = path;
   key.fill_rule = fill_rule;
   key.stroke = stroke;
+  key.scale_x = scale_x;
+  key.scale_y = scale_y;
   key.hash = compute_hash (&key);
 
   item = g_hash_table_lookup (self->textures, &key);
@@ -130,6 +140,8 @@ gsk_gl_path_cache_commit (GskGLPathCache        *self,
                           GskPath               *path,
                           GskFillRule            fill_rule,
                           const GskStroke       *stroke,
+                          float                  scale_x,
+                          float                  scale_y,
                           int                    texture_id,
                           const graphene_rect_t *bounds)
 {
@@ -147,6 +159,9 @@ gsk_gl_path_cache_commit (GskGLPathCache        *self,
       gsk_stroke_init_copy (&item->stroke_copy, stroke);
       item->stroke = &item->stroke_copy;
     }
+  item->scale_x = scale_x;
+  item->scale_y = scale_y;
+
   item->hash = compute_hash (item);
 
   item->unused_frames = 0;
diff --git a/gsk/gl/gskglpathcacheprivate.h b/gsk/gl/gskglpathcacheprivate.h
index 181d4be26f..cc2081c8ea 100644
--- a/gsk/gl/gskglpathcacheprivate.h
+++ b/gsk/gl/gskglpathcacheprivate.h
@@ -20,11 +20,15 @@ int  gsk_gl_path_cache_get_texture_id (GskGLPathCache        *self,
                                        GskPath               *path,
                                        GskFillRule            fill_rule,
                                        const GskStroke       *stroke,
+                                       float                  scale_x,
+                                       float                  scale_y,
                                        graphene_rect_t       *out_bounds);
 void gsk_gl_path_cache_commit         (GskGLPathCache        *self,
                                        GskPath               *path,
                                        GskFillRule            fill_rule,
                                        const GskStroke       *stroke,
+                                       float                  scale_x,
+                                       float                  scale_y,
                                        int                    texture_id,
                                        const graphene_rect_t *bounds);
 
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 54ccef5659..dda87ddb52 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -2767,6 +2767,8 @@ render_mask_node (GskGLRenderer   *self,
 static GdkTexture *
 make_path_mask (GskPath         *path,
                 GskFillRule      fill_rule,
+                float            scale_x,
+                float            scale_y,
                 graphene_rect_t *bounds)
 {
   cairo_surface_t *surface;
@@ -2780,8 +2782,8 @@ make_path_mask (GskPath         *path,
 
   gsk_path_get_bounds (path, bounds);
 
-  width = ceilf (bounds->size.width);
-  height = ceilf (bounds->size.height);
+  width = ceilf (bounds->size.width * scale_x);
+  height = ceilf (bounds->size.height * scale_y);
   stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width);
 
   buffer = g_malloc0 (stride * height);
@@ -2789,6 +2791,7 @@ make_path_mask (GskPath         *path,
                                                  CAIRO_FORMAT_ARGB32,
                                                  width, height,
                                                  stride);
+  cairo_surface_set_device_scale (surface, scale_x, scale_y);
 
   cr = cairo_create (surface);
   cairo_translate (cr, 0, bounds->size.height);
@@ -2838,6 +2841,8 @@ render_fill_node (GskGLRenderer   *self,
   graphene_rect_t mask_bounds;
   int mask_texture_id;
   OpMask *op;
+  float scale_x = builder->scale_x;
+  float scale_y = builder->scale_y;
 
   if (!add_offscreen_ops (self, builder,
                           &node->bounds,
@@ -2849,19 +2854,19 @@ render_fill_node (GskGLRenderer   *self,
       return;
     }
 
-  /* TODO: apply scale */
   path = gsk_fill_node_get_path (node);
   fill_rule = gsk_fill_node_get_fill_rule (node);
   mask_texture_id = gsk_gl_path_cache_get_texture_id (&self->path_cache,
                                                       path,
                                                       fill_rule,
                                                       NULL,
+                                                      scale_x, scale_y,
                                                       &mask_bounds);
   if (mask_texture_id == 0)
     {
       GdkTexture *mask;
 
-      mask = make_path_mask (path, fill_rule, &mask_bounds);
+      mask = make_path_mask (path, fill_rule, scale_x, scale_y, &mask_bounds);
 
       mask_texture_id =
           gsk_gl_driver_get_texture_for_texture (self->gl_driver,
@@ -2874,6 +2879,7 @@ render_fill_node (GskGLRenderer   *self,
                                 path,
                                 fill_rule,
                                 NULL,
+                                scale_x, scale_y,
                                 mask_texture_id,
                                 &mask_bounds);
 
@@ -2907,6 +2913,8 @@ render_stroke_node (GskGLRenderer   *self,
   int mask_texture_id;
   graphene_rect_t mask_bounds;
   OpMask *op;
+  float scale_x = builder->scale_x;
+  float scale_y = builder->scale_y;
 
   if (!add_offscreen_ops (self, builder,
                           &node->bounds,
@@ -2918,7 +2926,6 @@ render_stroke_node (GskGLRenderer   *self,
       return;
     }
 
-  /* TODO: apply scale */
   path = gsk_stroke_node_get_path (node);
   stroke = (GskStroke *)gsk_stroke_node_get_stroke (node);
 
@@ -2926,6 +2933,7 @@ render_stroke_node (GskGLRenderer   *self,
                                                       path,
                                                       GSK_FILL_RULE_WINDING,
                                                       stroke,
+                                                      scale_x, scale_y,
                                                       &mask_bounds);
   if (mask_texture_id == 0)
     {
@@ -2933,7 +2941,7 @@ render_stroke_node (GskGLRenderer   *self,
       GdkTexture *mask;
 
       stroke_path = gsk_path_stroke (path, stroke);
-      mask = make_path_mask (stroke_path, GSK_FILL_RULE_WINDING, &mask_bounds);
+      mask = make_path_mask (stroke_path, GSK_FILL_RULE_WINDING, scale_x, scale_y, &mask_bounds);
 
       mask_texture_id =
           gsk_gl_driver_get_texture_for_texture (self->gl_driver,
@@ -2946,6 +2954,7 @@ render_stroke_node (GskGLRenderer   *self,
                                 path,
                                 GSK_FILL_RULE_WINDING,
                                 stroke,
+                                scale_x, scale_y,
                                 mask_texture_id,
                                 &mask_bounds);
       g_object_unref (mask);


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