4
4
5
5
#define VECS_PER_SPECIFIC_BRUSH 3
6
6
7
+ #define COMPONENT_TRANSFER_IDENTITY 0
8
+ #define COMPONENT_TRANSFER_TABLE 1
9
+ #define COMPONENT_TRANSFER_DISCRETE 2
10
+ #define COMPONENT_TRANSFER_LINEAR 3
11
+ #define COMPONENT_TRANSFER_GAMMA 4
12
+
7
13
#include shared ,prim_shared,brush
8
14
9
15
// Interpolated UV coordinates to sample.
@@ -16,6 +22,8 @@ flat varying int vOp;
16
22
flat varying mat3 vColorMat;
17
23
flat varying vec3 vColorOffset;
18
24
flat varying vec4 vUvClipBounds;
25
+ flat varying int vTableAddress;
26
+ flat varying int vFuncs[4 ];
19
27
20
28
#ifdef WR_VERTEX_SHADER
21
29
@@ -55,9 +63,21 @@ void brush_vs(
55
63
float amount = float (user_data.z) / 65536.0 ;
56
64
float invAmount = 1.0 - amount;
57
65
58
- vOp = user_data.y;
66
+ vOp = user_data.y & 0xffff ;
59
67
vAmount = amount;
60
68
69
+ // This assignment is only used for component transfer filters but this
70
+ // assignment has to be done here and not in the component transfer case
71
+ // below because it doesn't get executed on Windows because of a suspected
72
+ // miscompile of this shader on Windows. See
73
+ // https://github.com/servo/webrender/wiki/Driver-issues#bug-1505871---assignment-to-varying-flat-arrays-inside-switch-statement-of-vertex-shader-suspected-miscompile-on-windows
74
+ // default: just to satisfy angle_shader_validation.rs which needs one
75
+ // default: for every switch, even in comments.
76
+ vFuncs[0 ] = (user_data.y >> 28 ) & 0xf; // R
77
+ vFuncs[1 ] = (user_data.y >> 24 ) & 0xf; // G
78
+ vFuncs[2 ] = (user_data.y >> 20 ) & 0xf; // B
79
+ vFuncs[3 ] = (user_data.y >> 16 ) & 0xf; // A
80
+
61
81
switch (vOp) {
62
82
case 2 : {
63
83
// Grayscale
@@ -109,6 +129,11 @@ void brush_vs(
109
129
vColorOffset = offset_data.rgb;
110
130
break ;
111
131
}
132
+ case 13 : {
133
+ // Component Transfer
134
+ vTableAddress = user_data.z;
135
+ break ;
136
+ }
112
137
default : break ;
113
138
}
114
139
}
@@ -177,6 +202,58 @@ Fragment brush_fs() {
177
202
case 12 :
178
203
color = LinearToSrgb(color);
179
204
break ;
205
+ case 13 : // Component Transfer
206
+ int offset = 0 ;
207
+ vec4 texel;
208
+ int k;
209
+
210
+ // We push a different amount of data to the gpu cache depending
211
+ // on the function type.
212
+ // Identity => 0 blocks
213
+ // Table/Discrete => 64 blocks (256 values)
214
+ // Linear => 1 block (2 values)
215
+ // Gamma => 1 block (3 values)
216
+ // We loop through the color components and increment the offset
217
+ // (for the next color component) into the gpu cache based on how
218
+ // many blocks that function type put into the gpu cache.
219
+ // Table/Discrete use a 256 entry look up table.
220
+ // Linear/Gamma are a simple calculation.
221
+ vec4 colora = alpha != 0.0 ? Cs / alpha : Cs;
222
+ for (int i = 0 ; i < 4 ; i++ ) {
223
+ switch (vFuncs[i]) {
224
+ case COMPONENT_TRANSFER_IDENTITY:
225
+ break ;
226
+ case COMPONENT_TRANSFER_TABLE:
227
+ case COMPONENT_TRANSFER_DISCRETE:
228
+ // fetch value from lookup table
229
+ k = int (floor (colora[i]* 255.0 ));
230
+ texel = fetch_from_gpu_cache_1(vTableAddress + offset + k/ 4 );
231
+ colora[i] = clamp (texel[k % 4 ], 0.0 , 1.0 );
232
+ // offset plus 256/4 blocks
233
+ offset = offset + 64 ;
234
+ break ;
235
+ case COMPONENT_TRANSFER_LINEAR:
236
+ // fetch the two values for use in the linear equation
237
+ texel = fetch_from_gpu_cache_1(vTableAddress + offset);
238
+ colora[i] = clamp (texel[0 ] * colora[i] + texel[1 ], 0.0 , 1.0 );
239
+ // offset plus 1 block
240
+ offset = offset + 1 ;
241
+ break ;
242
+ case COMPONENT_TRANSFER_GAMMA:
243
+ // fetch the three values for use in the gamma equation
244
+ texel = fetch_from_gpu_cache_1(vTableAddress + offset);
245
+ colora[i] = clamp (texel[0 ] * pow (colora[i], texel[1 ]) + texel[2 ], 0.0 , 1.0 );
246
+ // offset plus 1 block
247
+ offset = offset + 1 ;
248
+ break ;
249
+ default :
250
+ // shouldn't happen
251
+ break ;
252
+ }
253
+ }
254
+ color = colora.rgb;
255
+ alpha = colora.a;
256
+ break ;
180
257
default :
181
258
color = vColorMat * color + vColorOffset;
182
259
}
0 commit comments