forked from Floorp-Projects/Floorp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcs_clip_line.glsl
207 lines (178 loc) · 6.91 KB
/
cs_clip_line.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/* 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,clip_shared
#define LINE_STYLE_SOLID 0
#define LINE_STYLE_DOTTED 1
#define LINE_STYLE_DASHED 2
#define LINE_STYLE_WAVY 3
varying vec3 vLocalPos;
flat varying int vStyle;
flat varying float vAxisSelect;
flat varying vec4 vParams;
flat varying vec2 vLocalOrigin;
#ifdef WR_VERTEX_SHADER
#define LINE_ORIENTATION_VERTICAL 0
#define LINE_ORIENTATION_HORIZONTAL 1
struct LineDecorationData {
RectWithSize local_rect;
float wavyLineThickness;
float style;
float orientation;
};
LineDecorationData fetch_data(ivec2 address) {
vec4 data[2] = fetch_from_resource_cache_2_direct(address);
RectWithSize local_rect = RectWithSize(data[0].xy, data[0].zw);
LineDecorationData line_data = LineDecorationData(
local_rect,
data[1].x,
data[1].y,
data[1].z
);
return line_data;
}
void main(void) {
ClipMaskInstance cmi = fetch_clip_item();
ClipArea area = fetch_clip_area(cmi.render_task_address);
Transform clip_transform = fetch_transform(cmi.clip_transform_id);
Transform prim_transform = fetch_transform(cmi.prim_transform_id);
LineDecorationData data = fetch_data(cmi.clip_data_address);
ClipVertexInfo vi = write_clip_tile_vertex(
data.local_rect,
prim_transform,
clip_transform,
area
);
vLocalPos = vi.local_pos;
vec2 pos, size;
switch (int(data.orientation)) {
case LINE_ORIENTATION_HORIZONTAL:
vAxisSelect = 0.0;
pos = data.local_rect.p0;
size = data.local_rect.size;
break;
case LINE_ORIENTATION_VERTICAL:
vAxisSelect = 1.0;
pos = data.local_rect.p0.yx;
size = data.local_rect.size.yx;
break;
default:
vAxisSelect = 0.0;
pos = size = vec2(0.0);
}
vLocalOrigin = pos;
vStyle = int(data.style);
switch (vStyle) {
case LINE_STYLE_SOLID: {
break;
}
case LINE_STYLE_DASHED: {
float dash_length = size.y * 3.0;
vParams = vec4(2.0 * dash_length, // period
dash_length, // dash length
0.0,
0.0);
break;
}
case LINE_STYLE_DOTTED: {
float diameter = size.y;
float period = diameter * 2.0;
float center_line = pos.y + 0.5 * size.y;
float max_x = floor(size.x / period) * period;
vParams = vec4(period,
diameter / 2.0, // radius
center_line,
max_x);
break;
}
case LINE_STYLE_WAVY: {
// This logic copied from gecko to get the same results
float line_thickness = max(data.wavyLineThickness, 1.0);
// Difference in height between peaks and troughs
// (and since slopes are 45 degrees, the length of each slope)
float slope_length = size.y - line_thickness;
// Length of flat runs
float flat_length = max((line_thickness - 1.0) * 2.0, 1.0);
vParams = vec4(line_thickness / 2.0,
slope_length,
flat_length,
size.y);
break;
}
default:
vParams = vec4(0.0);
}
}
#endif
#ifdef WR_FRAGMENT_SHADER
#define MAGIC_WAVY_LINE_AA_SNAP 0.5
void main(void) {
// Find the appropriate distance to apply the step over.
vec2 local_pos = vLocalPos.xy / vLocalPos.z;
float aa_range = compute_aa_range(local_pos);
float alpha = 1.0;
// Select the x/y coord, depending on which axis this edge is.
vec2 pos = mix(local_pos.xy, local_pos.yx, vAxisSelect);
switch (vStyle) {
case LINE_STYLE_SOLID: {
break;
}
case LINE_STYLE_DASHED: {
// Get the main-axis position relative to closest dot or dash.
float x = mod(pos.x - vLocalOrigin.x, vParams.x);
// Calculate dash alpha (on/off) based on dash length
alpha = step(x, vParams.y);
break;
}
case LINE_STYLE_DOTTED: {
// Get the main-axis position relative to closest dot or dash.
float x = mod(pos.x - vLocalOrigin.x, vParams.x);
// Get the dot alpha
vec2 dot_relative_pos = vec2(x, pos.y) - vParams.yz;
float dot_distance = length(dot_relative_pos) - vParams.y;
alpha = distance_aa(aa_range, dot_distance);
// Clip off partial dots
alpha *= step(pos.x - vLocalOrigin.x, vParams.w);
break;
}
case LINE_STYLE_WAVY: {
vec2 normalized_local_pos = pos - vLocalOrigin.xy;
float half_line_thickness = vParams.x;
float slope_length = vParams.y;
float flat_length = vParams.z;
float vertical_bounds = vParams.w;
// Our pattern is just two slopes and two flats
float half_period = slope_length + flat_length;
float mid_height = vertical_bounds / 2.0;
float peak_offset = mid_height - half_line_thickness;
// Flip the wave every half period
float flip = -2.0 * (step(mod(normalized_local_pos.x, 2.0 * half_period), half_period) - 0.5);
// float flip = -1.0;
peak_offset *= flip;
float peak_height = mid_height + peak_offset;
// Convert pos to a local position within one half period
normalized_local_pos.x = mod(normalized_local_pos.x, half_period);
// Compute signed distance to the 3 lines that make up an arc
float dist1 = distance_to_line(vec2(0.0, peak_height),
vec2(1.0, -flip),
normalized_local_pos);
float dist2 = distance_to_line(vec2(0.0, peak_height),
vec2(0, -flip),
normalized_local_pos);
float dist3 = distance_to_line(vec2(flat_length, peak_height),
vec2(-1.0, -flip),
normalized_local_pos);
float dist = abs(max(max(dist1, dist2), dist3));
// Apply AA based on the thickness of the wave
alpha = distance_aa(aa_range, dist - half_line_thickness);
// Disable AA for thin lines
if (half_line_thickness <= 1.0) {
alpha = 1.0 - step(alpha, MAGIC_WAVY_LINE_AA_SNAP);
}
break;
}
default: break;
}
oFragColor = vec4(alpha);
}
#endif