vulkan: Make border shader handle fractional widths
authorBenjamin Otte <otte@redhat.com>
Sun, 7 May 2023 01:41:38 +0000 (03:41 +0200)
committerBenjamin Otte <otte@redhat.com>
Sun, 4 Jun 2023 17:42:00 +0000 (19:42 +0200)
We were rounding widths properly, make sure we always round up.

gsk/vulkan/resources/border.vert
gsk/vulkan/resources/clip.vert.glsl
gsk/vulkan/resources/color.vert
gsk/vulkan/resources/rect.glsl

index c712796e6bfdf1076552f151498d4caea928b6ed..d0f328a2e1482019f66041fe32ebaf5ac32b52d7 100644 (file)
@@ -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;
index ae5c75a39ddf61439854779980be2827e6391998..3c1e81eaf1c3e8508390d7fada7697cf0484d5d8 100644 (file)
@@ -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
index 7601b7d82ac94f400ffa2751f0bfec5257a3beb1..cc2a853b5c3f1b928f67267164a1673d23a8d35f 100644 (file)
@@ -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);
index ba07a05a9892134e8d4b3b5624e6d0bf56b1dee3..31c8d476f901d1f7f6dbd28cc06a23feec77e294 100644 (file)
@@ -29,11 +29,23 @@ 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)
 {