зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland. a=merge CLOSED TREE
This commit is contained in:
Коммит
129962fb8c
|
@ -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")
|
||||
|
|
Загрузка…
Ссылка в новой задаче