forked from Floorp-Projects/Floorp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcs_border_solid.glsl
139 lines (114 loc) · 3.81 KB
/
cs_border_solid.glsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include shared,ellipse
#define DONT_MIX 0
#define MIX_AA 1
#define MIX_NO_AA 2
// For edges, the colors are the same. For corners, these
// are the colors of each edge making up the corner.
flat varying vec4 vColor0;
flat varying vec4 vColor1;
// A point + tangent defining the line where the edge
// transition occurs. Used for corners only.
flat varying vec4 vColorLine;
// A boolean indicating that we should be mixing between edge colors.
flat varying int vMixColors;
// xy = Local space position of the clip center.
// zw = Scale the rect origin by this to get the outer
// corner from the segment rectangle.
flat varying vec4 vClipCenter_Sign;
// An outer and inner elliptical radii for border
// corner clipping.
flat varying vec4 vClipRadii;
// Local space position
varying vec2 vPos;
#define SEGMENT_TOP_LEFT 0
#define SEGMENT_TOP_RIGHT 1
#define SEGMENT_BOTTOM_RIGHT 2
#define SEGMENT_BOTTOM_LEFT 3
#ifdef WR_VERTEX_SHADER
in vec2 aTaskOrigin;
in vec4 aRect;
in vec4 aColor0;
in vec4 aColor1;
in int aFlags;
in vec2 aWidths;
in vec2 aRadii;
vec2 get_outer_corner_scale(int segment) {
vec2 p;
switch (segment) {
case SEGMENT_TOP_LEFT:
p = vec2(0.0, 0.0);
break;
case SEGMENT_TOP_RIGHT:
p = vec2(1.0, 0.0);
break;
case SEGMENT_BOTTOM_RIGHT:
p = vec2(1.0, 1.0);
break;
case SEGMENT_BOTTOM_LEFT:
p = vec2(0.0, 1.0);
break;
default:
// The result is only used for non-default segment cases
p = vec2(0.0);
break;
}
return p;
}
void main(void) {
int segment = aFlags & 0xff;
bool do_aa = ((aFlags >> 24) & 0xf0) != 0;
vec2 outer_scale = get_outer_corner_scale(segment);
vec2 outer = outer_scale * aRect.zw;
vec2 clip_sign = 1.0 - 2.0 * outer_scale;
int mix_colors;
switch (segment) {
case SEGMENT_TOP_LEFT:
case SEGMENT_TOP_RIGHT:
case SEGMENT_BOTTOM_RIGHT:
case SEGMENT_BOTTOM_LEFT:
mix_colors = do_aa ? MIX_AA : MIX_NO_AA;
break;
default:
mix_colors = DONT_MIX;
break;
}
vMixColors = mix_colors;
vPos = aRect.zw * aPosition.xy;
vColor0 = aColor0;
vColor1 = aColor1;
vClipCenter_Sign = vec4(outer + clip_sign * aRadii, clip_sign);
vClipRadii = vec4(aRadii, max(aRadii - aWidths, 0.0));
vColorLine = vec4(outer, aWidths.y * -clip_sign.y, aWidths.x * clip_sign.x);
gl_Position = uTransform * vec4(aTaskOrigin + aRect.xy + vPos, 0.0, 1.0);
}
#endif
#ifdef WR_FRAGMENT_SHADER
void main(void) {
float aa_range = compute_aa_range(vPos);
bool do_aa = vMixColors != MIX_NO_AA;
float mix_factor = 0.0;
if (vMixColors != DONT_MIX) {
float d_line = distance_to_line(vColorLine.xy, vColorLine.zw, vPos);
if (do_aa) {
mix_factor = distance_aa(aa_range, -d_line);
} else {
mix_factor = d_line + EPSILON >= 0. ? 1.0 : 0.0;
}
}
// Check if inside corner clip-region
vec2 clip_relative_pos = vPos - vClipCenter_Sign.xy;
bool in_clip_region = all(lessThan(vClipCenter_Sign.zw * clip_relative_pos, vec2(0.0)));
float d = -1.0;
if (in_clip_region) {
float d_radii_a = distance_to_ellipse(clip_relative_pos, vClipRadii.xy, aa_range);
float d_radii_b = distance_to_ellipse(clip_relative_pos, vClipRadii.zw, aa_range);
d = max(d_radii_a, -d_radii_b);
}
float alpha = do_aa ? distance_aa(aa_range, d) : 1.0;
vec4 color = mix(vColor0, vColor1, mix_factor);
oFragColor = color * alpha;
}
#endif