[gtk/wip/baedert/css-values: 13/17] gl renderer: Draw outset shadows white



commit 583c1762a44bf6ec92db229b491dc5f3c6cfb7fb
Author: Timm Bäder <mail baedert org>
Date:   Thu Jan 16 08:02:48 2020 +0100

    gl renderer: Draw outset shadows white
    
    and only apply the actual shadow color when we draw them from the
    texture. This way we can reuse the cached shadows during color
    transitions.

 gsk/gl/gskglrenderer.c                |  7 ++++---
 gsk/gl/gskglrenderopsprivate.h        |  1 +
 gsk/gl/gskglshadowcache.c             | 12 +++---------
 gsk/gl/gskglshadowcacheprivate.h      |  2 --
 gsk/resources/glsl/outset_shadow.glsl | 21 ++++++++++++++++++---
 5 files changed, 26 insertions(+), 17 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 7928da3096..1753ad0468 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -1665,6 +1665,7 @@ render_unblurred_outset_shadow_node (GskGLRenderer   *self,
   load_vertex_data (ops_draw (builder, NULL), node, builder);
 }
 
+static GdkRGBA COLOR_WHITE = { 1, 1, 1, 1 };
 static inline void
 render_outset_shadow_node (GskGLRenderer   *self,
                            GskRenderNode   *node,
@@ -1717,7 +1718,6 @@ render_outset_shadow_node (GskGLRenderer   *self,
   cached_tid = gsk_gl_shadow_cache_get_texture_id (&self->shadow_cache,
                                                    self->gl_driver,
                                                    &scaled_outline,
-                                                   color,
                                                    blur_radius);
 
   if (cached_tid == 0)
@@ -1749,7 +1749,7 @@ render_outset_shadow_node (GskGLRenderer   *self,
       /* Draw outline */
       ops_set_program (builder, &self->color_program);
       ops_push_clip (builder, &scaled_outline);
-      ops_set_color (builder, color);
+      ops_set_color (builder, &COLOR_WHITE);
       ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
         { { 0,                            }, { 0, 1 }, },
         { { 0,             texture_height }, { 0, 0 }, },
@@ -1776,7 +1776,6 @@ render_outset_shadow_node (GskGLRenderer   *self,
       gsk_gl_driver_mark_texture_permanent (self->gl_driver, blurred_texture_id);
       gsk_gl_shadow_cache_commit (&self->shadow_cache,
                                   &scaled_outline,
-                                  color,
                                   blur_radius,
                                   blurred_texture_id);
     }
@@ -1786,6 +1785,7 @@ render_outset_shadow_node (GskGLRenderer   *self,
     }
 
   ops_set_program (builder, &self->outset_shadow_program);
+  ops_set_color (builder, color);
   ops_set_texture (builder, blurred_texture_id);
 
   shadow = ops_begin (builder, OP_CHANGE_OUTSET_SHADOW);
@@ -2660,6 +2660,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
   INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, outline_rect);
 
   /* outset shadow */
+  INIT_PROGRAM_UNIFORM_LOCATION (outset_shadow, color);
   INIT_PROGRAM_UNIFORM_LOCATION (outset_shadow, outline_rect);
 
   /* unblurred outset shadow */
diff --git a/gsk/gl/gskglrenderopsprivate.h b/gsk/gl/gskglrenderopsprivate.h
index 49d0cec2de..dd3f609ab8 100644
--- a/gsk/gl/gskglrenderopsprivate.h
+++ b/gsk/gl/gskglrenderopsprivate.h
@@ -73,6 +73,7 @@ struct _Program
       int outline_rect_location;
     } inset_shadow;
     struct {
+      int color_location;
       int outline_rect_location;
     } outset_shadow;
     struct {
diff --git a/gsk/gl/gskglshadowcache.c b/gsk/gl/gskglshadowcache.c
index 57ef600403..a0eeef904d 100644
--- a/gsk/gl/gskglshadowcache.c
+++ b/gsk/gl/gskglshadowcache.c
@@ -7,14 +7,12 @@ typedef struct
 {
   GskRoundedRect outline;
   float blur_radius;
-  GdkRGBA color;
 } CacheKey;
 
 typedef struct
 {
   GskRoundedRect outline;
   float blur_radius;
-  GdkRGBA color;
 
   int texture_id;
   int unused_frames;
@@ -32,8 +30,7 @@ key_equal (const void *x,
          graphene_size_equal (&a->outline.corner[1], &b->outline.corner[1]) &&
          graphene_size_equal (&a->outline.corner[2], &b->outline.corner[2]) &&
          graphene_size_equal (&a->outline.corner[3], &b->outline.corner[3]) &&
-         graphene_rect_equal (&a->outline.bounds, &b->outline.bounds) &&
-         gdk_rgba_equal (&a->color, &b->color);
+         graphene_rect_equal (&a->outline.bounds, &b->outline.bounds);
 }
 
 void
@@ -91,7 +88,6 @@ int
 gsk_gl_shadow_cache_get_texture_id (GskGLShadowCache     *self,
                                     GskGLDriver          *gl_driver,
                                     const GskRoundedRect *shadow_rect,
-                                    const GdkRGBA        *color,
                                     float                 blur_radius)
 {
   CacheItem *item= NULL;
@@ -105,8 +101,8 @@ gsk_gl_shadow_cache_get_texture_id (GskGLShadowCache     *self,
     {
       CacheItem *k = &g_array_index (self->textures, CacheItem, i);
 
-      if (key_equal (&(CacheKey){*shadow_rect, blur_radius, *color},
-                     &(CacheKey){k->outline, k->blur_radius, k->color}))
+      if (key_equal (&(CacheKey){*shadow_rect, blur_radius},
+                     &(CacheKey){k->outline, k->blur_radius}))
         {
           item = k;
           break;
@@ -126,7 +122,6 @@ gsk_gl_shadow_cache_get_texture_id (GskGLShadowCache     *self,
 void
 gsk_gl_shadow_cache_commit (GskGLShadowCache     *self,
                             const GskRoundedRect *shadow_rect,
-                            const GdkRGBA        *color,
                             float                 blur_radius,
                             int                   texture_id)
 {
@@ -140,7 +135,6 @@ gsk_gl_shadow_cache_commit (GskGLShadowCache     *self,
   item = &g_array_index (self->textures, CacheItem, self->textures->len - 1);
 
   item->outline = *shadow_rect;
-  item->color = *color;
   item->blur_radius = blur_radius;
   item->unused_frames = 0;
   item->texture_id = texture_id;
diff --git a/gsk/gl/gskglshadowcacheprivate.h b/gsk/gl/gskglshadowcacheprivate.h
index d4b03cc2a9..6623f16235 100644
--- a/gsk/gl/gskglshadowcacheprivate.h
+++ b/gsk/gl/gskglshadowcacheprivate.h
@@ -21,11 +21,9 @@ void gsk_gl_shadow_cache_begin_frame    (GskGLShadowCache     *self,
 int  gsk_gl_shadow_cache_get_texture_id (GskGLShadowCache     *self,
                                          GskGLDriver          *gl_driver,
                                          const GskRoundedRect *shadow_rect,
-                                         const GdkRGBA        *color,
                                          float                 blur_radius);
 void gsk_gl_shadow_cache_commit         (GskGLShadowCache     *self,
                                          const GskRoundedRect *shadow_rect,
-                                         const GdkRGBA        *color,
                                          float                 blur_radius,
                                          int                   texture_id);
 
diff --git a/gsk/resources/glsl/outset_shadow.glsl b/gsk/resources/glsl/outset_shadow.glsl
index d052049c2d..f0c5b3fede 100644
--- a/gsk/resources/glsl/outset_shadow.glsl
+++ b/gsk/resources/glsl/outset_shadow.glsl
@@ -1,13 +1,24 @@
 // VERTEX_SHADER:
+uniform vec4 u_color;
+
+_OUT_ vec4 final_color;
+
 void main() {
   gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
 
   vUv = vec2(aUv.x, aUv.y);
+
+  final_color = u_color;
+  // pre-multiply
+  final_color.rgb *= final_color.a;
+  final_color *= u_alpha;
 }
 
 // FRAGMENT_SHADER:
 uniform vec4[3] u_outline_rect;
 
+_IN_ vec4 final_color;
+
 void main() {
   vec4 f = gl_FragCoord;
 
@@ -15,7 +26,11 @@ void main() {
   f.y = (u_viewport.y + u_viewport.w) - f.y;
 
   RoundedRect outline = create_rect(u_outline_rect);
-  vec4 color = Texture(u_source, vUv);
-  color = color * (1.0 -  clamp(rounded_rect_coverage(outline, f.xy), 0.0, 1.0));
-  setOutputColor(color * u_alpha);
+
+  float alpha = Texture(u_source, vUv).a;
+  alpha *= (1.0 -  clamp(rounded_rect_coverage(outline, f.xy), 0.0, 1.0));
+
+  vec4 color = final_color * alpha;
+
+  setOutputColor(color);
 }


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