cs_border_solid.glsl (5790B)
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/. */ 4 5 #include shared,rect,ellipse 6 7 #define DONT_MIX 0 8 #define MIX_AA 1 9 #define MIX_NO_AA 2 10 11 // For edges, the colors are the same. For corners, these 12 // are the colors of each edge making up the corner. 13 flat varying mediump vec4 vColor0; 14 flat varying mediump vec4 vColor1; 15 16 // A point + tangent defining the line where the edge 17 // transition occurs. Used for corners only. 18 flat varying highp vec4 vColorLine; 19 20 // A boolean indicating that we should be mixing between edge colors. 21 // Packed in to a vector to work around bug 1630356. 22 flat varying mediump ivec2 vMixColors; 23 24 // xy = Local space position of the clip center. 25 // zw = Scale the rect origin by this to get the outer 26 // corner from the segment rectangle. 27 flat varying highp vec4 vClipCenter_Sign; 28 29 // An outer and inner elliptical radii for border 30 // corner clipping. 31 flat varying highp vec4 vClipRadii; 32 33 // Position, scale, and radii of horizontally and vertically adjacent corner clips. 34 flat varying highp vec4 vHorizontalClipCenter_Sign; 35 flat varying highp vec2 vHorizontalClipRadii; 36 flat varying highp vec4 vVerticalClipCenter_Sign; 37 flat varying highp vec2 vVerticalClipRadii; 38 39 // Local space position 40 varying highp vec2 vPos; 41 42 #define SEGMENT_TOP_LEFT 0 43 #define SEGMENT_TOP_RIGHT 1 44 #define SEGMENT_BOTTOM_RIGHT 2 45 #define SEGMENT_BOTTOM_LEFT 3 46 47 #ifdef WR_VERTEX_SHADER 48 49 PER_INSTANCE in vec2 aTaskOrigin; 50 PER_INSTANCE in vec4 aRect; 51 PER_INSTANCE in vec4 aColor0; 52 PER_INSTANCE in vec4 aColor1; 53 PER_INSTANCE in int aFlags; 54 PER_INSTANCE in vec2 aWidths; 55 PER_INSTANCE in vec2 aRadii; 56 PER_INSTANCE in vec4 aClipParams1; 57 PER_INSTANCE in vec4 aClipParams2; 58 59 vec2 get_outer_corner_scale(int segment) { 60 vec2 p; 61 62 switch (segment) { 63 case SEGMENT_TOP_LEFT: 64 p = vec2(0.0, 0.0); 65 break; 66 case SEGMENT_TOP_RIGHT: 67 p = vec2(1.0, 0.0); 68 break; 69 case SEGMENT_BOTTOM_RIGHT: 70 p = vec2(1.0, 1.0); 71 break; 72 case SEGMENT_BOTTOM_LEFT: 73 p = vec2(0.0, 1.0); 74 break; 75 default: 76 // The result is only used for non-default segment cases 77 p = vec2(0.0); 78 break; 79 } 80 81 return p; 82 } 83 84 void main(void) { 85 int segment = aFlags & 0xff; 86 bool do_aa = ((aFlags >> 24) & 0xf0) != 0; 87 88 vec2 outer_scale = get_outer_corner_scale(segment); 89 vec2 size = aRect.zw - aRect.xy; 90 vec2 outer = outer_scale * size; 91 vec2 clip_sign = 1.0 - 2.0 * outer_scale; 92 93 int mix_colors; 94 switch (segment) { 95 case SEGMENT_TOP_LEFT: 96 case SEGMENT_TOP_RIGHT: 97 case SEGMENT_BOTTOM_RIGHT: 98 case SEGMENT_BOTTOM_LEFT: { 99 mix_colors = do_aa ? MIX_AA : MIX_NO_AA; 100 break; 101 } 102 default: 103 mix_colors = DONT_MIX; 104 break; 105 } 106 107 vMixColors.x = mix_colors; 108 vPos = size * aPosition.xy; 109 110 vColor0 = aColor0; 111 vColor1 = aColor1; 112 vClipCenter_Sign = vec4(outer + clip_sign * aRadii, clip_sign); 113 vClipRadii = vec4(aRadii, max(aRadii - aWidths, 0.0)); 114 vColorLine = vec4(outer, aWidths.y * -clip_sign.y, aWidths.x * clip_sign.x); 115 116 vec2 horizontal_clip_sign = vec2(-clip_sign.x, clip_sign.y); 117 vHorizontalClipCenter_Sign = vec4(aClipParams1.xy + 118 horizontal_clip_sign * aClipParams1.zw, 119 horizontal_clip_sign); 120 vHorizontalClipRadii = aClipParams1.zw; 121 122 vec2 vertical_clip_sign = vec2(clip_sign.x, -clip_sign.y); 123 vVerticalClipCenter_Sign = vec4(aClipParams2.xy + 124 vertical_clip_sign * aClipParams2.zw, 125 vertical_clip_sign); 126 vVerticalClipRadii = aClipParams2.zw; 127 128 gl_Position = uTransform * vec4(aTaskOrigin + aRect.xy + vPos, 0.0, 1.0); 129 } 130 #endif 131 132 #ifdef WR_FRAGMENT_SHADER 133 void main(void) { 134 float aa_range = compute_aa_range(vPos); 135 bool do_aa = vMixColors.x != MIX_NO_AA; 136 137 float mix_factor = 0.0; 138 if (vMixColors.x != DONT_MIX) { 139 float d_line = distance_to_line(vColorLine.xy, vColorLine.zw, vPos); 140 if (do_aa) { 141 mix_factor = distance_aa(aa_range, -d_line); 142 } else { 143 mix_factor = d_line + EPSILON >= 0. ? 1.0 : 0.0; 144 } 145 } 146 147 // Check if inside main corner clip-region 148 vec2 clip_relative_pos = vPos - vClipCenter_Sign.xy; 149 bool in_clip_region = all(lessThan(vClipCenter_Sign.zw * clip_relative_pos, vec2(0.0))); 150 151 float d = -1.0; 152 if (in_clip_region) { 153 float d_radii_a = distance_to_ellipse(clip_relative_pos, vClipRadii.xy); 154 float d_radii_b = distance_to_ellipse(clip_relative_pos, vClipRadii.zw); 155 d = max(d_radii_a, -d_radii_b); 156 } 157 158 // And again for horizontally-adjacent corner 159 clip_relative_pos = vPos - vHorizontalClipCenter_Sign.xy; 160 in_clip_region = all(lessThan(vHorizontalClipCenter_Sign.zw * clip_relative_pos, vec2(0.0))); 161 if (in_clip_region) { 162 float d_radii = distance_to_ellipse(clip_relative_pos, vHorizontalClipRadii.xy); 163 d = max(d_radii, d); 164 } 165 166 // And finally for vertically-adjacent corner 167 clip_relative_pos = vPos - vVerticalClipCenter_Sign.xy; 168 in_clip_region = all(lessThan(vVerticalClipCenter_Sign.zw * clip_relative_pos, vec2(0.0))); 169 if (in_clip_region) { 170 float d_radii = distance_to_ellipse(clip_relative_pos, vVerticalClipRadii.xy); 171 d = max(d_radii, d); 172 } 173 174 float alpha = do_aa ? distance_aa(aa_range, d) : 1.0; 175 vec4 color = mix(vColor0, vColor1, mix_factor); 176 oFragColor = color * alpha; 177 } 178 #endif