diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /gfx/wr/webrender_build/src/shader_features.rs | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/wr/webrender_build/src/shader_features.rs')
-rw-r--r-- | gfx/wr/webrender_build/src/shader_features.rs | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/gfx/wr/webrender_build/src/shader_features.rs b/gfx/wr/webrender_build/src/shader_features.rs new file mode 100644 index 0000000000..45efd72532 --- /dev/null +++ b/gfx/wr/webrender_build/src/shader_features.rs @@ -0,0 +1,200 @@ +/* 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/. */ + +use std::collections::HashMap; + +bitflags! { + #[derive(Default)] + pub struct ShaderFeatureFlags: u32 { + const GL = 1 << 0; + const GLES = 1 << 1; + + const ADVANCED_BLEND_EQUATION = 1 << 8; + const DUAL_SOURCE_BLENDING = 1 << 9; + const DITHERING = 1 << 10; + const TEXTURE_EXTERNAL = 1 << 11; + const DEBUG = 1 << 12; + } +} + +pub type ShaderFeatures = HashMap<&'static str, Vec<String>>; + +/// Builder for a list of features. +#[derive(Clone)] +struct FeatureList<'a> { + list: Vec<&'a str>, +} + +impl<'a> FeatureList<'a> { + fn new() -> Self { + FeatureList { + list: Vec::new(), + } + } + + fn add(&mut self, feature: &'a str) { + assert!(!feature.contains(',')); + self.list.push(feature); + } + + fn with(&self, feature: &'a str) -> Self { + let mut other = self.clone(); + other.add(feature); + other + } + + fn concat(&self, other: &Self) -> Self { + let mut list = self.list.clone(); + list.extend_from_slice(&other.list); + FeatureList { + list + } + } + + fn finish(&mut self) -> String { + self.list.sort_unstable(); + self.list.join(",") + } +} + +/// Computes available shaders and their features for the given feature flags. +pub fn get_shader_features(flags: ShaderFeatureFlags) -> ShaderFeatures { + let mut shaders = ShaderFeatures::new(); + + // Clip shaders + shaders.insert("cs_clip_rectangle", vec![String::new(), "FAST_PATH".to_string()]); + shaders.insert("cs_clip_image", vec!["TEXTURE_2D".to_string()]); + shaders.insert("cs_clip_box_shadow", vec!["TEXTURE_2D".to_string()]); + + // Cache shaders + shaders.insert("cs_blur", vec!["ALPHA_TARGET".to_string(), "COLOR_TARGET".to_string()]); + + for name in &["cs_line_decoration", "cs_gradient", "cs_border_segment", "cs_border_solid", "cs_svg_filter"] { + shaders.insert(name, vec![String::new()]); + } + + let mut base_prim_features = FeatureList::new(); + + // Brush shaders + let mut brush_alpha_features = base_prim_features.with("ALPHA_PASS"); + 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()); + features.push("DEBUG_OVERDRAW".to_string()); + shaders.insert(name, features); + } + for name in &["brush_conic_gradient", "brush_radial_gradient", "brush_linear_gradient"] { + let mut features: Vec<String> = Vec::new(); + let mut list = FeatureList::new(); + if flags.contains(ShaderFeatureFlags::DITHERING) { + list.add("DITHERING"); + } + features.push(list.concat(&base_prim_features).finish()); + features.push(list.concat(&brush_alpha_features).finish()); + features.push(list.with("DEBUG_OVERDRAW").finish()); + 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_ARRAY", "TEXTURE_2D"]; + if flags.contains(ShaderFeatureFlags::GL) { + texture_types.push("TEXTURE_RECT"); + } + if flags.contains(ShaderFeatureFlags::TEXTURE_EXTERNAL) { + texture_types.push("TEXTURE_EXTERNAL"); + } + let mut image_features: Vec<String> = Vec::new(); + for texture_type in &texture_types { + let mut fast = FeatureList::new(); + if !texture_type.is_empty() { + fast.add(texture_type); + } + image_features.push(fast.concat(&base_prim_features).finish()); + image_features.push(fast.concat(&brush_alpha_features).finish()); + image_features.push(fast.with("DEBUG_OVERDRAW").finish()); + let mut slow = fast.clone(); + slow.add("REPETITION"); + slow.add("ANTIALIASING"); + image_features.push(slow.concat(&base_prim_features).finish()); + image_features.push(slow.concat(&brush_alpha_features).finish()); + image_features.push(slow.with("DEBUG_OVERDRAW").finish()); + if flags.contains(ShaderFeatureFlags::ADVANCED_BLEND_EQUATION) { + let advanced_blend_features = brush_alpha_features.with("ADVANCED_BLEND"); + image_features.push(fast.concat(&advanced_blend_features).finish()); + image_features.push(slow.concat(&advanced_blend_features).finish()); + } + if flags.contains(ShaderFeatureFlags::DUAL_SOURCE_BLENDING) { + let dual_source_features = brush_alpha_features.with("DUAL_SOURCE_BLENDING"); + image_features.push(fast.concat(&dual_source_features).finish()); + image_features.push(slow.concat(&dual_source_features).finish()); + } + } + shaders.insert("brush_image", image_features); + + let mut composite_features: Vec<String> = Vec::new(); + for texture_type in &texture_types { + let base = texture_type.to_string(); + composite_features.push(base); + } + shaders.insert("cs_scale", composite_features.clone()); + + // YUV image brush shaders + let mut yuv_features: Vec<String> = Vec::new(); + for texture_type in &texture_types { + let mut list = FeatureList::new(); + if !texture_type.is_empty() { + list.add(texture_type); + } + list.add("YUV"); + composite_features.push(list.finish()); + yuv_features.push(list.concat(&base_prim_features).finish()); + yuv_features.push(list.concat(&brush_alpha_features).finish()); + yuv_features.push(list.with("DEBUG_OVERDRAW").finish()); + } + shaders.insert("composite", composite_features); + shaders.insert("brush_yuv_image", yuv_features); + + // Prim shaders + let mut text_types = vec![""]; + if flags.contains(ShaderFeatureFlags::DUAL_SOURCE_BLENDING) { + text_types.push("DUAL_SOURCE_BLENDING"); + } + let mut text_features: Vec<String> = Vec::new(); + for text_type in &text_types { + let mut list = base_prim_features.with("TEXTURE_2D"); + if !text_type.is_empty() { + list.add(text_type); + } + let mut alpha_list = list.with("ALPHA_PASS"); + text_features.push(alpha_list.finish()); + text_features.push(alpha_list.with("GLYPH_TRANSFORM").finish()); + text_features.push(list.with("DEBUG_OVERDRAW").finish()); + } + shaders.insert("ps_text_run", text_features); + + shaders.insert("ps_split_composite", vec![base_prim_features.finish()]); + + shaders.insert("ps_clear", vec![base_prim_features.finish()]); + + if flags.contains(ShaderFeatureFlags::DEBUG) { + for name in &["debug_color", "debug_font"] { + shaders.insert(name, vec![String::new()]); + } + } + + shaders +} + |