summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2023-05-07 03:41:38 +0200
committerBenjamin Otte <otte@redhat.com>2023-05-17 02:25:32 +0200
commit963d0c9d69fd65317b53af508bee418bc0b0e073 (patch)
tree5009e3762470a13bedf011a7288b55e9b3774062
parentfb3f4a2f279dbbbf37d046a39d9166ba0aa99eef (diff)
downloadgtk+-963d0c9d69fd65317b53af508bee418bc0b0e073.tar.gz
vulkan: Make border shader handle fractional widths
We were rounding widths properly, make sure we always round up.
-rw-r--r--gsk/vulkan/resources/border.vert33
-rw-r--r--gsk/vulkan/resources/clip.vert.glsl12
-rw-r--r--gsk/vulkan/resources/color.vert2
-rw-r--r--gsk/vulkan/resources/rect.glsl14
4 files changed, 41 insertions, 20 deletions
diff --git a/gsk/vulkan/resources/border.vert b/gsk/vulkan/resources/border.vert
index c712796e6b..d0f328a2e1 100644
--- a/gsk/vulkan/resources/border.vert
+++ b/gsk/vulkan/resources/border.vert
@@ -48,46 +48,55 @@ void main() {
vec4 corner_widths = max (inCornerWidths, inBorderWidths.wyyw);
vec4 corner_heights = max (inCornerHeights, inBorderWidths.xxzz);
- vec4 rect;
+ Rect rect;
switch (slice_index)
{
case SLICE_TOP_LEFT:
- rect = vec4(inRect.xy, corner_widths[TOP_LEFT], corner_heights[TOP_LEFT]);
+ rect = rect_from_gsk (vec4(inRect.xy, corner_widths[TOP_LEFT], corner_heights[TOP_LEFT]));
+ rect = rect_round_larger (rect);
vert_index = (vert_index + 3) % 6;
break;
case SLICE_TOP:
- rect = vec4(inRect.x + corner_widths[TOP_LEFT], inRect.y, inRect.z - corner_widths[TOP_LEFT] - corner_widths[TOP_RIGHT], inBorderWidths[TOP]);
+ rect = rect_from_gsk (vec4(inRect.x + corner_widths[TOP_LEFT], inRect.y, inRect.z - corner_widths[TOP_LEFT] - corner_widths[TOP_RIGHT], inBorderWidths[TOP]));
+ rect = rect_round_smaller_larger (rect);
outColor = inBorderColors[TOP];
break;
case SLICE_TOP_RIGHT:
- rect = vec4(inRect.x + inRect.z - corner_widths[TOP_RIGHT], inRect.y, corner_widths[TOP_RIGHT], corner_heights[TOP_RIGHT]);
+ rect = rect_from_gsk (vec4(inRect.x + inRect.z - corner_widths[TOP_RIGHT], inRect.y, corner_widths[TOP_RIGHT], corner_heights[TOP_RIGHT]));
+ rect = rect_round_larger (rect);
break;
case SLICE_RIGHT:
- rect = vec4(inRect.x + inRect.z - inBorderWidths[RIGHT], inRect.y + corner_heights[TOP_RIGHT], inBorderWidths[RIGHT], inRect.w - corner_heights[TOP_RIGHT] - corner_heights[BOTTOM_RIGHT]);
+ rect = rect_from_gsk (vec4(inRect.x + inRect.z - inBorderWidths[RIGHT], inRect.y + corner_heights[TOP_RIGHT], inBorderWidths[RIGHT], inRect.w - corner_heights[TOP_RIGHT] - corner_heights[BOTTOM_RIGHT]));
+ rect = rect_round_larger_smaller (rect);
outColor = inBorderColors[RIGHT];
break;
case SLICE_BOTTOM_RIGHT:
- rect = vec4(inRect.x + inRect.z - corner_widths[BOTTOM_RIGHT], inRect.y + inRect.w - corner_heights[BOTTOM_RIGHT], corner_widths[BOTTOM_RIGHT], corner_heights[BOTTOM_RIGHT]);
+ rect = rect_from_gsk (vec4(inRect.x + inRect.z - corner_widths[BOTTOM_RIGHT], inRect.y + inRect.w - corner_heights[BOTTOM_RIGHT], corner_widths[BOTTOM_RIGHT], corner_heights[BOTTOM_RIGHT]));
+ rect = rect_round_larger (rect);
break;
case SLICE_BOTTOM:
- rect = vec4(inRect.x + corner_widths[BOTTOM_LEFT], inRect.y + inRect.w - inBorderWidths[BOTTOM], inRect.z - corner_widths[BOTTOM_LEFT] - corner_widths[BOTTOM_RIGHT], inBorderWidths[BOTTOM]);
+ rect = rect_from_gsk (vec4(inRect.x + corner_widths[BOTTOM_LEFT], inRect.y + inRect.w - inBorderWidths[BOTTOM], inRect.z - corner_widths[BOTTOM_LEFT] - corner_widths[BOTTOM_RIGHT], inBorderWidths[BOTTOM]));
+ rect = rect_round_smaller_larger (rect);
break;
case SLICE_BOTTOM_LEFT:
- rect = vec4(inRect.x, inRect.y + inRect.w - corner_heights[BOTTOM_LEFT], corner_widths[BOTTOM_LEFT], corner_heights[BOTTOM_LEFT]);
+ rect = rect_from_gsk (vec4(inRect.x, inRect.y + inRect.w - corner_heights[BOTTOM_LEFT], corner_widths[BOTTOM_LEFT], corner_heights[BOTTOM_LEFT]));
vert_index = (vert_index + 3) % 6;
+ rect = rect_round_larger (rect);
break;
case SLICE_LEFT:
- rect = vec4(inRect.x, inRect.y + corner_heights[TOP_LEFT], inBorderWidths[LEFT], inRect.w - corner_heights[TOP_LEFT] - corner_heights[BOTTOM_LEFT]);
+ rect = rect_from_gsk (vec4(inRect.x, inRect.y + corner_heights[TOP_LEFT], inBorderWidths[LEFT], inRect.w - corner_heights[TOP_LEFT] - corner_heights[BOTTOM_LEFT]));
+ rect = rect_round_larger_smaller (rect);
break;
}
- rect = clip (rect);
+ rect = clip_rect (rect);
+
vec2 pos;
if ((slice_index % 4) != 0 || (vert_index % 3) != 2)
- pos = rect.xy + rect.zw * offsets[vert_index];
+ pos = mix (rect.bounds.xy, rect.bounds.zw, offsets[vert_index]);
else
- pos = rect.xy + rect.zw * vec2(1.0 - offsets[vert_index].x, offsets[vert_index].y);
+ pos = mix (rect.bounds.zy, rect.bounds.xw, offsets[vert_index]);
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
outColor = inBorderColors[((gl_VertexIndex / 3 + 15) / 4) % 4];
outPos = pos;
diff --git a/gsk/vulkan/resources/clip.vert.glsl b/gsk/vulkan/resources/clip.vert.glsl
index ae5c75a39d..3c1e81eaf1 100644
--- a/gsk/vulkan/resources/clip.vert.glsl
+++ b/gsk/vulkan/resources/clip.vert.glsl
@@ -24,10 +24,10 @@ clip(vec4 rect)
}
Rect
-clip_rect (vec4 xywh)
+clip_rect (Rect r)
{
/* rounded corner clipping is done in fragment shader */
- return rect_intersect (rect_from_gsk (xywh), rect_to_int (rect_from_gsk (push.clip_bounds)));
+ return rect_intersect (r, rect_round_larger (rect_from_gsk (push.clip_bounds)));
}
#elif defined(CLIP_RECT)
@@ -39,9 +39,9 @@ clip(vec4 rect)
}
Rect
-clip_rect (vec4 xywh)
+clip_rect (Rect r)
{
- return rect_intersect (rect_from_gsk (xywh), rect_to_int (rect_from_gsk (push.clip_bounds)));
+ return rect_intersect (r, rect_round_larger (rect_from_gsk (push.clip_bounds)));
}
#elif defined(CLIP_NONE)
@@ -51,9 +51,9 @@ vec4 clip(vec4 rect)
}
Rect
-clip_rect (vec4 xywh)
+clip_rect (Rect r)
{
- return rect_from_gsk (xywh);
+ return r;
}
#else
diff --git a/gsk/vulkan/resources/color.vert b/gsk/vulkan/resources/color.vert
index 7601b7d82a..cc2a853b5c 100644
--- a/gsk/vulkan/resources/color.vert
+++ b/gsk/vulkan/resources/color.vert
@@ -18,7 +18,7 @@ vec2 offsets[6] = { vec2(0.0, 0.0),
vec2(1.0, 1.0) };
void main() {
- Rect rect = rect_to_int (clip_rect (inRect));
+ Rect rect = rect_round_larger (clip_rect (rect_from_gsk (inRect)));
vec2 pos = mix (rect.bounds.xy, rect.bounds.zw, offsets[gl_VertexIndex]);
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
diff --git a/gsk/vulkan/resources/rect.glsl b/gsk/vulkan/resources/rect.glsl
index ba07a05a98..31c8d476f9 100644
--- a/gsk/vulkan/resources/rect.glsl
+++ b/gsk/vulkan/resources/rect.glsl
@@ -29,12 +29,24 @@ rect_size (Rect r)
}
Rect
-rect_to_int (Rect r)
+rect_round_larger (Rect r)
{
return Rect (vec4 (floor(r.bounds.xy), ceil (r.bounds.zw)));
}
Rect
+rect_round_larger_smaller (Rect r)
+{
+ return Rect (mix (floor(r.bounds), ceil (r.bounds), bvec4(0, 1, 1, 0)));
+}
+
+Rect
+rect_round_smaller_larger (Rect r)
+{
+ return Rect (mix (floor(r.bounds), ceil (r.bounds), bvec4(1, 0, 0, 1)));
+}
+
+Rect
rect_intersect (Rect a, Rect b)
{
vec4 result = vec4(max(a.bounds.xy, b.bounds.xy), min(a.bounds.zw, b.bounds.zw));