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.
This commit is contained in:
Timm Bäder 2020-01-16 08:02:48 +01:00
parent f5182f1c35
commit dc8dedce07
5 changed files with 26 additions and 17 deletions

View 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 */

View File

@ -73,6 +73,7 @@ struct _Program
int outline_rect_location;
} inset_shadow;
struct {
int color_location;
int outline_rect_location;
} outset_shadow;
struct {

View 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;

View 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);

View 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);
}