Bug 1675590 - avoid using alpha-pass version of gradient shader for clip-mask-only cases. r=jrmuizel

Differential Revision: https://phabricator.services.mozilla.com/D102999
This commit is contained in:
Lee Salzman 2021-01-26 03:56:10 +00:00
Родитель 8b4b32c5c1
Коммит b9384b091e
4 изменённых файлов: 31 добавлений и 26 удалений

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

@ -156,7 +156,11 @@ void brush_shader_main_vs(
// shaders that don't clip in the future,
// but it's reasonable to assume that one
// implies the other, for now.
#ifdef WR_FEATURE_ALPHA_PASS
// SW-WR may decay some requests for alpha-pass shaders to
// the opaque version if only the clip-mask is required. In
// that case the opaque vertex shader must still write out
// the clip information, which is cheap to do for SWGL.
#if defined(WR_FEATURE_ALPHA_PASS) || defined(SWGL)
write_clip(
vi.world_pos,
clip_area,

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

@ -981,6 +981,9 @@ pub struct Capabilities {
/// Whether the driver prefers fewer and larger texture uploads
/// over many smaller updates.
pub prefers_batched_texture_uploads: bool,
/// Whether clip-masking is supported natively by the GL implementation
/// rather than emulated in shaders.
pub uses_native_clip_mask: bool,
/// The name of the renderer, as reported by GL
pub renderer_name: String,
}
@ -1627,6 +1630,12 @@ impl Device {
gl::GlType::Gles => gl_version >= [3, 1],
};
// SWGL uses swgl_clipMask() instead of implementing clip-masking in shaders.
// This allows certain shaders to potentially bypass the more expensive alpha-
// pass variants if they know the alpha-pass was only required to deal with
// clip-masking.
let uses_native_clip_mask = is_software_webrender;
// On Mali-Gxx the driver really struggles with many small texture uploads,
// and handles fewer, larger uploads better.
let prefers_batched_texture_uploads = is_mali_g;
@ -1654,6 +1663,7 @@ impl Device {
supports_render_target_partial_update,
supports_shader_storage_object,
prefers_batched_texture_uploads,
uses_native_clip_mask,
renderer_name,
},

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

@ -3038,7 +3038,7 @@ impl Renderer {
}
self.shaders.borrow_mut()
.get(&batch.key, batch.features, self.debug_flags)
.get(&batch.key, batch.features, self.debug_flags, &self.device)
.bind(
&mut self.device, projection,
&mut self.renderer_errors,
@ -3078,6 +3078,7 @@ impl Renderer {
&batch.key,
batch.features | BatchFeatures::ALPHA_PASS,
self.debug_flags,
&self.device,
);
if batch.key.blend_mode != prev_blend_mode {

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

@ -1060,6 +1060,7 @@ impl Shaders {
key: &BatchKey,
mut features: BatchFeatures,
debug_flags: DebugFlags,
device: &Device,
) -> &mut LazilyCompiledShader {
match key.kind {
BatchKind::SplitComposite => {
@ -1089,7 +1090,15 @@ impl Shaders {
BrushBatchKind::MixBlend { .. } => {
&mut self.brush_mix_blend
}
BrushBatchKind::LinearGradient |
BrushBatchKind::RadialGradient |
BrushBatchKind::ConicGradient => {
// SWGL uses a native clip mask implementation that bypasses the shader.
// Don't consider it in that case when deciding whether or not to use
// an alpha-pass shader.
if device.get_capabilities().uses_native_clip_mask {
features.remove(BatchFeatures::CLIP_MASK);
}
// Gradient brushes can optimistically use the opaque shader even
// with a blend mode if they don't require any features.
if !features.intersects(
@ -1099,31 +1108,12 @@ impl Shaders {
) {
features.remove(BatchFeatures::ALPHA_PASS);
}
&mut self.brush_conic_gradient
}
BrushBatchKind::RadialGradient => {
// Gradient brushes can optimistically use the opaque shader even
// with a blend mode if they don't require any features.
if !features.intersects(
BatchFeatures::ANTIALIASING
| BatchFeatures::REPETITION
| BatchFeatures::CLIP_MASK,
) {
features.remove(BatchFeatures::ALPHA_PASS);
match brush_kind {
BrushBatchKind::LinearGradient => &mut self.brush_linear_gradient,
BrushBatchKind::RadialGradient => &mut self.brush_radial_gradient,
BrushBatchKind::ConicGradient => &mut self.brush_conic_gradient,
_ => panic!(),
}
&mut self.brush_radial_gradient
}
BrushBatchKind::LinearGradient => {
// Gradient brushes can optimistically use the opaque shader even
// with a blend mode if they don't require any features.
if !features.intersects(
BatchFeatures::ANTIALIASING
| BatchFeatures::REPETITION
| BatchFeatures::CLIP_MASK,
) {
features.remove(BatchFeatures::ALPHA_PASS);
}
&mut self.brush_linear_gradient
}
BrushBatchKind::YuvImage(image_buffer_kind, ..) => {
let shader_index =