[gtk/ngl-tweaks: 1/3] ngl: Special-case CSS backgrounds




commit 70bf1ed0e48829fb7a7bb9d571c2a2e4c275794b
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Mar 9 18:54:29 2021 -0500

    ngl: Special-case CSS backgrounds
    
    Recognize the rounded-clip-with-color-inside situation
    and do manual nine-slicing for it to minimize the number
    of pixels send through clipping shaders.

 gsk/ngl/gsknglrenderjob.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)
---
diff --git a/gsk/ngl/gsknglrenderjob.c b/gsk/ngl/gsknglrenderjob.c
index 820c5d5321..6263676584 100644
--- a/gsk/ngl/gsknglrenderjob.c
+++ b/gsk/ngl/gsknglrenderjob.c
@@ -1635,6 +1635,84 @@ gsk_ngl_render_job_visit_clip_node (GskNglRenderJob     *job,
   gsk_ngl_render_job_visit_clipped_child (job, child, clip);
 }
 
+static inline void
+gsk_ngl_render_job_visit_rounded_color_node (GskNglRenderJob     *job,
+                                             const GskRenderNode *node)
+{
+  const GskRenderNode *child = gsk_rounded_clip_node_get_child (node);
+  const GskRoundedRect *clip = gsk_rounded_clip_node_get_clip (node);
+  const graphene_rect_t *outer;
+  graphene_rect_t inner;
+  graphene_rect_t rect;
+
+  outer = &node->bounds;
+  rounded_rect_get_inner (clip, &inner);
+  graphene_rect_intersection (outer, &inner, &inner);
+
+  gsk_ngl_render_job_begin_draw (job, job->driver->color);
+  gsk_ngl_program_set_uniform_color (job->current_program,
+                                     UNIFORM_COLOR_COLOR, 0,
+                                     gsk_color_node_get_color (child));
+
+  /* top left */
+  rect.origin.x = outer->origin.x;
+  rect.origin.y = outer->origin.y;
+  rect.size.width = inner.origin.x - rect.origin.x;
+  rect.size.height = inner.origin.y - rect.origin.y;
+  gsk_ngl_render_job_draw_rect (job, &rect);
+
+  /* top right */
+  rect.origin.x = inner.origin.x + inner.size.width;
+  rect.origin.y = outer->origin.y;
+  rect.size.width = outer->origin.x + outer->size.width - rect.origin.x;
+  rect.size.height = inner.origin.y - rect.origin.y;
+  gsk_ngl_render_job_draw_rect (job, &rect);
+
+  /* bottom right */
+  rect.origin.x = inner.origin.x + inner.size.width;
+  rect.origin.y = inner.origin.y + inner.size.height;
+  rect.size.width = outer->origin.x + outer->size.width - rect.origin.x;
+  rect.size.height = outer->origin.y + outer->size.height - rect.origin.y;
+  gsk_ngl_render_job_draw_rect (job, &rect);
+
+  /* bottom left */
+  rect.origin.x = outer->origin.x;
+  rect.origin.y = inner.origin.y + inner.size.height;
+  rect.size.width = inner.origin.x - rect.origin.x;
+  rect.size.height = outer->origin.y + outer->size.height - rect.origin.y;
+  gsk_ngl_render_job_draw_rect (job, &rect);
+
+  gsk_ngl_render_job_end_draw (job);
+
+  gsk_ngl_render_job_begin_draw (job, job->driver->color_no_clip);
+  gsk_ngl_program_set_uniform_color (job->current_program,
+                                     UNIFORM_COLOR_COLOR, 0,
+                                     gsk_color_node_get_color (child));
+
+  /* left side */
+  rect.origin.x = outer->origin.x;
+  rect.origin.y = inner.origin.y;
+  rect.size.width = inner.origin.x - rect.origin.x;
+  rect.size.height = inner.size.height;
+  gsk_ngl_render_job_draw_rect (job, &rect);
+
+  /* center */
+  rect.origin.x = inner.origin.x;
+  rect.origin.y = outer->origin.y;
+  rect.size.width = inner.size.width;
+  rect.size.height = outer->size.height;
+  gsk_ngl_render_job_draw_rect (job, &rect);
+
+  /* right side */
+  rect.origin.x = inner.origin.x + inner.size.width;
+  rect.origin.y = inner.origin.y;
+  rect.size.width = outer->origin.x + outer->size.width - rect.origin.x;
+  rect.size.height = inner.size.height;
+  gsk_ngl_render_job_draw_rect (job, &rect);
+
+  gsk_ngl_render_job_end_draw (job);
+}
+
 static inline void
 gsk_ngl_render_job_visit_rounded_clip_node (GskNglRenderJob     *job,
                                             const GskRenderNode *node)
@@ -1657,6 +1735,16 @@ gsk_ngl_render_job_visit_rounded_clip_node (GskNglRenderJob     *job,
       transformed_clip.corner[i].height = clip->corner[i].height * scale_y;
     }
 
+  if (gsk_render_node_get_node_type (child) == GSK_COLOR_NODE &&
+      job->current_clip->is_fully_contained)
+    {
+      /* special-case CSS backgrounds */
+      gsk_ngl_render_job_push_clip (job, &transformed_clip);
+      gsk_ngl_render_job_visit_rounded_color_node (job, node);
+      gsk_ngl_render_job_pop_clip (job);
+      return;
+    }
+
   if (job->current_clip->is_rectilinear)
     {
       GskRoundedRect intersected_clip;


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