mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 02:40:11 +00:00
gpu: Make border shader usable for inset/outset
... and use it for those when unblurred.
This commit is contained in:
parent
8043d4d6e0
commit
8271687ef6
@ -111,6 +111,7 @@ gsk_gpu_border_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
const GskRoundedRect *outline,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_point_t *inside_offset,
|
||||
const float widths[4],
|
||||
const GdkRGBA colors[4])
|
||||
{
|
||||
@ -129,5 +130,7 @@ gsk_gpu_border_op (GskGpuFrame *frame,
|
||||
instance->border_widths[i] = widths[i];
|
||||
gsk_gpu_rgba_to_float (&colors[i], &instance->border_colors[4 * i]);
|
||||
}
|
||||
instance->offset[0] = inside_offset->x;
|
||||
instance->offset[1] = inside_offset->y;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ void gsk_gpu_border_op (GskGpuF
|
||||
GskGpuShaderClip clip,
|
||||
const GskRoundedRect *outline,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_point_t *inside_offset,
|
||||
const float widths[4],
|
||||
const GdkRGBA colors[4]);
|
||||
|
||||
|
@ -1070,6 +1070,7 @@ gsk_gpu_node_processor_add_border_node (GskGpuNodeProcessor *self,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
gsk_border_node_get_outline (node),
|
||||
&self->offset,
|
||||
graphene_point_zero (),
|
||||
gsk_border_node_get_widths (node),
|
||||
gsk_border_node_get_colors (node));
|
||||
}
|
||||
@ -1137,6 +1138,68 @@ gsk_gpu_node_processor_create_texture_pattern (GskGpuPatternWriter *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_node_processor_add_inset_shadow_node (GskGpuNodeProcessor *self,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
const GdkRGBA *color;
|
||||
float spread, blur_radius;
|
||||
|
||||
spread = gsk_inset_shadow_node_get_spread (node);
|
||||
color = gsk_inset_shadow_node_get_color (node);
|
||||
blur_radius = gsk_inset_shadow_node_get_blur_radius (node);
|
||||
|
||||
if (blur_radius == 0)
|
||||
{
|
||||
gsk_gpu_border_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
gsk_inset_shadow_node_get_outline (node),
|
||||
&self->offset,
|
||||
&GRAPHENE_POINT_INIT (gsk_inset_shadow_node_get_dx (node),
|
||||
gsk_inset_shadow_node_get_dy (node)),
|
||||
(float[4]) { spread, spread, spread, spread },
|
||||
(GdkRGBA[4]) { *color, *color, *color, *color });
|
||||
return;
|
||||
}
|
||||
|
||||
GSK_DEBUG (FALLBACK, "No blurring for inset shadows");
|
||||
gsk_gpu_node_processor_add_fallback_node (self, node);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_node_processor_add_outset_shadow_node (GskGpuNodeProcessor *self,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
GskRoundedRect outline;
|
||||
const GdkRGBA *color;
|
||||
float spread, blur_radius, dx, dy;
|
||||
|
||||
spread = gsk_outset_shadow_node_get_spread (node);
|
||||
color = gsk_outset_shadow_node_get_color (node);
|
||||
blur_radius = gsk_outset_shadow_node_get_blur_radius (node);
|
||||
dx = gsk_outset_shadow_node_get_dx (node);
|
||||
dy = gsk_outset_shadow_node_get_dy (node);
|
||||
|
||||
gsk_rounded_rect_init_copy (&outline, gsk_outset_shadow_node_get_outline (node));
|
||||
gsk_rounded_rect_shrink (&outline, -spread, -spread, -spread, -spread);
|
||||
graphene_rect_offset (&outline.bounds, dx, dy);
|
||||
|
||||
if (blur_radius == 0)
|
||||
{
|
||||
gsk_gpu_border_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
&outline,
|
||||
&self->offset,
|
||||
&GRAPHENE_POINT_INIT (-dx, -dy),
|
||||
(float[4]) { spread, spread, spread, spread },
|
||||
(GdkRGBA[4]) { *color, *color, *color, *color });
|
||||
return;
|
||||
}
|
||||
|
||||
GSK_DEBUG (FALLBACK, "No blurring for outset shadows");
|
||||
gsk_gpu_node_processor_add_fallback_node (self, node);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_node_processor_create_linear_gradient_pattern (GskGpuPatternWriter *self,
|
||||
GskRenderNode *node)
|
||||
@ -1723,12 +1786,12 @@ static const struct
|
||||
},
|
||||
[GSK_INSET_SHADOW_NODE] = {
|
||||
0,
|
||||
NULL,
|
||||
gsk_gpu_node_processor_add_inset_shadow_node,
|
||||
NULL,
|
||||
},
|
||||
[GSK_OUTSET_SHADOW_NODE] = {
|
||||
0,
|
||||
NULL,
|
||||
gsk_gpu_node_processor_add_outset_shadow_node,
|
||||
NULL,
|
||||
},
|
||||
[GSK_TRANSFORM_NODE] = {
|
||||
|
@ -54,56 +54,41 @@ rect_get_position (Rect rect)
|
||||
}
|
||||
|
||||
vec2
|
||||
border_get_position (RoundedRect outline,
|
||||
vec4 border_widths)
|
||||
border_get_position (RoundedRect outside,
|
||||
RoundedRect inside)
|
||||
{
|
||||
uint slice_index = uint (GSK_VERTEX_INDEX) / 6u;
|
||||
uint vert_index = uint (GSK_VERTEX_INDEX) % 6u;
|
||||
|
||||
vec4 corner_widths = max (outline.corner_widths, border_widths.wyyw);
|
||||
vec4 corner_heights = max (outline.corner_heights, border_widths.xxzz);
|
||||
|
||||
Rect rect;
|
||||
Rect rect = rounded_rect_intersection_slice (outside, inside, slice_index);
|
||||
|
||||
switch (slice_index)
|
||||
{
|
||||
case SLICE_TOP_LEFT:
|
||||
rect = Rect (outline.bounds.xyxy + vec4 (0.0, 0.0, corner_widths[TOP_LEFT], corner_heights[TOP_LEFT]));
|
||||
rect = rect_round_larger (rect);
|
||||
rect.bounds = rect.bounds.xwzy;
|
||||
break;
|
||||
case SLICE_TOP:
|
||||
rect = Rect (vec4 (outline.bounds.x + corner_widths[TOP_LEFT], outline.bounds.y,
|
||||
outline.bounds.z - corner_widths[TOP_RIGHT], outline.bounds.y + border_widths[TOP]));
|
||||
rect = rect_round_smaller_larger (rect);
|
||||
break;
|
||||
case SLICE_TOP_RIGHT:
|
||||
rect = Rect (outline.bounds.zyzy + vec4 (- corner_widths[TOP_RIGHT], 0.0, 0.0, corner_heights[TOP_RIGHT]));
|
||||
rect = rect_round_larger (rect);
|
||||
break;
|
||||
case SLICE_RIGHT:
|
||||
rect = Rect (vec4 (outline.bounds.z - border_widths[RIGHT], outline.bounds.y + corner_widths[TOP_RIGHT],
|
||||
outline.bounds.z, outline.bounds.w - corner_widths[BOTTOM_RIGHT]));
|
||||
rect = rect_round_larger_smaller (rect);
|
||||
break;
|
||||
case SLICE_BOTTOM_RIGHT:
|
||||
rect = Rect (outline.bounds.zwzw + vec4 (- corner_widths[BOTTOM_RIGHT], - corner_heights[BOTTOM_RIGHT], 0.0, 0.0));
|
||||
rect = rect_round_larger (rect);
|
||||
rect.bounds = rect.bounds.zyxw;
|
||||
break;
|
||||
case SLICE_BOTTOM:
|
||||
rect = Rect (vec4 (outline.bounds.x + corner_widths[BOTTOM_LEFT], outline.bounds.w - border_widths[BOTTOM],
|
||||
outline.bounds.z - corner_widths[BOTTOM_RIGHT], outline.bounds.w));
|
||||
rect = rect_round_smaller_larger (rect);
|
||||
break;
|
||||
case SLICE_BOTTOM_LEFT:
|
||||
rect = Rect (outline.bounds.xwxw + vec4 (0.0, - corner_heights[BOTTOM_LEFT], corner_widths[BOTTOM_LEFT], 0.0));
|
||||
rect = rect_round_larger (rect);
|
||||
rect.bounds = rect.bounds.zwxy;
|
||||
break;
|
||||
case SLICE_LEFT:
|
||||
rect = Rect (vec4 (outline.bounds.x + border_widths[LEFT], outline.bounds.y + corner_widths[TOP_LEFT],
|
||||
outline.bounds.x, outline.bounds.w - corner_widths[BOTTOM_LEFT]));
|
||||
rect = rect_round_larger_smaller (rect);
|
||||
break;
|
||||
}
|
||||
@ -177,7 +162,7 @@ main_clip_rounded (void)
|
||||
run (color, pos);
|
||||
|
||||
RoundedRect clip = RoundedRect(vec4(push.clip_bounds.xy, push.clip_bounds.xy + push.clip_bounds.zw), push.clip_widths, push.clip_heights);
|
||||
clip = rounded_rect_scale (clip, push.scale);
|
||||
rounded_rect_scale (clip, push.scale);
|
||||
|
||||
float coverage = rounded_rect_coverage (clip, pos);
|
||||
color *= coverage;
|
||||
|
@ -12,6 +12,7 @@ PASS_FLAT(5) RoundedRect _inside;
|
||||
IN(0) mat4 in_border_colors;
|
||||
IN(4) mat3x4 in_outline;
|
||||
IN(7) vec4 in_border_widths;
|
||||
IN(8) vec2 in_offset;
|
||||
|
||||
vec4
|
||||
compute_color (void)
|
||||
@ -56,8 +57,9 @@ run (out vec2 pos)
|
||||
vec4 border_widths = in_border_widths * push.scale.yxyx;
|
||||
RoundedRect outside = rounded_rect_from_gsk (in_outline);
|
||||
RoundedRect inside = rounded_rect_shrink (outside, border_widths);
|
||||
rounded_rect_offset (inside, in_offset);
|
||||
|
||||
pos = border_get_position (outside, border_widths);
|
||||
pos = border_get_position (outside, inside);
|
||||
|
||||
_pos = pos;
|
||||
_color = compute_color ();
|
||||
|
@ -50,16 +50,6 @@ rounded_rect_distance (RoundedRect r, vec2 p)
|
||||
return max (max2.x, max2.y);
|
||||
}
|
||||
|
||||
RoundedRect
|
||||
rounded_rect_scale (RoundedRect r, vec2 scale)
|
||||
{
|
||||
r.bounds *= scale.xyxy;
|
||||
r.corner_widths *= scale.xxxx;
|
||||
r.corner_heights *= scale.yyyy;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
RoundedRect
|
||||
rounded_rect_shrink (RoundedRect r, vec4 amount)
|
||||
{
|
||||
@ -72,6 +62,120 @@ rounded_rect_shrink (RoundedRect r, vec4 amount)
|
||||
return RoundedRect (new_bounds, new_widths, new_heights);
|
||||
}
|
||||
|
||||
void
|
||||
rounded_rect_scale (inout RoundedRect r,
|
||||
vec2 scale)
|
||||
{
|
||||
r.bounds *= scale.xyxy;
|
||||
r.corner_widths *= scale.xxxx;
|
||||
r.corner_heights *= scale.yyyy;
|
||||
}
|
||||
|
||||
void
|
||||
rounded_rect_offset (inout RoundedRect r,
|
||||
vec2 offset)
|
||||
{
|
||||
r.bounds += offset.xyxy;
|
||||
}
|
||||
|
||||
Rect
|
||||
rounded_rect_intersection_slice (RoundedRect outside,
|
||||
RoundedRect inside,
|
||||
uint slice)
|
||||
{
|
||||
float left, right, top, bottom;
|
||||
|
||||
switch (slice)
|
||||
{
|
||||
case SLICE_TOP_LEFT:
|
||||
return Rect (vec4 (outside.bounds.x,
|
||||
outside.bounds.y,
|
||||
max (outside.bounds.x + outside.corner_widths[TOP_LEFT],
|
||||
inside.bounds.x + inside.corner_widths[TOP_LEFT]),
|
||||
max (outside.bounds.y + outside.corner_heights[TOP_LEFT],
|
||||
inside.bounds.y + inside.corner_heights[TOP_LEFT])));
|
||||
|
||||
case SLICE_TOP:
|
||||
left = max (outside.bounds.x + outside.corner_widths[TOP_LEFT],
|
||||
inside.bounds.x + inside.corner_widths[TOP_LEFT]);
|
||||
right = min (outside.bounds.z - outside.corner_widths[TOP_RIGHT],
|
||||
inside.bounds.z - inside.corner_widths[TOP_RIGHT]);
|
||||
return Rect (vec4 (left,
|
||||
outside.bounds.y,
|
||||
max (left, right),
|
||||
max (outside.bounds.y, inside.bounds.y)));
|
||||
|
||||
case SLICE_TOP_RIGHT:
|
||||
left = max (min (outside.bounds.z - outside.corner_widths[TOP_RIGHT],
|
||||
inside.bounds.z - inside.corner_widths[TOP_RIGHT]),
|
||||
max (outside.bounds.x + outside.corner_widths[TOP_LEFT],
|
||||
inside.bounds.x + inside.corner_widths[TOP_LEFT]));
|
||||
return Rect (vec4 (left,
|
||||
outside.bounds.y,
|
||||
outside.bounds.z,
|
||||
max (outside.bounds.y + outside.corner_heights[TOP_RIGHT],
|
||||
inside.bounds.y + inside.corner_heights[TOP_RIGHT])));
|
||||
|
||||
case SLICE_RIGHT:
|
||||
top = max (outside.bounds.y + outside.corner_heights[TOP_RIGHT],
|
||||
inside.bounds.y + inside.corner_heights[TOP_RIGHT]);
|
||||
bottom = min (outside.bounds.w - outside.corner_heights[BOTTOM_RIGHT],
|
||||
inside.bounds.w - inside.corner_heights[BOTTOM_RIGHT]);
|
||||
return Rect (vec4 (min (outside.bounds.z, inside.bounds.z),
|
||||
top,
|
||||
outside.bounds.z,
|
||||
max (bottom, top)));
|
||||
|
||||
case SLICE_BOTTOM_RIGHT:
|
||||
left = max (min (outside.bounds.z - outside.corner_widths[BOTTOM_RIGHT],
|
||||
inside.bounds.z - inside.corner_widths[BOTTOM_RIGHT]),
|
||||
max (outside.bounds.x + outside.corner_widths[BOTTOM_LEFT],
|
||||
inside.bounds.x + inside.corner_widths[BOTTOM_LEFT]));
|
||||
bottom = max (min (outside.bounds.w - outside.corner_heights[BOTTOM_RIGHT],
|
||||
inside.bounds.w - inside.corner_heights[BOTTOM_RIGHT]),
|
||||
max (outside.bounds.y + outside.corner_heights[TOP_RIGHT],
|
||||
inside.bounds.y + inside.corner_heights[TOP_RIGHT]));
|
||||
return Rect (vec4 (left,
|
||||
bottom,
|
||||
outside.bounds.z,
|
||||
outside.bounds.w));
|
||||
|
||||
case SLICE_BOTTOM:
|
||||
left = max (outside.bounds.x + outside.corner_widths[BOTTOM_LEFT],
|
||||
inside.bounds.x + inside.corner_widths[BOTTOM_LEFT]);
|
||||
right = min (outside.bounds.z - outside.corner_widths[BOTTOM_RIGHT],
|
||||
inside.bounds.z - inside.corner_widths[BOTTOM_RIGHT]);
|
||||
return Rect (vec4 (left,
|
||||
min (outside.bounds.w, inside.bounds.w),
|
||||
max (left, right),
|
||||
outside.bounds.w));
|
||||
|
||||
case SLICE_BOTTOM_LEFT:
|
||||
bottom = max (min (outside.bounds.w - outside.corner_heights[BOTTOM_LEFT],
|
||||
inside.bounds.w - inside.corner_heights[BOTTOM_LEFT]),
|
||||
max (outside.bounds.y + outside.corner_heights[TOP_LEFT],
|
||||
inside.bounds.y + inside.corner_heights[TOP_LEFT]));
|
||||
return Rect (vec4 (outside.bounds.x,
|
||||
bottom,
|
||||
max (outside.bounds.x + outside.corner_widths[BOTTOM_LEFT],
|
||||
inside.bounds.x + inside.corner_widths[BOTTOM_LEFT]),
|
||||
outside.bounds.w));
|
||||
|
||||
case SLICE_LEFT:
|
||||
top = max (outside.bounds.y + outside.corner_heights[TOP_LEFT],
|
||||
inside.bounds.y + inside.corner_heights[TOP_LEFT]);
|
||||
bottom = min (outside.bounds.w - outside.corner_heights[BOTTOM_LEFT],
|
||||
inside.bounds.w - inside.corner_heights[BOTTOM_LEFT]);
|
||||
return Rect (vec4 (outside.bounds.x,
|
||||
top,
|
||||
max (outside.bounds.x, inside.bounds.x),
|
||||
max (bottom, top)));
|
||||
|
||||
default:
|
||||
return Rect (vec4 (0.0));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GSK_FRAGMENT_SHADER
|
||||
|
||||
float
|
||||
|
Loading…
Reference in New Issue
Block a user