Bug 1665274 - Speed up brush_opacity. r=lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D91600
This commit is contained in:
Nicolas Silva 2020-10-01 13:13:30 +00:00
parent 45dd1ce875
commit 6ee09103d1
3 changed files with 49 additions and 19 deletions

View File

@ -10,8 +10,9 @@
varying vec2 v_uv;
varying vec2 v_local_pos;
// Normalized bounds of the source image in the texture.
flat varying vec4 v_uv_bounds;
// Normalized bounds of the source image in the texture, adjusted to avoid
// sampling artifacts.
flat varying vec4 v_uv_sample_bounds;
// Layer index to sample.
// Flag to allow perspective interpolation of UV.
@ -46,10 +47,11 @@ void brush_vs(
v_layer_and_perspective.x = res.layer;
v_layer_and_perspective.y = 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;
v_uv_sample_bounds = vec4(uv0 + vec2(0.5), uv1 - vec2(0.5)) / texture_size.xyxy;
#ifdef WR_FEATURE_ANTIALIASING
v_local_pos = vi.local_pos;
#endif
v_opacity = float(prim_user_data.y) / 65536.0;
}
@ -59,20 +61,19 @@ void brush_vs(
Fragment brush_fs() {
float perspective_divisor = mix(gl_FragCoord.w, 1.0, v_layer_and_perspective.y);
vec2 uv = v_uv * perspective_divisor;
vec4 Cs = texture(sColor0, vec3(uv, v_layer_and_perspective.x));
// Clamp the uvs to avoid sampling artifacts.
uv = clamp(uv, v_uv_sample_bounds.xy, v_uv_sample_bounds.zw);
// Un-premultiply the input.
float alpha = Cs.a;
vec3 color = alpha != 0.0 ? Cs.rgb / alpha : Cs.rgb;
// No need to un-premultiply since we'll only apply a factor to the alpha.
vec4 color = texture(sColor0, vec3(uv, v_layer_and_perspective.x));
alpha *= v_opacity;
float alpha = v_opacity;
// 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));
#ifdef WR_FEATURE_ANTIALIASING
alpha *= init_transform_fs(v_local_pos);
#endif
// Pre-multiply the alpha into the output value.
return Fragment(alpha * vec4(color, 1.0));
// Pre-multiply the contribution of the opacity factor.
return Fragment(alpha * color);
}
#endif

View File

@ -554,6 +554,7 @@ pub struct Shaders {
brush_radial_gradient: BrushShader,
brush_linear_gradient: BrushShader,
brush_opacity: BrushShader,
brush_opacity_aa: BrushShader,
/// These are "cache clip shaders". These shaders are used to
/// draw clip instances into the cached clip mask. The results
@ -705,6 +706,17 @@ impl Shaders {
use_pixel_local_storage,
)?;
let brush_opacity_aa = BrushShader::new(
"brush_opacity",
device,
&["ANTIALIASING"],
options.precache_flags,
&shader_list,
false /* advanced blend */,
false /* dual source */,
use_pixel_local_storage,
)?;
let brush_opacity = BrushShader::new(
"brush_opacity",
device,
@ -1048,6 +1060,7 @@ impl Shaders {
brush_radial_gradient,
brush_linear_gradient,
brush_opacity,
brush_opacity_aa,
cs_clip_rectangle_slow,
cs_clip_rectangle_fast,
cs_clip_box_shadow,
@ -1144,7 +1157,11 @@ impl Shaders {
.expect("Unsupported YUV shader kind")
}
BrushBatchKind::Opacity => {
&mut self.brush_opacity
if features.contains(BatchFeatures::ANTIALIASING) {
&mut self.brush_opacity_aa
} else {
&mut self.brush_opacity
}
}
};
brush_shader.get(key.blend_mode, debug_flags)
@ -1175,6 +1192,7 @@ impl Shaders {
self.brush_radial_gradient.deinit(device);
self.brush_linear_gradient.deinit(device);
self.brush_opacity.deinit(device);
self.brush_opacity_aa.deinit(device);
self.cs_clip_rectangle_slow.deinit(device);
self.cs_clip_rectangle_fast.deinit(device);
self.cs_clip_box_shadow.deinit(device);

View File

@ -89,7 +89,7 @@ pub fn get_shader_features(flags: ShaderFeatureFlags) -> ShaderFeatures {
// Brush shaders
let mut brush_alpha_features = base_prim_features.with("ALPHA_PASS");
for name in &["brush_solid", "brush_blend", "brush_mix_blend", "brush_opacity"] {
for name in &["brush_solid", "brush_blend", "brush_mix_blend"] {
let mut features: Vec<String> = Vec::new();
features.push(base_prim_features.finish());
features.push(brush_alpha_features.finish());
@ -108,6 +108,17 @@ pub fn get_shader_features(flags: ShaderFeatureFlags) -> ShaderFeatures {
shaders.insert(name, features);
}
{
let mut features: Vec<String> = Vec::new();
features.push(base_prim_features.finish());
features.push(brush_alpha_features.finish());
features.push(base_prim_features.with("ANTIALIASING").finish());
features.push(brush_alpha_features.with("ANTIALIASING").finish());
features.push("ANTIALIASING,DEBUG_OVERDRAW".to_string());
features.push("DEBUG_OVERDRAW".to_string());
shaders.insert("brush_opacity", features);
}
// Image brush shaders
let mut texture_types = vec!["", "TEXTURE_2D"];
if flags.contains(ShaderFeatureFlags::GL) {