gl renderer: Draw outset shadows white
authorTimm Bäder <mail@baedert.org>
Thu, 16 Jan 2020 07:02:48 +0000 (08:02 +0100)
committerTimm Bäder <mail@baedert.org>
Sat, 18 Jan 2020 07:49:52 +0000 (08:49 +0100)
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
gsk/gl/gskglrenderopsprivate.h
gsk/gl/gskglshadowcache.c
gsk/gl/gskglshadowcacheprivate.h
gsk/resources/glsl/outset_shadow.glsl

index 7928da30962e67dca2648ff19fbfc1ea40966a46..1753ad04687e869ae8e2aeb51b476be36209e506 100644 (file)
@@ -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 */
index 49d0cec2dea22ff2498bf4e3e745883e38c2e522..dd3f609ab8805193e66135043666c8e5439059b5 100644 (file)
@@ -73,6 +73,7 @@ struct _Program
       int outline_rect_location;
     } inset_shadow;
     struct {
+      int color_location;
       int outline_rect_location;
     } outset_shadow;
     struct {
index 57ef600403fb66f49fffff2b08fe9f057773ad60..a0eeef904d167050d35d0a6fc3dd2a7bc0cd8565 100644 (file)
@@ -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;
index d4b03cc2a9e1dd281f25db50eb8a102b7972e908..6623f1623595ec3c7c3be6379177b912b43d5259 100644 (file)
@@ -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);
 
index d052049c2dc59376426c8515f1543f37c716ee86..f0c5b3fede227268e8bc7c684d09c0f619397f88 100644 (file)
@@ -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);
 }