Bug 1857841 - pt 3. Add a new page kind named "fresh" r=glandium
[gecko.git] / gfx / wr / webrender / res / cs_line_decoration.glsl
blob00ed2e249a2dfa017271c604ae72c766d0f43a84
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include shared
7 #define LINE_STYLE_SOLID        0
8 #define LINE_STYLE_DOTTED       1
9 #define LINE_STYLE_DASHED       2
10 #define LINE_STYLE_WAVY         3
12 // Fragment position in the coordinate system used for positioning decorations.
13 // To keep the code independent of whether the line is horizontal or vertical,
14 // vLocalPos.x is always parallel, and .y always perpendicular, to the line
15 // being decorated.
16 varying highp vec2 vLocalPos;
18 // Line style. Packed in to a vector to work around bug 1630356.
19 flat varying mediump ivec2 vStyle;
21 flat varying mediump vec4 vParams;
23 #ifdef WR_VERTEX_SHADER
25 // The size of the mask tile we're rendering, in pixels.
26 PER_INSTANCE in vec4 aTaskRect;
28 // The size of the mask tile. aLocalSize.x is always horizontal and .y vertical,
29 // regardless of the line's orientation. The size is chosen by
30 // prim_store::line_dec::get_line_decoration_sizes.
31 PER_INSTANCE in vec2 aLocalSize;
33 // A LINE_STYLE_* value, indicating what sort of line to draw.
34 PER_INSTANCE in int aStyle;
36 // 0.0 for a horizontal line, 1.0 for a vertical line.
37 PER_INSTANCE in float aAxisSelect;
39 // The thickness of the wavy line itself, not the amplitude of the waves (i.e.,
40 // the thickness of the final decorated line).
41 PER_INSTANCE in float aWavyLineThickness;
43 void main(void) {
44     vec2 size = mix(aLocalSize, aLocalSize.yx, aAxisSelect);
45     vStyle.x = aStyle;
47     switch (vStyle.x) {
48         case LINE_STYLE_SOLID: {
49             break;
50         }
51         case LINE_STYLE_DASHED: {
52             vParams = vec4(size.x,          // period
53                            0.5 * size.x,    // dash length
54                            0.0,
55                            0.0);
56             break;
57         }
58         case LINE_STYLE_DOTTED: {
59             float diameter = size.y;
60             float period = diameter * 2.0;
61             float center_line = 0.5 * size.y;
62             vParams = vec4(period,
63                            diameter / 2.0, // radius
64                            center_line,
65                            0.0);
66             break;
67         }
68         case LINE_STYLE_WAVY: {
69             // This logic copied from gecko to get the same results
70             float line_thickness = max(aWavyLineThickness, 1.0);
71             // Difference in height between peaks and troughs
72             // (and since slopes are 45 degrees, the length of each slope)
73             float slope_length = size.y - line_thickness;
74             // Length of flat runs
75             float flat_length = max((line_thickness - 1.0) * 2.0, 1.0);
77             vParams = vec4(line_thickness / 2.0,
78                            slope_length,
79                            flat_length,
80                            size.y);
81             break;
82         }
83         default:
84             vParams = vec4(0.0);
85     }
87     vLocalPos = mix(aPosition.xy, aPosition.yx, aAxisSelect) * size;
89     gl_Position = uTransform * vec4(mix(aTaskRect.xy, aTaskRect.zw, aPosition.xy), 0.0, 1.0);
91 #endif
93 #ifdef WR_FRAGMENT_SHADER
95 #define MAGIC_WAVY_LINE_AA_SNAP         0.5
97 void main(void) {
98     // Find the appropriate distance to apply the step over.
99     vec2 pos = vLocalPos;
100     float aa_range = compute_aa_range(pos);
101     float alpha = 1.0;
103     switch (vStyle.x) {
104         case LINE_STYLE_SOLID: {
105             break;
106         }
107         case LINE_STYLE_DASHED: {
108             // Calculate dash alpha (on/off) based on dash length
109             alpha = step(floor(pos.x + 0.5), vParams.y);
110             break;
111         }
112         case LINE_STYLE_DOTTED: {
113             // Get the dot alpha
114             vec2 dot_relative_pos = pos - vParams.yz;
115             float dot_distance = length(dot_relative_pos) - vParams.y;
116             alpha = distance_aa(aa_range, dot_distance);
117             break;
118         }
119         case LINE_STYLE_WAVY: {
120             float half_line_thickness = vParams.x;
121             float slope_length = vParams.y;
122             float flat_length = vParams.z;
123             float vertical_bounds = vParams.w;
124             // Our pattern is just two slopes and two flats
125             float half_period = slope_length + flat_length;
127             float mid_height = vertical_bounds / 2.0;
128             float peak_offset = mid_height - half_line_thickness;
129             // Flip the wave every half period
130             float flip = -2.0 * (step(mod(pos.x, 2.0 * half_period), half_period) - 0.5);
131             // float flip = -1.0;
132             peak_offset *= flip;
133             float peak_height = mid_height + peak_offset;
135             // Convert pos to a local position within one half period
136             pos.x = mod(pos.x, half_period);
138             // Compute signed distance to the 3 lines that make up an arc
139             float dist1 = distance_to_line(vec2(0.0, peak_height),
140                                            vec2(1.0, -flip),
141                                            pos);
142             float dist2 = distance_to_line(vec2(0.0, peak_height),
143                                            vec2(0, -flip),
144                                            pos);
145             float dist3 = distance_to_line(vec2(flat_length, peak_height),
146                                            vec2(-1.0, -flip),
147                                            pos);
148             float dist = abs(max(max(dist1, dist2), dist3));
150             // Apply AA based on the thickness of the wave
151             alpha = distance_aa(aa_range, dist - half_line_thickness);
153             // Disable AA for thin lines
154             if (half_line_thickness <= 1.0) {
155                 alpha = 1.0 - step(alpha, MAGIC_WAVY_LINE_AA_SNAP);
156             }
158             break;
159         }
160         default: break;
161     }
163     oFragColor = vec4(alpha);
165 #endif