[gtk/wip/matthiasc/shared-glyph-cache: 3/3] Consider all offscreen drawings for the icon cache



commit 66f67f2006ad3509c23b8b0616b8be0833054bd7
Author: Timm Bäder <tbaeder redhat com>
Date:   Tue Jun 4 17:28:59 2019 +0000

    Consider all offscreen drawings for the icon cache

 gsk/gl/gskglrenderer.c | 253 +++++++++++++++++++++++++++----------------------
 1 file changed, 140 insertions(+), 113 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index a288fea50b..ab7fcd1f01 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -67,6 +67,26 @@ typedef enum
   DUMP_FRAMEBUFFER = 1 << 3
 } OffscreenFlags;
 
+typedef struct
+{
+  int texture_id;
+  float x;
+  float y;
+  float x2;
+  float y2;
+} TextureRegion;
+
+static inline void
+init_full_texture_region (TextureRegion *r,
+                          int            texture_id)
+{
+  r->texture_id = texture_id;
+  r->x = 0;
+  r->y = 0;
+  r->x2 = 1;
+  r->y2 = 1;
+}
+
 static void G_GNUC_UNUSED
 print_render_node_tree (GskRenderNode *root, int level)
 {
@@ -187,15 +207,6 @@ font_has_color_glyphs (const PangoFont *font)
   return has_color;
 }
 
-static void
-get_gl_scaling_filters (GskRenderNode *node,
-                        int           *min_filter_r,
-                        int           *mag_filter_r)
-{
-  *min_filter_r = GL_LINEAR;
-  *mag_filter_r = GL_LINEAR;
-}
-
 static inline void
 rgba_to_float (const GdkRGBA *c,
                float         *f)
@@ -297,7 +308,7 @@ static void add_offscreen_ops                 (GskGLRenderer   *self,
                                                RenderOpBuilder       *builder,
                                                const graphene_rect_t *bounds,
                                                GskRenderNode         *child_node,
-                                               int                   *texture_id,
+                                               TextureRegion         *region_out,
                                                gboolean              *is_offscreen,
                                                guint                  flags);
 static void gsk_gl_renderer_add_render_ops     (GskGLRenderer   *self,
@@ -789,6 +800,42 @@ render_color_node (GskGLRenderer       *self,
   ops_draw (builder, vertex_data);
 }
 
+static inline void
+upload_texture (GskGLRenderer *self,
+                GdkTexture    *texture,
+                TextureRegion *out_region)
+{
+  int texture_id;
+
+  if (texture->width <= 128 &&
+      texture->height <= 128)
+    {
+      graphene_rect_t trect;
+
+      gsk_gl_icon_cache_lookup_or_add (self->icon_cache,
+                                       texture,
+                                       &texture_id,
+                                       &trect);
+      out_region->x = trect.origin.x;
+      out_region->y = trect.origin.y;
+      out_region->x2 = out_region->x + trect.size.width;
+      out_region->y2 = out_region->y + trect.size.height;
+    }
+  else
+    {
+      texture_id = gsk_gl_driver_get_texture_for_texture (self->gl_driver,
+                                                          texture,
+                                                          GL_LINEAR,
+                                                          GL_LINEAR);
+      out_region->x  = 0;
+      out_region->y  = 0;
+      out_region->x2 = 1;
+      out_region->y2 = 1;
+    }
+
+  out_region->texture_id = texture_id;
+}
+
 static inline void
 render_texture_node (GskGLRenderer       *self,
                      GskRenderNode       *node,
@@ -836,45 +883,21 @@ render_texture_node (GskGLRenderer       *self,
     }
   else
     {
-      int texture_id;
-      float tx = 0, ty = 0, tx2 = 1, ty2 = 1;
-
-      if (texture->width <= 128 &&
-          texture->height <= 128)
-        {
-          graphene_rect_t trect;
-
-          gsk_gl_icon_cache_lookup_or_add (self->icon_cache,
-                                           texture,
-                                           &texture_id,
-                                           &trect);
-          tx = trect.origin.x;
-          ty = trect.origin.y;
-          tx2 = tx + trect.size.width;
-          ty2 = ty + trect.size.height;
-        }
-      else
-        {
-          int gl_min_filter = GL_NEAREST, gl_mag_filter = GL_NEAREST;
-          get_gl_scaling_filters (node, &gl_min_filter, &gl_mag_filter);
+      TextureRegion r;
 
-          texture_id = gsk_gl_driver_get_texture_for_texture (self->gl_driver,
-                                                              texture,
-                                                              gl_min_filter,
-                                                              gl_mag_filter);
-        }
+      upload_texture (self, texture, &r);
 
       ops_set_program (builder, &self->blit_program);
-      ops_set_texture (builder, texture_id);
+      ops_set_texture (builder, r.texture_id);
 
       ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
-        { { min_x, min_y }, { tx,  ty  }, },
-        { { min_x, max_y }, { tx,  ty2 }, },
-        { { max_x, min_y }, { tx2, ty  }, },
+        { { min_x, min_y }, { r.x,  r.y  }, },
+        { { min_x, max_y }, { r.x,  r.y2 }, },
+        { { max_x, min_y }, { r.x2, r.y  }, },
 
-        { { max_x, max_y }, { tx2, ty2 }, },
-        { { min_x, max_y }, { tx,  ty2 }, },
-        { { max_x, min_y }, { tx2, ty  }, },
+        { { max_x, max_y }, { r.x2, r.y2 }, },
+        { { min_x, max_y }, { r.x,  r.y2 }, },
+        { { max_x, min_y }, { r.x2, r.y  }, },
       });
     }
 }
@@ -935,7 +958,7 @@ render_transform_node (GskGLRenderer   *self,
             const float min_y = child->bounds.origin.y;
             const float max_x = min_x + child->bounds.size.width;
             const float max_y = min_y + child->bounds.size.height;
-            int texture_id;
+            TextureRegion region;
             gboolean is_offscreen;
             /* For non-trivial transforms, we draw everything on a texture and then
              * draw the texture transformed. */
@@ -946,24 +969,24 @@ render_transform_node (GskGLRenderer   *self,
             add_offscreen_ops (self, builder,
                                &child->bounds,
                                child,
-                               &texture_id, &is_offscreen,
+                               &region, &is_offscreen,
                                RESET_CLIP | RESET_OPACITY);
 
             gsk_transform_to_matrix (node_transform, &mat);
             ops_push_modelview (builder, node_transform);
-            ops_set_texture (builder, texture_id);
+            ops_set_texture (builder, region.texture_id);
             ops_set_program (builder, &self->blit_program);
 
             if (is_offscreen)
               {
                 const GskQuadVertex offscreen_vertex_data[GL_N_VERTICES] = {
-                  { { min_x, min_y }, { 0, 1 }, },
-                  { { min_x, max_y }, { 0, 0 }, },
-                  { { max_x, min_y }, { 1, 1 }, },
+                  { { min_x, min_y }, { region.x,  region.y2 }, },
+                  { { min_x, max_y }, { region.x,  region.y  }, },
+                  { { max_x, min_y }, { region.x2, region.y2 }, },
 
-                  { { max_x, max_y }, { 1, 0 }, },
-                  { { min_x, max_y }, { 0, 0 }, },
-                  { { max_x, min_y }, { 1, 1 }, },
+                  { { max_x, max_y }, { region.x2, region.y  }, },
+                  { { min_x, max_y }, { region.x,  region.y  }, },
+                  { { max_x, min_y }, { region.x2, region.y2 }, },
                 };
 
                 ops_draw (builder, offscreen_vertex_data);
@@ -971,13 +994,13 @@ render_transform_node (GskGLRenderer   *self,
             else
               {
                 const GskQuadVertex onscreen_vertex_data[GL_N_VERTICES] = {
-                  { { min_x, min_y }, { 0, 0 }, },
-                  { { min_x, max_y }, { 0, 1 }, },
-                  { { max_x, min_y }, { 1, 0 }, },
+                  { { min_x, min_y }, { region.x,  region.y  }, },
+                  { { min_x, max_y }, { region.x,  region.y2 }, },
+                  { { max_x, min_y }, { region.x2, region.y  }, },
 
-                  { { max_x, max_y }, { 1, 1 }, },
-                  { { min_x, max_y }, { 0, 1 }, },
-                  { { max_x, min_y }, { 1, 0 }, },
+                  { { max_x, max_y }, { region.x2, region.y2 }, },
+                  { { min_x, max_y }, { region.x,  region.y2 }, },
+                  { { max_x, min_y }, { region.x2, region.y  }, },
                 };
 
                 ops_draw (builder, onscreen_vertex_data);
@@ -1237,7 +1260,7 @@ render_rounded_clip_node (GskGLRenderer       *self,
       const float max_y = min_y + node->bounds.size.height;
       graphene_matrix_t scale_matrix;
       gboolean is_offscreen;
-      int texture_id;
+      TextureRegion region;
       /* NOTE: We are *not* transforming the clip by the current modelview here.
        *       We instead draw the untransformed clip to a texture and then transform
        *       that texture.
@@ -1258,18 +1281,18 @@ render_rounded_clip_node (GskGLRenderer       *self,
       ops_push_clip (builder, &child_clip);
       add_offscreen_ops (self, builder, &node->bounds,
                          child,
-                         &texture_id, &is_offscreen,
+                         &region, &is_offscreen,
                          FORCE_OFFSCREEN | RESET_OPACITY);
       ops_pop_clip (builder);
 
       ops_set_program (builder, &self->blit_program);
-      ops_set_texture (builder, texture_id);
+      ops_set_texture (builder, region.texture_id);
 
       ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
         { { min_x, min_y }, { 0, 1 }, },
         { { min_x, max_y }, { 0, 0 }, },
         { { max_x, min_y }, { 1, 1 }, },
-
+ 
         { { max_x, max_y }, { 1, 0 }, },
         { { min_x, max_y }, { 0, 0 }, },
         { { max_x, min_y }, { 1, 1 }, },
@@ -1289,13 +1312,13 @@ render_color_matrix_node (GskGLRenderer       *self,
   const float max_x = min_x + node->bounds.size.width;
   const float max_y = min_y + node->bounds.size.height;
   GskRenderNode *child = gsk_color_matrix_node_get_child (node);
-  int texture_id;
+  TextureRegion region;
   gboolean is_offscreen;
 
   add_offscreen_ops (self, builder,
                      &node->bounds,
                      child,
-                     &texture_id, &is_offscreen,
+                     &region, &is_offscreen,
                      RESET_CLIP | RESET_OPACITY);
 
   ops_set_program (builder, &self->color_matrix_program);
@@ -1303,25 +1326,35 @@ render_color_matrix_node (GskGLRenderer       *self,
                         gsk_color_matrix_node_peek_color_matrix (node),
                         gsk_color_matrix_node_peek_color_offset (node));
 
-  ops_set_texture (builder, texture_id);
+  ops_set_texture (builder, region.texture_id);
 
   if (is_offscreen)
     {
       GskQuadVertex offscreen_vertex_data[GL_N_VERTICES] = {
-        { { min_x, min_y }, { 0, 1 }, },
-        { { min_x, max_y }, { 0, 0 }, },
-        { { max_x, min_y }, { 1, 1 }, },
+        { { min_x, min_y }, { region.x,  region.y2 }, },
+        { { min_x, max_y }, { region.x,  region.y  }, },
+        { { max_x, min_y }, { region.x2, region.y2 }, },
 
-        { { max_x, max_y }, { 1, 0 }, },
-        { { min_x, max_y }, { 0, 0 }, },
-        { { max_x, min_y }, { 1, 1 }, },
+        { { max_x, max_y }, { region.x2, region.y  }, },
+        { { min_x, max_y }, { region.x,  region.y  }, },
+        { { max_x, min_y }, { region.x2, region.y2 }, },
       };
 
       ops_draw (builder, offscreen_vertex_data);
     }
   else
     {
-      ops_draw (builder, vertex_data);
+      const GskQuadVertex onscreen_vertex_data[GL_N_VERTICES] = {
+        { { min_x, min_y }, { region.x,  region.y }, },
+        { { min_x, max_y }, { region.x,  region.y2 }, },
+        { { max_x, min_y }, { region.x2, region.y }, },
+
+        { { max_x, max_y }, { region.x2, region.y2 }, },
+        { { min_x, max_y }, { region.x,  region.y2 }, },
+        { { max_x, min_y }, { region.x2, region.y }, },
+      };
+
+      ops_draw (builder, onscreen_vertex_data);
     }
 }
 
@@ -1336,7 +1369,7 @@ render_blur_node (GskGLRenderer       *self,
   const float max_x = min_x + node->bounds.size.width;
   const float max_y = min_y + node->bounds.size.height;
   const float blur_radius = gsk_blur_node_get_radius (node);
-  int texture_id;
+  TextureRegion region;
   gboolean is_offscreen;
   RenderOp op;
 
@@ -1354,7 +1387,7 @@ render_blur_node (GskGLRenderer       *self,
   add_offscreen_ops (self, builder,
                      &node->bounds,
                      gsk_blur_node_get_child (node),
-                     &texture_id, &is_offscreen,
+                     &region, &is_offscreen,
                      RESET_CLIP | FORCE_OFFSCREEN | RESET_OPACITY);
 
   ops_set_program (builder, &self->blur_program);
@@ -1363,7 +1396,7 @@ render_blur_node (GskGLRenderer       *self,
   op.blur.radius = gsk_blur_node_get_radius (node);
   ops_add (builder, &op);
 
-  ops_set_texture (builder, texture_id);
+  ops_set_texture (builder, region.texture_id);
 
   if (is_offscreen)
     {
@@ -1371,7 +1404,7 @@ render_blur_node (GskGLRenderer       *self,
         { { min_x, min_y }, { 0, 1 }, },
         { { min_x, max_y }, { 0, 0 }, },
         { { max_x, min_y }, { 1, 1 }, },
-
+ 
         { { max_x, max_y }, { 1, 0 }, },
         { { min_x, max_y }, { 0, 0 }, },
         { { max_x, min_y }, { 1, 1 }, },
@@ -1856,7 +1889,7 @@ render_shadow_node (GskGLRenderer       *self,
       const GskShadow *shadow = gsk_shadow_node_peek_shadow (node, i);
       const float dx = shadow->dx;
       const float dy = shadow->dy;
-      int texture_id;
+      TextureRegion region;
       gboolean is_offscreen;
 
       g_assert (shadow->radius <= 0);
@@ -1880,22 +1913,22 @@ render_shadow_node (GskGLRenderer       *self,
       /* Draw the child offscreen, without the offset. */
       add_offscreen_ops (self, builder,
                          &shadow_child->bounds,
-                         shadow_child, &texture_id, &is_offscreen,
+                         shadow_child, &region, &is_offscreen,
                          RESET_CLIP | RESET_OPACITY);
 
       ops_set_program (builder, &self->coloring_program);
       ops_set_color (builder, &shadow->color);
-      ops_set_texture (builder, texture_id);
+      ops_set_texture (builder, region.texture_id);
       if (is_offscreen)
         {
           const GskQuadVertex offscreen_vertex_data[GL_N_VERTICES] = {
-            { { dx + min_x, dy + min_y }, { 0, 1 }, },
-            { { dx + min_x, dy + max_y }, { 0, 0 }, },
-            { { dx + max_x, dy + min_y }, { 1, 1 }, },
+            { { dx + min_x, dy + min_y }, { region.x,  region.y2 }, },
+            { { dx + min_x, dy + max_y }, { region.x,  region.y }, },
+            { { dx + max_x, dy + min_y }, { region.x2, region.y2 }, },
 
-            { { dx + max_x, dy + max_y }, { 1, 0 }, },
-            { { dx + min_x, dy + max_y }, { 0, 0 }, },
-            { { dx + max_x, dy + min_y }, { 1, 1 }, },
+            { { dx + max_x, dy + max_y }, { region.x2, region.y }, },
+            { { dx + min_x, dy + max_y }, { region.x,  region.y }, },
+            { { dx + max_x, dy + min_y }, { region.x2, region.y2 }, },
           };
 
           ops_draw (builder, offscreen_vertex_data);
@@ -1903,13 +1936,13 @@ render_shadow_node (GskGLRenderer       *self,
       else
         {
           const GskQuadVertex onscreen_vertex_data[GL_N_VERTICES] = {
-            { { dx + min_x, dy + min_y }, { 0, 0 }, },
-            { { dx + min_x, dy + max_y }, { 0, 1 }, },
-            { { dx + max_x, dy + min_y }, { 1, 0 }, },
+            { { dx + min_x, dy + min_y }, { region.x,  region.y }, },
+            { { dx + min_x, dy + max_y }, { region.x,  region.y2 }, },
+            { { dx + max_x, dy + min_y }, { region.x2, region.y }, },
 
-            { { dx + max_x, dy + max_y }, { 1, 1 }, },
-            { { dx + min_x, dy + max_y }, { 0, 1 }, },
-            { { dx + max_x, dy + min_y }, { 1, 0 }, },
+            { { dx + max_x, dy + max_y }, { region.x2, region.y2 }, },
+            { { dx + min_x, dy + max_y }, { region.x,  region.y2 }, },
+            { { dx + max_x, dy + min_y }, { region.x2, region.y }, },
           };
 
           ops_draw (builder, onscreen_vertex_data);
@@ -1932,8 +1965,8 @@ render_cross_fade_node (GskGLRenderer       *self,
   GskRenderNode *start_node = gsk_cross_fade_node_get_start_child (node);
   GskRenderNode *end_node = gsk_cross_fade_node_get_end_child (node);
   float progress = gsk_cross_fade_node_get_progress (node);
-  int start_texture_id;
-  int end_texture_id;
+  TextureRegion start_region;
+  TextureRegion end_region;
   gboolean is_offscreen1, is_offscreen2;
   RenderOp op;
   const GskQuadVertex vertex_data[GL_N_VERTICES] = {
@@ -1952,21 +1985,21 @@ render_cross_fade_node (GskGLRenderer       *self,
   add_offscreen_ops (self, builder,
                      &node->bounds,
                      start_node,
-                     &start_texture_id, &is_offscreen1,
+                     &start_region, &is_offscreen1,
                      FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY);
 
   add_offscreen_ops (self, builder,
                      &node->bounds,
                      end_node,
-                     &end_texture_id, &is_offscreen2,
+                     &end_region, &is_offscreen2,
                      FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY);
 
   ops_set_program (builder, &self->cross_fade_program);
   op.op = OP_CHANGE_CROSS_FADE;
   op.cross_fade.progress = progress;
-  op.cross_fade.source2 = end_texture_id;
+  op.cross_fade.source2 = end_region.texture_id;
   ops_add (builder, &op);
-  ops_set_texture (builder, start_texture_id);
+  ops_set_texture (builder, start_region.texture_id);
 
   ops_draw (builder, vertex_data);
 }
@@ -1982,8 +2015,8 @@ render_blend_node (GskGLRenderer   *self,
   const float min_y = builder->dy + node->bounds.origin.y;
   const float max_x = min_x + node->bounds.size.width;
   const float max_y = min_y + node->bounds.size.height;
-  int top_texture_id;
-  int bottom_texture_id;
+  TextureRegion top_region;
+  TextureRegion bottom_region;
   gboolean is_offscreen1, is_offscreen2;
   RenderOp op;
   const GskQuadVertex vertex_data[GL_N_VERTICES] = {
@@ -2001,19 +2034,19 @@ render_blend_node (GskGLRenderer   *self,
   add_offscreen_ops (self, builder,
                      &node->bounds,
                      bottom_child,
-                     &bottom_texture_id, &is_offscreen1,
+                     &bottom_region, &is_offscreen1,
                      FORCE_OFFSCREEN | RESET_CLIP);
 
   add_offscreen_ops (self, builder,
                      &node->bounds,
                      top_child,
-                     &top_texture_id, &is_offscreen2,
+                     &top_region, &is_offscreen2,
                      FORCE_OFFSCREEN | RESET_CLIP);
 
   ops_set_program (builder, &self->blend_program);
-  ops_set_texture (builder, bottom_texture_id);
+  ops_set_texture (builder, bottom_region.texture_id);
   op.op = OP_CHANGE_BLEND;
-  op.blend.source2 = top_texture_id;
+  op.blend.source2 = top_region.texture_id;
   op.blend.mode = gsk_blend_node_get_blend_mode (node);
   ops_add (builder, &op);
   ops_draw (builder, vertex_data);
@@ -2814,7 +2847,7 @@ add_offscreen_ops (GskGLRenderer         *self,
                    RenderOpBuilder       *builder,
                    const graphene_rect_t *bounds,
                    GskRenderNode         *child_node,
-                   int                   *texture_id_out,
+                   TextureRegion         *texture_region_out,
                    gboolean              *is_offscreen,
                    guint                  flags)
 {
@@ -2839,14 +2872,8 @@ add_offscreen_ops (GskGLRenderer         *self,
       (flags & FORCE_OFFSCREEN) == 0)
     {
       GdkTexture *texture = gsk_texture_node_get_texture (child_node);
-      int gl_min_filter = GL_NEAREST, gl_mag_filter = GL_NEAREST;
-
-      get_gl_scaling_filters (child_node, &gl_min_filter, &gl_mag_filter);
 
-      *texture_id_out = gsk_gl_driver_get_texture_for_texture (self->gl_driver,
-                                                               texture,
-                                                               gl_min_filter,
-                                                               gl_mag_filter);
+      upload_texture (self, texture, texture_region_out);
       *is_offscreen = FALSE;
       return;
     }
@@ -2857,7 +2884,7 @@ add_offscreen_ops (GskGLRenderer         *self,
 
     if (cached_id != 0)
       {
-        *texture_id_out = cached_id;
+        init_full_texture_region (texture_region_out, cached_id);
         /* We didn't render it offscreen, but hand out an offscreen texture id */
         *is_offscreen = TRUE;
         return;
@@ -2929,7 +2956,7 @@ add_offscreen_ops (GskGLRenderer         *self,
   ops_set_render_target (builder, prev_render_target);
 
   *is_offscreen = TRUE;
-  *texture_id_out = texture_id;
+  init_full_texture_region (texture_region_out, texture_id);
 
   gsk_gl_driver_set_texture_for_pointer (self->gl_driver, child_node, texture_id);
 }


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