Merge mozilla-central to autoland. a=merge CLOSED TREE

This commit is contained in:
Ciure Andrei 2019-11-25 06:24:28 +02:00
Родитель f6ed797af7 96141919a9
Коммит 129962fb8c
16 изменённых файлов: 267 добавлений и 733 удалений

Просмотреть файл

@ -36,7 +36,7 @@ fn write_shaders(glsl_files: Vec<PathBuf>, shader_file_path: &Path) {
let mut hasher = Sha256::new();
let base = glsl.parent().unwrap();
assert!(base.is_dir());
ShaderSourceParser::new().parse(
parse_shader_source(
Cow::Owned(shader_source_from_file(&glsl)),
&|f| Cow::Owned(shader_source_from_file(&base.join(&format!("{}.glsl", f)))),
&mut |s| hasher.input(s.as_bytes()),

Просмотреть файл

@ -46,52 +46,10 @@
/// other brush types don't use it.
///
#ifdef WR_FEATURE_MULTI_BRUSH
flat varying int v_brush_kind;
#endif
// A few varying slots for the brushes to use.
// Using these instead of adding dedicated varyings avoids using a high
// number of varyings in the multi-brush shader.
flat varying vec4 flat_varying_vec4_0;
flat varying vec4 flat_varying_vec4_1;
flat varying vec4 flat_varying_vec4_2;
flat varying vec4 flat_varying_vec4_3;
flat varying vec4 flat_varying_vec4_4;
flat varying ivec4 flat_varying_ivec4_0;
varying vec4 varying_vec4_0;
varying vec4 varying_vec4_1;
flat varying HIGHP_FS_ADDRESS int flat_varying_highp_int_address_0;
#ifdef WR_VERTEX_SHADER
#define FWD_DECLARE_VS_FUNCTION(name) \
void name( \
VertexInfo vi, \
int prim_address, \
RectWithSize local_rect, \
RectWithSize segment_rect, \
ivec4 prim_user_data, \
int specific_resource_address, \
mat4 transform, \
PictureTask pic_task, \
int brush_flags, \
vec4 segment_data \
);
// Forward-declare all brush vertex entry points.
FWD_DECLARE_VS_FUNCTION(image_brush_vs)
FWD_DECLARE_VS_FUNCTION(solid_brush_vs)
FWD_DECLARE_VS_FUNCTION(blend_brush_vs)
FWD_DECLARE_VS_FUNCTION(mix_blend_brush_vs)
FWD_DECLARE_VS_FUNCTION(linear_gradient_brush_vs)
FWD_DECLARE_VS_FUNCTION(radial_gradient_brush_vs)
FWD_DECLARE_VS_FUNCTION(yuv_brush_vs)
void multi_brush_vs(
void brush_vs(
VertexInfo vi,
int prim_address,
RectWithSize local_rect,
@ -101,8 +59,7 @@ void multi_brush_vs(
mat4 transform,
PictureTask pic_task,
int brush_flags,
vec4 texel_rect,
int brush_kind
vec4 segment_data
);
#define VECS_PER_SEGMENT 2
@ -115,12 +72,6 @@ void multi_brush_vs(
#define INVALID_SEGMENT_INDEX 0xffff
#ifndef WR_FEATURE_MULTI_BRUSH
int vecs_per_brush(int brush_kind) {
return VECS_PER_SPECIFIC_BRUSH;
}
#endif
void main(void) {
// Load the brush instance from vertex attributes.
Instance instance = decode_instance_attributes();
@ -136,7 +87,7 @@ void main(void) {
segment_data = vec4(0.0);
} else {
int segment_address = ph.specific_prim_address +
vecs_per_brush(instance.brush_kind) +
VECS_PER_SPECIFIC_BRUSH +
instance.segment_index * VECS_PER_SEGMENT;
vec4[2] segment_info = fetch_from_gpu_cache_2(segment_address);
@ -201,38 +152,19 @@ void main(void) {
#endif
// Run the specific brush VS code to write interpolators.
#ifdef WR_FEATURE_MULTI_BRUSH
v_brush_kind = instance.brush_kind;
multi_brush_vs(
brush_vs(
vi,
ph.specific_prim_address,
ph.local_rect,
segment_rect,
ph.user_data,
instance.resource_address,
transform.m,
pic_task,
brush_flags,
segment_data,
instance.brush_kind
);
#else
WR_BRUSH_VS_FUNCTION(
vi,
ph.specific_prim_address,
ph.local_rect,
segment_rect,
ph.user_data,
instance.resource_address,
instance.user_data,
transform.m,
pic_task,
brush_flags,
segment_data
);
#endif
}
#endif
#ifdef WR_FRAGMENT_SHADER
@ -244,28 +176,14 @@ struct Fragment {
#endif
};
// Foward-declare all brush entry-points.
Fragment image_brush_fs();
Fragment solid_brush_fs();
Fragment blend_brush_fs();
Fragment mix_blend_brush_fs();
Fragment linear_gradient_brush_fs();
Fragment radial_gradient_brush_fs();
Fragment yuv_brush_fs();
Fragment multi_brush_fs(int brush_kind);
Fragment brush_fs();
void main(void) {
#ifdef WR_FEATURE_DEBUG_OVERDRAW
oFragColor = WR_DEBUG_OVERDRAW_COLOR;
#else
// Run the specific brush FS code to output the color.
#ifdef WR_FEATURE_MULTI_BRUSH
Fragment frag = multi_brush_fs(v_brush_kind);
#else
Fragment frag = WR_BRUSH_FS_FUNCTION();
#endif
Fragment frag = brush_fs();
#ifdef WR_FEATURE_ALPHA_PASS
// Apply the clip mask

Просмотреть файл

@ -2,11 +2,7 @@
* 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/. */
#define VECS_PER_BLEND_BRUSH 3
#define VECS_PER_SPECIFIC_BRUSH VECS_PER_BLEND_BRUSH
#define WR_BRUSH_VS_FUNCTION blend_brush_vs
#define WR_BRUSH_FS_FUNCTION blend_brush_fs
#define VECS_PER_SPECIFIC_BRUSH 3
#define COMPONENT_TRANSFER_IDENTITY 0
#define COMPONENT_TRANSFER_TABLE 1
@ -17,32 +13,23 @@
#include shared,prim_shared,brush
// Interpolated UV coordinates to sample.
#define V_UV varying_vec4_0.zw
#define V_LOCAL_POS varying_vec4_0.xy
#define V_FLOOD_COLOR flat_varying_vec4_1
// Normalized bounds of the source image in the texture.
#define V_UV_BOUNDS flat_varying_vec4_2
#define V_COLOR_OFFSET flat_varying_vec4_3.xyz
#define V_AMOUNT flat_varying_vec4_3.w
// Layer index to sample.
#define V_LAYER flat_varying_vec4_4.x
// Flag to allow perspective interpolation of UV.
#define V_PERSPECTIVE flat_varying_vec4_4.y
#define V_OP flat_varying_ivec4_0.x
#define V_TABLE_ADDRESS flat_varying_ivec4_0.y
varying vec2 vUv;
varying vec2 vLocalPos;
// X = layer index to sample, Y = flag to allow perspective interpolation of UV.
flat varying vec2 vLayerAndPerspective;
flat varying float vAmount;
flat varying int vOp;
flat varying mat3 vColorMat;
flat varying vec3 vColorOffset;
flat varying vec4 vUvClipBounds;
flat varying int vTableAddress;
flat varying int vFuncs[4];
flat varying vec4 vFloodColor;
#ifdef WR_VERTEX_SHADER
void blend_brush_vs(
void brush_vs(
VertexInfo vi,
int prim_address,
RectWithSize local_rect,
@ -64,14 +51,10 @@ void blend_brush_vs(
vec2 uv = mix(uv0, uv1, f);
float perspective_interpolate = (brush_flags & BRUSH_FLAG_PERSPECTIVE_INTERPOLATION) != 0 ? 1.0 : 0.0;
V_UV = uv / texture_size * mix(vi.world_pos.w, 1.0, perspective_interpolate);
V_LAYER = res.layer;
V_PERSPECTIVE = perspective_interpolate;
// TODO: The image shader treats this differently: deflate the rect by half a pixel on each side and
// clamp the uv in the frame shader. Does it make sense to do the same here?
V_UV_BOUNDS = vec4(uv0, uv1) / texture_size.xyxy;
V_LOCAL_POS = vi.local_pos;
vUv = uv / texture_size * mix(vi.world_pos.w, 1.0, perspective_interpolate);
vLayerAndPerspective = vec2(res.layer, perspective_interpolate);
vUvClipBounds = vec4(uv0, uv1) / texture_size.xyxy;
vLocalPos = vi.local_pos;
float lumR = 0.2126;
float lumG = 0.7152;
@ -83,8 +66,8 @@ void blend_brush_vs(
float amount = float(prim_user_data.z) / 65536.0;
float invAmount = 1.0 - amount;
V_OP = prim_user_data.y & 0xffff;
V_AMOUNT = amount;
vOp = prim_user_data.y & 0xffff;
vAmount = amount;
// This assignment is only used for component transfer filters but this
// assignment has to be done here and not in the component transfer case
@ -98,7 +81,7 @@ void blend_brush_vs(
vFuncs[2] = (prim_user_data.y >> 20) & 0xf; // B
vFuncs[3] = (prim_user_data.y >> 16) & 0xf; // A
switch (V_OP) {
switch (vOp) {
case 2: {
// Grayscale
vColorMat = mat3(
@ -106,7 +89,7 @@ void blend_brush_vs(
vec3(lumG - lumG * invAmount, lumG + oneMinusLumG * invAmount, lumG - lumG * invAmount),
vec3(lumB - lumB * invAmount, lumB - lumB * invAmount, lumB + oneMinusLumB * invAmount)
);
V_COLOR_OFFSET = vec3(0.0);
vColorOffset = vec3(0.0);
break;
}
case 3: {
@ -118,7 +101,7 @@ void blend_brush_vs(
vec3(lumG - lumG * c - lumG * s, lumG + oneMinusLumG * c + 0.140 * s, lumG - lumG * c + lumG * s),
vec3(lumB - lumB * c + oneMinusLumB * s, lumB - lumB * c - 0.283 * s, lumB + oneMinusLumB * c + lumB * s)
);
V_COLOR_OFFSET = vec3(0.0);
vColorOffset = vec3(0.0);
break;
}
case 5: {
@ -128,7 +111,7 @@ void blend_brush_vs(
vec3(invAmount * lumG, invAmount * lumG + amount, invAmount * lumG),
vec3(invAmount * lumB, invAmount * lumB, invAmount * lumB + amount)
);
V_COLOR_OFFSET = vec3(0.0);
vColorOffset = vec3(0.0);
break;
}
case 6: {
@ -138,7 +121,7 @@ void blend_brush_vs(
vec3(0.769 - 0.769 * invAmount, 0.686 + 0.314 * invAmount, 0.534 - 0.534 * invAmount),
vec3(0.189 - 0.189 * invAmount, 0.168 - 0.168 * invAmount, 0.131 + 0.869 * invAmount)
);
V_COLOR_OFFSET = vec3(0.0);
vColorOffset = vec3(0.0);
break;
}
case 10: {
@ -146,17 +129,17 @@ void blend_brush_vs(
vec4 mat_data[3] = fetch_from_gpu_cache_3(prim_user_data.z);
vec4 offset_data = fetch_from_gpu_cache_1(prim_user_data.z + 4);
vColorMat = mat3(mat_data[0].xyz, mat_data[1].xyz, mat_data[2].xyz);
V_COLOR_OFFSET = offset_data.rgb;
vColorOffset = offset_data.rgb;
break;
}
case 13: {
// Component Transfer
V_TABLE_ADDRESS = prim_user_data.z;
vTableAddress = prim_user_data.z;
break;
}
case 14: {
// Flood
V_FLOOD_COLOR = fetch_from_gpu_cache_1(prim_user_data.z);
vFloodColor = fetch_from_gpu_cache_1(prim_user_data.z);
break;
}
default: break;
@ -224,7 +207,7 @@ vec4 ComponentTransfer(vec4 colora) {
case COMPONENT_TRANSFER_DISCRETE: {
// fetch value from lookup table
k = int(floor(colora[i]*255.0));
texel = fetch_from_gpu_cache_1(V_TABLE_ADDRESS + offset + k/4);
texel = fetch_from_gpu_cache_1(vTableAddress + offset + k/4);
colora[i] = clamp(texel[k % 4], 0.0, 1.0);
// offset plus 256/4 blocks
offset = offset + 64;
@ -232,7 +215,7 @@ vec4 ComponentTransfer(vec4 colora) {
}
case COMPONENT_TRANSFER_LINEAR: {
// fetch the two values for use in the linear equation
texel = fetch_from_gpu_cache_1(V_TABLE_ADDRESS + offset);
texel = fetch_from_gpu_cache_1(vTableAddress + offset);
colora[i] = clamp(texel[0] * colora[i] + texel[1], 0.0, 1.0);
// offset plus 1 block
offset = offset + 1;
@ -240,7 +223,7 @@ vec4 ComponentTransfer(vec4 colora) {
}
case COMPONENT_TRANSFER_GAMMA: {
// fetch the three values for use in the gamma equation
texel = fetch_from_gpu_cache_1(V_TABLE_ADDRESS + offset);
texel = fetch_from_gpu_cache_1(vTableAddress + offset);
colora[i] = clamp(texel[0] * pow(colora[i], texel[1]) + texel[2], 0.0, 1.0);
// offset plus 1 block
offset = offset + 1;
@ -254,29 +237,29 @@ vec4 ComponentTransfer(vec4 colora) {
return colora;
}
Fragment blend_brush_fs() {
float perspective_divisor = mix(gl_FragCoord.w, 1.0, V_PERSPECTIVE);
vec2 uv = V_UV * perspective_divisor;
vec4 Cs = texture(sColor0, vec3(uv, V_LAYER));
Fragment brush_fs() {
float perspective_divisor = mix(gl_FragCoord.w, 1.0, vLayerAndPerspective.y);
vec2 uv = vUv * perspective_divisor;
vec4 Cs = texture(sColor0, vec3(uv, vLayerAndPerspective.x));
// Un-premultiply the input.
float alpha = Cs.a;
vec3 color = alpha != 0.0 ? Cs.rgb / alpha : Cs.rgb;
switch (V_OP) {
switch (vOp) {
case 0:
break;
case 1:
color = Contrast(color, V_AMOUNT);
color = Contrast(color, vAmount);
break;
case 4:
color = Invert(color, V_AMOUNT);
color = Invert(color, vAmount);
break;
case 7:
color = Brightness(color, V_AMOUNT);
color = Brightness(color, vAmount);
break;
case 8: // Opacity
alpha *= V_AMOUNT;
alpha *= vAmount;
break;
case 11:
color = SrgbToLinear(color);
@ -294,31 +277,19 @@ Fragment blend_brush_fs() {
break;
}
case 14: // Flood
color = V_FLOOD_COLOR.rgb;
alpha = V_FLOOD_COLOR.a;
color = vFloodColor.rgb;
alpha = vFloodColor.a;
break;
default:
color = vColorMat * color + V_COLOR_OFFSET;
color = vColorMat * color + vColorOffset;
}
// Fail-safe to ensure that we don't sample outside the rendered
// portion of a blend source.
alpha *= min(point_inside_rect(uv, V_UV_BOUNDS.xy, V_UV_BOUNDS.zw),
init_transform_fs(V_LOCAL_POS));
alpha *= min(point_inside_rect(uv, vUvClipBounds.xy, vUvClipBounds.zw),
init_transform_fs(vLocalPos));
// Pre-multiply the alpha into the output value.
return Fragment(alpha * vec4(color, 1.0));
}
#endif
// Undef macro names that could be re-defined by other shaders.
#undef V_UV
#undef V_LOCAL_POS
#undef V_FLOOD_COLOR
#undef V_UV_BOUNDS
#undef V_COLOR_OFFSET
#undef V_AMOUNT
#undef V_LAYER
#undef V_PERSPECTIVE
#undef V_OP
#undef V_TABLE_ADDRESS

Просмотреть файл

@ -2,36 +2,29 @@
* 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/. */
#define VECS_PER_IMAGE_BRUSH 3
#define VECS_PER_SPECIFIC_BRUSH VECS_PER_IMAGE_BRUSH
#define WR_BRUSH_VS_FUNCTION image_brush_vs
#define WR_BRUSH_FS_FUNCTION image_brush_fs
#define VECS_PER_SPECIFIC_BRUSH 3
#include shared,prim_shared,brush
#ifdef WR_FEATURE_ALPHA_PASS
#define V_LOCAL_POS varying_vec4_0.xy
varying vec2 vLocalPos;
#endif
// Interpolated UV coordinates to sample.
#define V_UV varying_vec4_0.zw
#ifdef WR_FEATURE_ALPHA_PASS
#define V_COLOR flat_varying_vec4_0
#define V_MASK_SWIZZLE flat_varying_vec4_1.xy
#define V_TILE_REPEAT flat_varying_vec4_1.zw
#endif
varying vec2 vUv;
// X = layer index to sample, Y = flag to allow perspective interpolation of UV.
flat varying vec2 vLayerAndPerspective;
// Normalized bounds of the source image in the texture.
#define V_UV_BOUNDS flat_varying_vec4_2
flat varying vec4 vUvBounds;
// Normalized bounds of the source image in the texture, adjusted to avoid
// sampling artifacts.
#define V_UV_SAMPLE_BOUNDS flat_varying_vec4_3
// Layer index to sample.
#define V_LAYER flat_varying_vec4_4.x
// Flag to allow perspective interpolation of UV.
#define V_PERSPECTIVE flat_varying_vec4_4.y
flat varying vec4 vUvSampleBounds;
#ifdef WR_FEATURE_ALPHA_PASS
flat varying vec4 vColor;
flat varying vec2 vMaskSwizzle;
flat varying vec2 vTileRepeat;
#endif
#ifdef WR_VERTEX_SHADER
@ -55,7 +48,7 @@ ImageBrushData fetch_image_data(int address) {
return data;
}
void image_brush_vs(
void brush_vs(
VertexInfo vi,
int prim_address,
RectWithSize prim_rect,
@ -115,15 +108,14 @@ void image_brush_vs(
}
float perspective_interpolate = (brush_flags & BRUSH_FLAG_PERSPECTIVE_INTERPOLATION) != 0 ? 1.0 : 0.0;
V_LAYER = res.layer;
V_PERSPECTIVE = perspective_interpolate;
vLayerAndPerspective = vec2(res.layer, perspective_interpolate);
// Handle case where the UV coords are inverted (e.g. from an
// external image).
vec2 min_uv = min(uv0, uv1);
vec2 max_uv = max(uv0, uv1);
V_UV_SAMPLE_BOUNDS = vec4(
vUvSampleBounds = vec4(
min_uv + vec2(0.5),
max_uv - vec2(0.5)
) / texture_size.xyxy;
@ -155,23 +147,23 @@ void image_brush_vs(
}
#endif
// Offset and scale V_UV here to avoid doing it in the fragment shader.
// Offset and scale vUv here to avoid doing it in the fragment shader.
vec2 repeat = local_rect.size / stretch_size;
V_UV = mix(uv0, uv1, f) - min_uv;
V_UV /= texture_size;
V_UV *= repeat.xy;
vUv = mix(uv0, uv1, f) - min_uv;
vUv /= texture_size;
vUv *= repeat.xy;
if (perspective_interpolate == 0.0) {
V_UV *= vi.world_pos.w;
vUv *= vi.world_pos.w;
}
#ifdef WR_FEATURE_TEXTURE_RECT
V_UV_BOUNDS = vec4(0.0, 0.0, vec2(textureSize(sColor0)));
vUvBounds = vec4(0.0, 0.0, vec2(textureSize(sColor0)));
#else
V_UV_BOUNDS = vec4(min_uv, max_uv) / texture_size.xyxy;
vUvBounds = vec4(min_uv, max_uv) / texture_size.xyxy;
#endif
#ifdef WR_FEATURE_ALPHA_PASS
V_TILE_REPEAT = repeat.xy;
vTileRepeat = repeat.xy;
float opacity = float(prim_user_data.z) / 65535.0;
switch (blend_mode) {
@ -187,31 +179,31 @@ void image_brush_vs(
switch (color_mode) {
case COLOR_MODE_ALPHA:
case COLOR_MODE_BITMAP:
V_MASK_SWIZZLE = vec2(0.0, 1.0);
V_COLOR = image_data.color;
vMaskSwizzle = vec2(0.0, 1.0);
vColor = image_data.color;
break;
case COLOR_MODE_SUBPX_BG_PASS2:
case COLOR_MODE_SUBPX_DUAL_SOURCE:
case COLOR_MODE_IMAGE:
V_MASK_SWIZZLE = vec2(1.0, 0.0);
V_COLOR = image_data.color;
vMaskSwizzle = vec2(1.0, 0.0);
vColor = image_data.color;
break;
case COLOR_MODE_SUBPX_CONST_COLOR:
case COLOR_MODE_SUBPX_BG_PASS0:
case COLOR_MODE_COLOR_BITMAP:
V_MASK_SWIZZLE = vec2(1.0, 0.0);
V_COLOR = vec4(image_data.color.a);
vMaskSwizzle = vec2(1.0, 0.0);
vColor = vec4(image_data.color.a);
break;
case COLOR_MODE_SUBPX_BG_PASS1:
V_MASK_SWIZZLE = vec2(-1.0, 1.0);
V_COLOR = vec4(image_data.color.a) * image_data.background_color;
vMaskSwizzle = vec2(-1.0, 1.0);
vColor = vec4(image_data.color.a) * image_data.background_color;
break;
default:
V_MASK_SWIZZLE = vec2(0.0);
V_COLOR = vec4(1.0);
vMaskSwizzle = vec2(0.0);
vColor = vec4(1.0);
}
V_LOCAL_POS = vi.local_pos;
vLocalPos = vi.local_pos;
#endif
}
#endif
@ -219,62 +211,62 @@ void image_brush_vs(
#ifdef WR_FRAGMENT_SHADER
vec2 compute_repeated_uvs(float perspective_divisor) {
vec2 uv_size = V_UV_BOUNDS.zw - V_UV_BOUNDS.xy;
vec2 uv_size = vUvBounds.zw - vUvBounds.xy;
#ifdef WR_FEATURE_ALPHA_PASS
// This prevents the uv on the top and left parts of the primitive that was inflated
// for anti-aliasing purposes from going beyound the range covered by the regular
// (non-inflated) primitive.
vec2 local_uv = max(V_UV * perspective_divisor, vec2(0.0));
vec2 local_uv = max(vUv * perspective_divisor, vec2(0.0));
// Handle horizontal and vertical repetitions.
vec2 repeated_uv = mod(local_uv, uv_size) + V_UV_BOUNDS.xy;
vec2 repeated_uv = mod(local_uv, uv_size) + vUvBounds.xy;
// This takes care of the bottom and right inflated parts.
// We do it after the modulo because the latter wraps around the values exactly on
// the right and bottom edges, which we do not want.
if (local_uv.x >= V_TILE_REPEAT.x * uv_size.x) {
repeated_uv.x = V_UV_BOUNDS.z;
if (local_uv.x >= vTileRepeat.x * uv_size.x) {
repeated_uv.x = vUvBounds.z;
}
if (local_uv.y >= V_TILE_REPEAT.y * uv_size.y) {
repeated_uv.y = V_UV_BOUNDS.w;
if (local_uv.y >= vTileRepeat.y * uv_size.y) {
repeated_uv.y = vUvBounds.w;
}
#else
vec2 repeated_uv = mod(V_UV * perspective_divisor, uv_size) + V_UV_BOUNDS.xy;
vec2 repeated_uv = mod(vUv * perspective_divisor, uv_size) + vUvBounds.xy;
#endif
return repeated_uv;
}
Fragment image_brush_fs() {
float perspective_divisor = mix(gl_FragCoord.w, 1.0, V_PERSPECTIVE);
Fragment brush_fs() {
float perspective_divisor = mix(gl_FragCoord.w, 1.0, vLayerAndPerspective.y);
#ifdef WR_FEATURE_REPETITION
vec2 repeated_uv = compute_repeated_uvs(perspective_divisor);
#else
vec2 repeated_uv = V_UV * perspective_divisor + V_UV_BOUNDS.xy;
vec2 repeated_uv = vUv * perspective_divisor + vUvBounds.xy;
#endif
// Clamp the uvs to avoid sampling artifacts.
vec2 uv = clamp(repeated_uv, V_UV_SAMPLE_BOUNDS.xy, V_UV_SAMPLE_BOUNDS.zw);
vec2 uv = clamp(repeated_uv, vUvSampleBounds.xy, vUvSampleBounds.zw);
vec4 texel = TEX_SAMPLE(sColor0, vec3(uv, V_LAYER));
vec4 texel = TEX_SAMPLE(sColor0, vec3(uv, vLayerAndPerspective.x));
Fragment frag;
#ifdef WR_FEATURE_ALPHA_PASS
#ifdef WR_FEATURE_ANTIALIASING
float alpha = init_transform_fs(V_LOCAL_POS);
float alpha = init_transform_fs(vLocalPos);
#else
float alpha = 1.0;
#endif
texel.rgb = texel.rgb * V_MASK_SWIZZLE.x + texel.aaa * V_MASK_SWIZZLE.y;
texel.rgb = texel.rgb * vMaskSwizzle.x + texel.aaa * vMaskSwizzle.y;
vec4 alpha_mask = texel * alpha;
frag.color = V_COLOR * alpha_mask;
frag.color = vColor * alpha_mask;
#ifdef WR_FEATURE_DUAL_SOURCE_BLENDING
frag.blend = alpha_mask * V_COLOR.a;
frag.blend = alpha_mask * vColor.a;
#endif
#else
frag.color = texel;
@ -283,14 +275,3 @@ Fragment image_brush_fs() {
return frag;
}
#endif
// Undef macro names that could be re-defined by other shaders.
#undef V_LOCAL_POS
#undef V_UV
#undef V_COLOR
#undef V_MASK_SWIZZLE
#undef V_TILE_REPEAT
#undef V_UV_BOUNDS
#undef V_UV_SAMPLE_BOUNDS
#undef V_LAYER
#undef V_PERSPECTIVE

Просмотреть файл

@ -2,30 +2,25 @@
* 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/. */
#define VECS_PER_LINEAR_GRADIENT_BRUSH 2
#define VECS_PER_SPECIFIC_BRUSH VECS_PER_LINEAR_GRADIENT_BRUSH
#define WR_BRUSH_VS_FUNCTION linear_gradient_brush_vs
#define WR_BRUSH_FS_FUNCTION linear_gradient_brush_fs
#define VECS_PER_SPECIFIC_BRUSH 2
#include shared,prim_shared,brush
#define V_GRADIENT_ADDRESS flat_varying_highp_int_address_0
flat varying HIGHP_FS_ADDRESS int vGradientAddress;
flat varying float vGradientRepeat;
#define V_START_POINT flat_varying_vec4_0.xy
#define V_SCALE_DIR flat_varying_vec4_0.zw
flat varying vec2 vScaledDir;
flat varying vec2 vStartPoint;
// Size of the gradient pattern's rectangle, used to compute horizontal and vertical
// repetitions. Not to be confused with another kind of repetition of the pattern
// which happens along the gradient stops.
#define V_REPEATED_SIZE flat_varying_vec4_1.xy
// Repetition along the gradient stops.
#define V_GRADIENT_REPEAT flat_varying_vec4_1.z
flat varying vec2 vRepeatedSize;
#define V_POS varying_vec4_0.zw
varying vec2 vPos;
#ifdef WR_FEATURE_ALPHA_PASS
#define V_LOCAL_POS varying_vec4_0.xy
#define V_TILE_REPEAT flat_varying_vec4_2.xy
varying vec2 vLocalPos;
flat varying vec2 vTileRepeat;
#endif
#ifdef WR_VERTEX_SHADER
@ -45,7 +40,7 @@ Gradient fetch_gradient(int address) {
);
}
void linear_gradient_brush_vs(
void brush_vs(
VertexInfo vi,
int prim_address,
RectWithSize local_rect,
@ -60,78 +55,68 @@ void linear_gradient_brush_vs(
Gradient gradient = fetch_gradient(prim_address);
if ((brush_flags & BRUSH_FLAG_SEGMENT_RELATIVE) != 0) {
V_POS = (vi.local_pos - segment_rect.p0) / segment_rect.size;
V_POS = V_POS * (texel_rect.zw - texel_rect.xy) + texel_rect.xy;
V_POS = V_POS * local_rect.size;
vPos = (vi.local_pos - segment_rect.p0) / segment_rect.size;
vPos = vPos * (texel_rect.zw - texel_rect.xy) + texel_rect.xy;
vPos = vPos * local_rect.size;
} else {
V_POS = vi.local_pos - local_rect.p0;
vPos = vi.local_pos - local_rect.p0;
}
vec2 start_point = gradient.start_end_point.xy;
vec2 end_point = gradient.start_end_point.zw;
vec2 dir = end_point - start_point;
V_START_POINT = start_point;
V_SCALE_DIR = dir / dot(dir, dir);
vStartPoint = start_point;
vScaledDir = dir / dot(dir, dir);
vec2 tile_repeat = local_rect.size / gradient.stretch_size;
V_REPEATED_SIZE = gradient.stretch_size;
vRepeatedSize = gradient.stretch_size;
V_GRADIENT_ADDRESS = prim_user_data.x;
vGradientAddress = prim_user_data.x;
// Whether to repeat the gradient along the line instead of clamping.
V_GRADIENT_REPEAT = float(gradient.extend_mode != EXTEND_MODE_CLAMP);
vGradientRepeat = float(gradient.extend_mode != EXTEND_MODE_CLAMP);
#ifdef WR_FEATURE_ALPHA_PASS
V_TILE_REPEAT = tile_repeat;
V_LOCAL_POS = vi.local_pos;
vTileRepeat = tile_repeat;
vLocalPos = vi.local_pos;
#endif
}
#endif
#ifdef WR_FRAGMENT_SHADER
Fragment linear_gradient_brush_fs() {
Fragment brush_fs() {
#ifdef WR_FEATURE_ALPHA_PASS
// Handle top and left inflated edges (see brush_image).
vec2 local_pos = max(V_POS, vec2(0.0));
vec2 local_pos = max(vPos, vec2(0.0));
// Apply potential horizontal and vertical repetitions.
vec2 pos = mod(local_pos, V_REPEATED_SIZE);
vec2 pos = mod(local_pos, vRepeatedSize);
vec2 prim_size = V_REPEATED_SIZE * V_TILE_REPEAT;
vec2 prim_size = vRepeatedSize * vTileRepeat;
// Handle bottom and right inflated edges (see brush_image).
if (local_pos.x >= prim_size.x) {
pos.x = V_REPEATED_SIZE.x;
pos.x = vRepeatedSize.x;
}
if (local_pos.y >= prim_size.y) {
pos.y = V_REPEATED_SIZE.y;
pos.y = vRepeatedSize.y;
}
#else
// Apply potential horizontal and vertical repetitions.
vec2 pos = mod(V_POS, V_REPEATED_SIZE);
vec2 pos = mod(vPos, vRepeatedSize);
#endif
float offset = dot(pos - V_START_POINT, V_SCALE_DIR);
float offset = dot(pos - vStartPoint, vScaledDir);
vec4 color = sample_gradient(V_GRADIENT_ADDRESS,
vec4 color = sample_gradient(vGradientAddress,
offset,
V_GRADIENT_REPEAT);
vGradientRepeat);
#ifdef WR_FEATURE_ALPHA_PASS
color *= init_transform_fs(V_LOCAL_POS);
color *= init_transform_fs(vLocalPos);
#endif
return Fragment(color);
}
#endif
// Undef macro names that could be re-defined by other shaders.
#undef V_GRADIENT_ADDRESS
#undef V_START_POINT
#undef V_SCALE_DIR
#undef V_REPEATED_SIZE
#undef V_GRADIENT_REPEAT
#undef V_POS
#undef V_LOCAL_POS
#undef V_TILE_REPEAT

Просмотреть файл

@ -2,21 +2,13 @@
* 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/. */
#define VECS_PER_MIX_BLEND_BRUSH 3
#define VECS_PER_SPECIFIC_BRUSH VECS_PER_MIX_BLEND_BRUSH
#define WR_BRUSH_VS_FUNCTION mix_blend_brush_vs
#define WR_BRUSH_FS_FUNCTION mix_blend_brush_fs
#define VECS_PER_SPECIFIC_BRUSH 3
#include shared,prim_shared,brush
#define V_SRC_UV varying_vec4_0.xy
#define V_SRC_LAYER varying_vec4_0.w
#define V_BACKDROP_UV varying_vec4_1.xy
#define V_BACKDROP_LAYER varying_vec4_1.w
#define V_OP flat_varying_ivec4_0.x
varying vec3 vSrcUv;
varying vec3 vBackdropUv;
flat varying int vOp;
#ifdef WR_VERTEX_SHADER
@ -25,7 +17,7 @@ vec2 snap_device_pos(VertexInfo vi, float device_pixel_scale) {
return vi.world_pos.xy * device_pixel_scale / max(0.0, vi.world_pos.w) + vi.snap_offset;
}
void mix_blend_brush_vs(
void brush_vs(
VertexInfo vi,
int prim_address,
RectWithSize local_rect,
@ -39,21 +31,19 @@ void mix_blend_brush_vs(
) {
vec2 snapped_device_pos = snap_device_pos(vi, pic_task.device_pixel_scale);
vec2 texture_size = vec2(textureSize(sPrevPassColor, 0));
V_OP = prim_user_data.x;
vOp = prim_user_data.x;
PictureTask src_task = fetch_picture_task(prim_user_data.z);
vec2 src_uv = snapped_device_pos +
src_task.common_data.task_rect.p0 -
src_task.content_origin;
V_SRC_UV = src_uv / texture_size;
V_SRC_LAYER = src_task.common_data.texture_layer_index;
vSrcUv = vec3(src_uv / texture_size, src_task.common_data.texture_layer_index);
RenderTaskCommonData backdrop_task = fetch_render_task_common_data(prim_user_data.y);
vec2 backdrop_uv = snapped_device_pos +
backdrop_task.task_rect.p0 -
src_task.content_origin;
V_BACKDROP_UV = backdrop_uv / texture_size;
V_BACKDROP_LAYER = backdrop_task.texture_layer_index;
vBackdropUv = vec3(backdrop_uv / texture_size, backdrop_task.texture_layer_index);
}
#endif
@ -215,9 +205,9 @@ const int MixBlendMode_Saturation = 13;
const int MixBlendMode_Color = 14;
const int MixBlendMode_Luminosity = 15;
Fragment mix_blend_brush_fs() {
vec4 Cb = textureLod(sPrevPassColor, vec3(V_BACKDROP_UV, V_BACKDROP_LAYER), 0.0);
vec4 Cs = textureLod(sPrevPassColor, vec3(V_SRC_UV, V_SRC_LAYER), 0.0);
Fragment brush_fs() {
vec4 Cb = textureLod(sPrevPassColor, vBackdropUv, 0.0);
vec4 Cs = textureLod(sPrevPassColor, vSrcUv, 0.0);
// The mix-blend-mode functions assume no premultiplied alpha
if (Cb.a != 0.0) {
@ -231,7 +221,7 @@ Fragment mix_blend_brush_fs() {
// Return yellow if none of the branches match (shouldn't happen).
vec4 result = vec4(1.0, 1.0, 0.0, 1.0);
switch (V_OP) {
switch (vOp) {
case MixBlendMode_Multiply:
result.rgb = Multiply(Cb.rgb, Cs.rgb);
break;
@ -295,10 +285,3 @@ Fragment mix_blend_brush_fs() {
return Fragment(result);
}
#endif
// Undef macro names that could be re-defined by other shaders.
#undef V_SRC_UV
#undef V_SRC_LAYER
#undef V_BACKDROP_UV
#undef V_BACKDROP_LAYER
#undef V_OP

Просмотреть файл

@ -1,199 +0,0 @@
/* 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/. */
// The multi-brush shader is capable of rendering most types of brushes
// if they are enabled via WR_FEATURE_*_BRUSH defines.
// This type of uber-shader comes at a cost so the goal for this is to
// provide opportunities for aggressive batching when the number of draw
// calls so high that reducing the number of draw calls is worth the
// cost of this "über-shader".
#define WR_FEATURE_MULTI_BRUSH
// These constants must match the BrushShaderKind enum in gpu_types.rs.
#define BRUSH_KIND_SOLID 1
#define BRUSH_KIND_IMAGE 2
#define BRUSH_KIND_TEXT 3
#define BRUSH_KIND_LINEAR_GRADIENT 4
#define BRUSH_KIND_RADIAL_GRADIENT 5
#define BRUSH_KIND_BLEND 6
#define BRUSH_KIND_MIX_BLEND 7
#define BRUSH_KIND_YV 8
int vecs_per_brush(int brush_kind);
#include shared,prim_shared,brush
#ifdef WR_FEATURE_IMAGE_BRUSH
#include brush_image
#endif
#undef VECS_PER_SPECIFIC_BRUSH
#undef WR_BRUSH_VS_FUNCTION
#undef WR_BRUSH_FS_FUNCTION
#ifdef WR_FEATURE_SOLID_BRUSH
#include brush_solid
#endif
#undef VECS_PER_SPECIFIC_BRUSH
#undef WR_BRUSH_VS_FUNCTION
#undef WR_BRUSH_FS_FUNCTION
#ifdef WR_FEATURE_BLEND_BRUSH
#include brush_blend
#endif
#undef VECS_PER_SPECIFIC_BRUSH
#undef WR_BRUSH_VS_FUNCTION
#undef WR_BRUSH_FS_FUNCTION
#ifdef WR_FEATURE_MIX_BLEND_BRUSH
#include brush_mix_blend
#endif
#undef VECS_PER_SPECIFIC_BRUSH
#undef WR_BRUSH_VS_FUNCTION
#undef WR_BRUSH_FS_FUNCTION
#ifdef WR_FEATURE_LINEAR_GRADIENT_BRUSH
#include brush_linear_gradient
#endif
#undef VECS_PER_SPECIFIC_BRUSH
#undef WR_BRUSH_VS_FUNCTION
#undef WR_BRUSH_FS_FUNCTION
#ifdef WR_FEATURE_RADIAL_GRADIENT_BRUSH
#include brush_radial_gradient
#endif
int vecs_per_brush(int brush_kind) {
switch (brush_kind) {
// The default arm should never be taken, we let it point to whichever shader
// is enabled first to satisfy ANGLE validation.
default:
#ifdef WR_FEATURE_IMAGE_BRUSH
case BRUSH_KIND_IMAGE: return VECS_PER_IMAGE_BRUSH;
#endif
#ifdef WR_FEATURE_IMAGE_BRUSH
case BRUSH_KIND_SOLID: return VECS_PER_SOLID_BRUSH;
#endif
#ifdef WR_FEATURE_BLEND_BRUSH
case BRUSH_KIND_BLEND: return VECS_PER_BLEND_BRUSH;
#endif
#ifdef WR_FEATURE_MIX_BLEND_BRUSH
case BRUSH_KIND_MIX_BLEND: return VECS_PER_MIX_BLEND_BRUSH;
#endif
#ifdef WR_FEATURE_LINEAR_GRADIENT_BRUSH
case BRUSH_KIND_LINEAR_GRADIENT: return VECS_PER_LINEAR_GRADIENT_BRUSH;
#endif
#ifdef WR_FEATURE_RADIAL_GRADIENT_BRUSH
case BRUSH_KIND_RADIAL_GRADIENT: return VECS_PER_RADIAL_GRADIENT_BRUSH;
#endif
}
}
#define BRUSH_VS_PARAMS vi, prim_address, local_rect, segment_rect, \
prim_user_data, specific_resource_address, transform, pic_task, \
brush_flags, texel_rect
#ifdef WR_VERTEX_SHADER
void multi_brush_vs(
VertexInfo vi,
int prim_address,
RectWithSize local_rect,
RectWithSize segment_rect,
ivec4 prim_user_data,
int specific_resource_address,
mat4 transform,
PictureTask pic_task,
int brush_flags,
vec4 texel_rect,
int brush_kind
) {
switch (brush_kind) {
default:
#ifdef WR_FEATURE_IMAGE_BRUSH
case BRUSH_KIND_IMAGE:
image_brush_vs(BRUSH_VS_PARAMS);
break;
#endif
#ifdef WR_FEATURE_SOLID_BRUSH
case BRUSH_KIND_SOLID:
solid_brush_vs(BRUSH_VS_PARAMS);
break;
#endif
#ifdef WR_FEATURE_BLEND_BRUSH
case BRUSH_KIND_BLEND:
blend_brush_vs(BRUSH_VS_PARAMS);
break;
#endif
#ifdef WR_FEATURE_MIX_BLEND_BRUSH
case BRUSH_KIND_MIX_BLEND:
mix_blend_brush_vs(BRUSH_VS_PARAMS);
break;
#endif
#ifdef WR_FEATURE_LINEAR_GRADIENT_BRUSH
case BRUSH_KIND_LINEAR_GRADIENT:
linear_gradient_brush_vs(BRUSH_VS_PARAMS);
break;
#endif
#ifdef WR_FEATURE_RADIAL_GRADIENT_BRUSH
case BRUSH_KIND_RADIAL_GRADIENT:
radial_gradient_brush_vs(BRUSH_VS_PARAMS);
break;
#endif
}
}
#endif // WR_VERTEX_SHADER
#ifdef WR_FRAGMENT_SHADER
Fragment multi_brush_fs(int brush_kind) {
switch (brush_kind) {
default:
#ifdef WR_FEATURE_IMAGE_BRUSH
case BRUSH_KIND_IMAGE: return image_brush_fs();
#endif
#ifdef WR_FEATURE_SOLID_BRUSH
case BRUSH_KIND_SOLID: return solid_brush_fs();
#endif
#ifdef WR_FEATURE_BLEND_BRUSH
case BRUSH_KIND_BLEND: return blend_brush_fs();
#endif
#ifdef WR_FEATURE_MIX_BLEND_BRUSH
case BRUSH_KIND_MIX_BLEND: return mix_blend_brush_fs();
#endif
#ifdef WR_FEATURE_LINEAR_GRADIENT_BRUSH
case BRUSH_KIND_LINEAR_GRADIENT: return linear_gradient_brush_fs();
#endif
#ifdef WR_FEATURE_RADIAL_GRADIENT_BRUSH
case BRUSH_KIND_RADIAL_GRADIENT: return radial_gradient_brush_fs();
#endif
}
}
#endif

Просмотреть файл

@ -2,28 +2,23 @@
* 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/. */
#define VECS_PER_RADIAL_GRADIENT_BRUSH 2
#define VECS_PER_SPECIFIC_BRUSH VECS_PER_RADIAL_GRADIENT_BRUSH
#define WR_BRUSH_VS_FUNCTION radial_gradient_brush_vs
#define WR_BRUSH_FS_FUNCTION radial_gradient_brush_fs
#define VECS_PER_SPECIFIC_BRUSH 2
#include shared,prim_shared,brush
#define V_GRADIENT_ADDRESS flat_varying_highp_int_address_0
flat varying HIGHP_FS_ADDRESS int vGradientAddress;
flat varying float vGradientRepeat;
#define V_CENTER flat_varying_vec4_0.xy
#define V_START_RADIUS flat_varying_vec4_0.z
#define V_END_RADIUS flat_varying_vec4_0.w
flat varying vec2 vCenter;
flat varying float vStartRadius;
flat varying float vEndRadius;
#define V_REPEATED_SIZE flat_varying_vec4_1.xy
#define V_GRADIENT_REPEAT flat_varying_vec4_1.z
#define V_POS varying_vec4_0.zw
varying vec2 vPos;
flat varying vec2 vRepeatedSize;
#ifdef WR_FEATURE_ALPHA_PASS
#define V_LOCAL_POS varying_vec4_0.xy
#define V_TILE_REPEAT flat_varying_vec4_2.xy
varying vec2 vLocalPos;
flat varying vec2 vTileRepeat;
#endif
#ifdef WR_VERTEX_SHADER
@ -45,7 +40,7 @@ RadialGradient fetch_radial_gradient(int address) {
);
}
void radial_gradient_brush_vs(
void brush_vs(
VertexInfo vi,
int prim_address,
RectWithSize local_rect,
@ -60,68 +55,68 @@ void radial_gradient_brush_vs(
RadialGradient gradient = fetch_radial_gradient(prim_address);
if ((brush_flags & BRUSH_FLAG_SEGMENT_RELATIVE) != 0) {
V_POS = (vi.local_pos - segment_rect.p0) / segment_rect.size;
V_POS = V_POS * (texel_rect.zw - texel_rect.xy) + texel_rect.xy;
V_POS = V_POS * local_rect.size;
vPos = (vi.local_pos - segment_rect.p0) / segment_rect.size;
vPos = vPos * (texel_rect.zw - texel_rect.xy) + texel_rect.xy;
vPos = vPos * local_rect.size;
} else {
V_POS = vi.local_pos - local_rect.p0;
vPos = vi.local_pos - local_rect.p0;
}
V_CENTER = gradient.center_start_end_radius.xy;
V_START_RADIUS = gradient.center_start_end_radius.z;
V_END_RADIUS = gradient.center_start_end_radius.w;
vCenter = gradient.center_start_end_radius.xy;
vStartRadius = gradient.center_start_end_radius.z;
vEndRadius = gradient.center_start_end_radius.w;
// Transform all coordinates by the y scale so the
// fragment shader can work with circles
vec2 tile_repeat = local_rect.size / gradient.stretch_size;
V_POS.y *= gradient.ratio_xy;
V_CENTER.y *= gradient.ratio_xy;
V_REPEATED_SIZE = gradient.stretch_size;
V_REPEATED_SIZE.y *= gradient.ratio_xy;
vPos.y *= gradient.ratio_xy;
vCenter.y *= gradient.ratio_xy;
vRepeatedSize = gradient.stretch_size;
vRepeatedSize.y *= gradient.ratio_xy;
V_GRADIENT_ADDRESS = prim_user_data.x;
vGradientAddress = prim_user_data.x;
// Whether to repeat the gradient instead of clamping.
V_GRADIENT_REPEAT = float(gradient.extend_mode != EXTEND_MODE_CLAMP);
vGradientRepeat = float(gradient.extend_mode != EXTEND_MODE_CLAMP);
#ifdef WR_FEATURE_ALPHA_PASS
V_TILE_REPEAT = tile_repeat.xy;
V_LOCAL_POS = vi.local_pos;
vTileRepeat = tile_repeat.xy;
vLocalPos = vi.local_pos;
#endif
}
#endif
#ifdef WR_FRAGMENT_SHADER
Fragment radial_gradient_brush_fs() {
Fragment brush_fs() {
#ifdef WR_FEATURE_ALPHA_PASS
// Handle top and left inflated edges (see brush_image).
vec2 local_pos = max(V_POS, vec2(0.0));
vec2 local_pos = max(vPos, vec2(0.0));
// Apply potential horizontal and vertical repetitions.
vec2 pos = mod(local_pos, V_REPEATED_SIZE);
vec2 pos = mod(local_pos, vRepeatedSize);
vec2 prim_size = V_REPEATED_SIZE * V_TILE_REPEAT;
vec2 prim_size = vRepeatedSize * vTileRepeat;
// Handle bottom and right inflated edges (see brush_image).
if (local_pos.x >= prim_size.x) {
pos.x = V_REPEATED_SIZE.x;
pos.x = vRepeatedSize.x;
}
if (local_pos.y >= prim_size.y) {
pos.y = V_REPEATED_SIZE.y;
pos.y = vRepeatedSize.y;
}
#else
// Apply potential horizontal and vertical repetitions.
vec2 pos = mod(V_POS, V_REPEATED_SIZE);
vec2 pos = mod(vPos, vRepeatedSize);
#endif
vec2 pd = pos - V_CENTER;
float rd = V_END_RADIUS - V_START_RADIUS;
vec2 pd = pos - vCenter;
float rd = vEndRadius - vStartRadius;
// Solve for t in length(t - pd) = V_START_RADIUS + t * rd
// Solve for t in length(t - pd) = vStartRadius + t * rd
// using a quadratic equation in form of At^2 - 2Bt + C = 0
float A = -(rd * rd);
float B = V_START_RADIUS * rd;
float C = dot(pd, pd) - V_START_RADIUS * V_START_RADIUS;
float B = vStartRadius * rd;
float C = dot(pd, pd) - vStartRadius * vStartRadius;
float offset;
if (A == 0.0) {
@ -130,7 +125,7 @@ Fragment radial_gradient_brush_fs() {
discard;
}
float t = 0.5 * C / B;
if (V_START_RADIUS + rd * t >= 0.0) {
if (vStartRadius + rd * t >= 0.0) {
offset = t;
} else {
discard;
@ -143,34 +138,23 @@ Fragment radial_gradient_brush_fs() {
discr = sqrt(discr);
float t0 = (B + discr) / A;
float t1 = (B - discr) / A;
if (V_START_RADIUS + rd * t0 >= 0.0) {
if (vStartRadius + rd * t0 >= 0.0) {
offset = t0;
} else if (V_START_RADIUS + rd * t1 >= 0.0) {
} else if (vStartRadius + rd * t1 >= 0.0) {
offset = t1;
} else {
discard;
}
}
vec4 color = sample_gradient(V_GRADIENT_ADDRESS,
vec4 color = sample_gradient(vGradientAddress,
offset,
V_GRADIENT_REPEAT);
vGradientRepeat);
#ifdef WR_FEATURE_ALPHA_PASS
color *= init_transform_fs(V_LOCAL_POS);
color *= init_transform_fs(vLocalPos);
#endif
return Fragment(color);
}
#endif
// Undef macro names that could be re-defined by other shaders.
#undef V_GRADIENT_ADDRESS
#undef V_CENTER
#undef V_START_RADIUS
#undef V_END_RADIUS
#undef V_REPEATED_SIZE
#undef V_GRADIENT_REPEAT
#undef V_POS
#undef V_LOCAL_POS
#undef V_TILE_REPEAT

Просмотреть файл

@ -2,18 +2,14 @@
* 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/. */
#define VECS_PER_SOLID_BRUSH 1
#define VECS_PER_SPECIFIC_BRUSH VECS_PER_SOLID_BRUSH
#define WR_BRUSH_VS_FUNCTION solid_brush_vs
#define WR_BRUSH_FS_FUNCTION solid_brush_fs
#define VECS_PER_SPECIFIC_BRUSH 1
#include shared,prim_shared,brush
#define V_COLOR flat_varying_vec4_0
flat varying vec4 vColor;
#ifdef WR_FEATURE_ALPHA_PASS
#define V_LOCAL_POS varying_vec4_0.xy
varying vec2 vLocalPos;
#endif
#ifdef WR_VERTEX_SHADER
@ -27,7 +23,7 @@ SolidBrush fetch_solid_primitive(int address) {
return SolidBrush(data);
}
void solid_brush_vs(
void brush_vs(
VertexInfo vi,
int prim_address,
RectWithSize local_rect,
@ -42,24 +38,20 @@ void solid_brush_vs(
SolidBrush prim = fetch_solid_primitive(prim_address);
float opacity = float(prim_user_data.x) / 65535.0;
V_COLOR = prim.color * opacity;
vColor = prim.color * opacity;
#ifdef WR_FEATURE_ALPHA_PASS
V_LOCAL_POS = vi.local_pos;
vLocalPos = vi.local_pos;
#endif
}
#endif
#ifdef WR_FRAGMENT_SHADER
Fragment solid_brush_fs() {
vec4 color = V_COLOR;
Fragment brush_fs() {
vec4 color = vColor;
#ifdef WR_FEATURE_ALPHA_PASS
color *= init_transform_fs(V_LOCAL_POS);
color *= init_transform_fs(vLocalPos);
#endif
return Fragment(color);
}
#endif
// Undef macro names that could be re-defined by other shaders.
#undef V_COLOR
#undef V_LOCAL_POS

Просмотреть файл

@ -2,11 +2,7 @@
* 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/. */
#define VECS_PER_YUV_BRUSH 1
#define VECS_PER_SPECIFIC_BRUSH VECS_PER_YUV_BRUSH
#define WR_BRUSH_VS_FUNCTION yuv_brush_vs
#define WR_BRUSH_FS_FUNCTION yuv_brush_fs
#define VECS_PER_SPECIFIC_BRUSH 1
#include shared,prim_shared,brush
@ -124,7 +120,7 @@ YuvPrimitive fetch_yuv_primitive(int address) {
return YuvPrimitive(data.x, int(data.y), int(data.z));
}
void yuv_brush_vs(
void brush_vs(
VertexInfo vi,
int prim_address,
RectWithSize local_rect,
@ -169,7 +165,7 @@ void yuv_brush_vs(
#ifdef WR_FRAGMENT_SHADER
Fragment yuv_brush_fs() {
Fragment brush_fs() {
vec3 yuv_value;
if (vFormat == YUV_FORMAT_PLANAR) {

Просмотреть файл

@ -57,8 +57,7 @@ struct Instance
int clip_address;
int segment_index;
int flags;
int resource_address;
int brush_kind;
int user_data;
};
Instance decode_instance_attributes() {
@ -69,8 +68,7 @@ Instance decode_instance_attributes() {
instance.clip_address = aData.y & 0xffff;
instance.segment_index = aData.z & 0xffff;
instance.flags = aData.z & 0xffff0000;
instance.resource_address = aData.w & 0xffffff;
instance.brush_kind = aData.w >> 24;
instance.user_data = aData.w;
return instance;
}

Просмотреть файл

@ -4,30 +4,13 @@
#include shared,prim_shared
// A few varying slots for the brushes to use.
// Using these instead of adding dedicated varyings avoids using a high
// number of varyings in the multi-brush shader.
//
// TODO: This is duplicated from the brush shader code and will be merged
// back once text runs use the brush infrastructure.
flat varying vec4 flat_varying_vec4_0;
flat varying vec4 flat_varying_vec4_1;
flat varying vec4 flat_varying_vec4_2;
varying vec4 varying_vec4_0;
varying vec4 varying_vec4_1;
#define V_COLOR flat_varying_vec4_0
#define V_MASK_SWIZZLE flat_varying_vec4_1.xy
// Normalized bounds of the source image in the texture.
#define V_UV_BOUNDS flat_varying_vec4_2
// Interpolated UV coordinates to sample.
#define V_UV varying_vec4_0.xy
#define V_LAYER varying_vec4_0.z
flat varying vec4 vColor;
varying vec3 vUv;
flat varying vec4 vUvBorder;
flat varying vec2 vMaskSwizzle;
#ifdef WR_FEATURE_GLYPH_TRANSFORM
#define V_UV_CLIP varying_vec4_1
varying vec4 vUvClip;
#endif
#ifdef WR_VERTEX_SHADER
@ -195,6 +178,7 @@ void main(void) {
int glyph_index = instance.segment_index;
int subpx_dir = (instance.flags >> 24) & 0xff;
int color_mode = (instance.flags >> 16) & 0xff;
int resource_address = instance.user_data;
PrimitiveHeader ph = fetch_prim_header(instance.prim_header_address);
Transform transform = fetch_transform(ph.transform_id);
@ -211,7 +195,7 @@ void main(void) {
Glyph glyph = fetch_glyph(ph.specific_prim_address, glyph_index);
glyph.offset += ph.local_rect.p0 - text_offset;
GlyphResource res = fetch_glyph_resource(instance.resource_address);
GlyphResource res = fetch_glyph_resource(resource_address);
#ifdef WR_FEATURE_GLYPH_TRANSFORM
// Transform from local space to glyph space.
@ -273,7 +257,7 @@ void main(void) {
#ifdef WR_FEATURE_GLYPH_TRANSFORM
vec2 f = (glyph_transform * vi.local_pos - glyph_rect.p0) / glyph_rect.size;
V_UV_CLIP = vec4(f, 1.0 - f);
vUvClip = vec4(f, 1.0 - f);
#else
vec2 f = (vi.local_pos - glyph_rect.p0) / glyph_rect.size;
#endif
@ -283,58 +267,57 @@ void main(void) {
switch (color_mode) {
case COLOR_MODE_ALPHA:
case COLOR_MODE_BITMAP:
V_MASK_SWIZZLE = vec2(0.0, 1.0);
V_COLOR = text.color;
vMaskSwizzle = vec2(0.0, 1.0);
vColor = text.color;
break;
case COLOR_MODE_SUBPX_BG_PASS2:
case COLOR_MODE_SUBPX_DUAL_SOURCE:
V_MASK_SWIZZLE = vec2(1.0, 0.0);
V_COLOR = text.color;
vMaskSwizzle = vec2(1.0, 0.0);
vColor = text.color;
break;
case COLOR_MODE_SUBPX_CONST_COLOR:
case COLOR_MODE_SUBPX_BG_PASS0:
case COLOR_MODE_COLOR_BITMAP:
V_MASK_SWIZZLE = vec2(1.0, 0.0);
V_COLOR = vec4(text.color.a);
vMaskSwizzle = vec2(1.0, 0.0);
vColor = vec4(text.color.a);
break;
case COLOR_MODE_SUBPX_BG_PASS1:
V_MASK_SWIZZLE = vec2(-1.0, 1.0);
V_COLOR = vec4(text.color.a) * text.bg_color;
vMaskSwizzle = vec2(-1.0, 1.0);
vColor = vec4(text.color.a) * text.bg_color;
break;
default:
V_MASK_SWIZZLE = vec2(0.0);
V_COLOR = vec4(1.0);
vMaskSwizzle = vec2(0.0);
vColor = vec4(1.0);
}
vec2 texture_size = vec2(textureSize(sColor0, 0));
vec2 st0 = res.uv_rect.xy / texture_size;
vec2 st1 = res.uv_rect.zw / texture_size;
V_UV = mix(st0, st1, f);
V_LAYER = res.layer;
V_UV_BOUNDS = (res.uv_rect + vec4(0.5, 0.5, -0.5, -0.5)) / texture_size.xyxy;
vUv = vec3(mix(st0, st1, f), res.layer);
vUvBorder = (res.uv_rect + vec4(0.5, 0.5, -0.5, -0.5)) / texture_size.xyxy;
}
#endif
#ifdef WR_FRAGMENT_SHADER
void main(void) {
vec3 tc = vec3(clamp(V_UV, V_UV_BOUNDS.xy, V_UV_BOUNDS.zw), V_LAYER);
vec3 tc = vec3(clamp(vUv.xy, vUvBorder.xy, vUvBorder.zw), vUv.z);
vec4 mask = texture(sColor0, tc);
mask.rgb = mask.rgb * V_MASK_SWIZZLE.x + mask.aaa * V_MASK_SWIZZLE.y;
mask.rgb = mask.rgb * vMaskSwizzle.x + mask.aaa * vMaskSwizzle.y;
float alpha = do_clip();
#ifdef WR_FEATURE_GLYPH_TRANSFORM
alpha *= float(all(greaterThanEqual(V_UV_CLIP, vec4(0.0))));
alpha *= float(all(greaterThanEqual(vUvClip, vec4(0.0))));
#endif
#if defined(WR_FEATURE_DEBUG_OVERDRAW)
oFragColor = WR_DEBUG_OVERDRAW_COLOR;
#elif defined(WR_FEATURE_DUAL_SOURCE_BLENDING)
vec4 alpha_mask = mask * alpha;
oFragColor = V_COLOR * alpha_mask;
oFragBlend = alpha_mask * V_COLOR.a;
oFragColor = vColor * alpha_mask;
oFragBlend = alpha_mask * vColor.a;
#else
write_output(V_COLOR * mask * alpha);
write_output(vColor * mask * alpha);
#endif
}
#endif

Просмотреть файл

@ -11,7 +11,7 @@ use crate::composite::{CompositeState, CompositeTile, CompositeTileSurface};
use crate::glyph_rasterizer::GlyphFormat;
use crate::gpu_cache::{GpuBlockData, GpuCache, GpuCacheHandle, GpuCacheAddress};
use crate::gpu_types::{BrushFlags, BrushInstance, PrimitiveHeaders, ZBufferId, ZBufferIdGenerator};
use crate::gpu_types::{ClipMaskInstance, SplitCompositeInstance, BrushShaderKind};
use crate::gpu_types::{ClipMaskInstance, SplitCompositeInstance};
use crate::gpu_types::{PrimitiveInstanceData, RasterizationSpace, GlyphInstance};
use crate::gpu_types::{PrimitiveHeader, PrimitiveHeaderIndex, TransformPaletteId, TransformPalette};
use crate::internal_types::{FastHashMap, SavedTargetIndex, Swizzle, TextureSource, Filter};
@ -70,22 +70,6 @@ pub enum BatchKind {
Brush(BrushBatchKind),
}
impl BatchKind {
fn shader_kind(&self) -> BrushShaderKind {
match self {
BatchKind::Brush(BrushBatchKind::Solid) => BrushShaderKind::Solid,
BatchKind::Brush(BrushBatchKind::Image(..)) => BrushShaderKind::Image,
BatchKind::Brush(BrushBatchKind::LinearGradient) => BrushShaderKind::LinearGradient,
BatchKind::Brush(BrushBatchKind::RadialGradient) => BrushShaderKind::RadialGradient,
BatchKind::Brush(BrushBatchKind::Blend) => BrushShaderKind::Blend,
BatchKind::Brush(BrushBatchKind::MixBlend { .. }) => BrushShaderKind::MixBlend,
BatchKind::Brush(BrushBatchKind::YuvImage(..)) => BrushShaderKind::Yuv,
BatchKind::TextRun(..) => BrushShaderKind::Text,
_ => BrushShaderKind::None,
}
}
}
/// Optional textures that can be used as a source in the shaders.
/// Textures that are not used by the batch are equal to TextureId::invalid().
#[derive(Copy, Clone, Debug)]
@ -591,7 +575,7 @@ impl BatchBuilder {
clip_task_address: RenderTaskAddress,
brush_flags: BrushFlags,
prim_header_index: PrimitiveHeaderIndex,
resource_address: i32,
user_data: i32,
prim_vis_mask: PrimitiveVisibilityMask,
) {
for batcher in &mut self.batchers {
@ -605,8 +589,7 @@ impl BatchBuilder {
render_task_address,
brush_flags,
prim_header_index,
resource_address,
brush_kind: batch_key.kind.shader_kind(),
user_data,
};
batcher.push_single_instance(

Просмотреть файл

@ -34,7 +34,7 @@ use std::{
time::Duration,
};
use webrender_build::shader::ProgramSourceDigest;
use webrender_build::shader::{ShaderSourceParser, shader_source_from_file};
use webrender_build::shader::{parse_shader_source, shader_source_from_file};
/// Sequence number for frames, as tracked by the device layer.
#[derive(Debug, Copy, Clone, PartialEq, Ord, Eq, PartialOrd)]
@ -288,11 +288,7 @@ fn build_shader_main_string<F: FnMut(&str)>(
output: &mut F,
) {
let shared_source = get_shader_source(base_filename, override_path);
ShaderSourceParser::new().parse(
shared_source,
&|f| get_shader_source(f, override_path),
output
);
parse_shader_source(shared_source, &|f| get_shader_source(f, override_path), output);
}
pub trait FileWatcherHandler: Send {

Просмотреть файл

@ -63,26 +63,6 @@ impl ZBufferIdGenerator {
}
}
/// A shader kind identifier that can be used by a generic-shader to select the behavior at runtime.
///
/// Not all brush kinds need to be present in this enum, only those we want to support in the generic
/// brush shader.
/// Do not use the 24 lowest bits. This will be packed with other information in the vertex attributes.
/// The constants must match the corresponding defines in brush_multi.glsl.
#[repr(i32)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum BrushShaderKind {
None = 0,
Solid = 1,
Image = 2,
Text = 3,
LinearGradient = 4,
RadialGradient = 5,
Blend = 6,
MixBlend = 7,
Yuv = 8,
}
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
@ -362,13 +342,13 @@ impl GlyphInstance {
// TODO(gw): Some of these fields can be moved to the primitive
// header since they are constant, and some can be
// compressed to a smaller size.
pub fn build(&self, data0: i32, data1: i32, resource_address: i32) -> PrimitiveInstanceData {
pub fn build(&self, data0: i32, data1: i32, data2: i32) -> PrimitiveInstanceData {
PrimitiveInstanceData {
data: [
self.prim_header_index.0 as i32,
data0,
data1,
resource_address | ((BrushShaderKind::Text as i32) << 24),
data2,
],
}
}
@ -415,7 +395,10 @@ bitflags! {
}
}
/// Convenience structure to encode into PrimitiveInstanceData.
// TODO(gw): Some of these fields can be moved to the primitive
// header since they are constant, and some can be
// compressed to a smaller size.
#[repr(C)]
pub struct BrushInstance {
pub prim_header_index: PrimitiveHeaderIndex,
pub render_task_address: RenderTaskAddress,
@ -423,8 +406,7 @@ pub struct BrushInstance {
pub segment_index: i32,
pub edge_flags: EdgeAaSegmentMask,
pub brush_flags: BrushFlags,
pub resource_address: i32,
pub brush_kind: BrushShaderKind,
pub user_data: i32,
}
impl From<BrushInstance> for PrimitiveInstanceData {
@ -432,13 +414,12 @@ impl From<BrushInstance> for PrimitiveInstanceData {
PrimitiveInstanceData {
data: [
instance.prim_header_index.0,
((instance.render_task_address.0 as i32) << 16)
| instance.clip_task_address.0 as i32,
instance.segment_index
| ((instance.edge_flags.bits() as i32) << 16)
| ((instance.brush_flags.bits() as i32) << 24),
instance.resource_address
| ((instance.brush_kind as i32) << 24),
((instance.render_task_address.0 as i32) << 16) |
instance.clip_task_address.0 as i32,
instance.segment_index |
((instance.edge_flags.bits() as i32) << 16) |
((instance.brush_flags.bits() as i32) << 24),
instance.user_data,
]
}
}

Просмотреть файл

@ -12,7 +12,6 @@ use std::borrow::Cow;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::collections::HashSet;
#[derive(PartialEq, Eq, Hash, Debug, Clone, Default)]
#[cfg_attr(feature = "serialize_program", derive(Deserialize, Serialize))]
@ -37,49 +36,32 @@ impl From<Sha256> for ProgramSourceDigest {
const SHADER_IMPORT: &str = "#include ";
pub struct ShaderSourceParser {
included: HashSet<String>,
}
/// Parses a shader string for imports. Imports are recursively processed, and
/// prepended to the output stream.
pub fn parse_shader_source<F: FnMut(&str), G: Fn(&str) -> Cow<'static, str>>(
source: Cow<'static, str>,
get_source: &G,
output: &mut F,
) {
for line in source.lines() {
if line.starts_with(SHADER_IMPORT) {
let imports = line[SHADER_IMPORT.len() ..].split(',');
impl ShaderSourceParser {
pub fn new() -> Self {
ShaderSourceParser {
included: HashSet::new(),
}
}
/// Parses a shader string for imports. Imports are recursively processed, and
/// prepended to the output stream.
pub fn parse<F: FnMut(&str), G: Fn(&str) -> Cow<'static, str>>(
&mut self,
source: Cow<'static, str>,
get_source: &G,
output: &mut F,
) {
for line in source.lines() {
if line.starts_with(SHADER_IMPORT) {
let imports = line[SHADER_IMPORT.len() ..].split(',');
// For each import, get the source, and recurse.
for import in imports {
if self.included.insert(import.into()) {
let include = get_source(import);
self.parse(include, get_source, output);
} else {
output(&format!("// {} is already included\n", import));
}
}
} else {
output(line);
output("\n");
// For each import, get the source, and recurse.
for import in imports {
let include = get_source(import);
parse_shader_source(include, get_source, output);
}
} else {
output(line);
output("\n");
}
}
}
/// Reads a shader source file from disk into a String.
pub fn shader_source_from_file(shader_path: &Path) -> String {
assert!(shader_path.exists(), "Shader not found {:?}", shader_path);
assert!(shader_path.exists(), "Shader not found");
let mut source = String::new();
File::open(&shader_path)
.expect("Shader not found")