mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-11 08:13:35 +00:00
Bug 1665274 - Speed up brush_opacity. r=lsalzman
Differential Revision: https://phabricator.services.mozilla.com/D91600
This commit is contained in:
parent
45dd1ce875
commit
6ee09103d1
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user