Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  shader_features.rs   Sprache: unbekannt

 
/* 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, Debug, Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
    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 TEXTURE_EXTERNAL_ESSL1 = 1 << 12;
        const TEXTURE_EXTERNAL_BT709 = 1 << 13;
        const DEBUG = 1 << 14;
    }
}

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_box_shadow", vec!["TEXTURE_2D".to_string()]);

    // Cache shaders
    shaders.insert("cs_blur", vec!["ALPHA_TARGET".to_string(), "COLOR_TARGET".to_string()]);

    shaders.insert("ps_quad_mask", vec![String::new(), "FAST_PATH".to_string()]);

    for name in &[
        "cs_line_decoration",
        "cs_fast_linear_gradient",
        "cs_border_segment",
        "cs_border_solid",
        "cs_svg_filter",
        "cs_svg_filter_node",
    ] {
        shaders.insert(name, vec![String::new()]);
    }

    for name in &[
        "cs_linear_gradient",
        "cs_radial_gradient",
        "cs_conic_gradient",
    ] {
        let mut features = Vec::new();
        features.push(String::new());
        if flags.contains(ShaderFeatureFlags::DITHERING) {
            features.push("DITHERING".to_string());
        }
        shaders.insert(name, features);
    }

    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 features: Vec<String> = vec![
            base_prim_features.finish(),
            brush_alpha_features.finish(),
            "DEBUG_OVERDRAW".to_string(),
        ];
        shaders.insert(name, features);
    }

    #[allow(clippy::single_element_loop)]
    for name in &["brush_linear_gradient"] {
        let mut list = FeatureList::new();
        if flags.contains(ShaderFeatureFlags::DITHERING) {
            list.add("DITHERING");
        }
        let features: Vec<String> = vec![
            list.concat(&base_prim_features).finish(),
            list.concat(&brush_alpha_features).finish(),
            list.with("DEBUG_OVERDRAW").finish(),
        ];
        shaders.insert(name, features);
    }

    {
        let features: Vec<String> = vec![
            base_prim_features.finish(),
            brush_alpha_features.finish(),
            base_prim_features.with("ANTIALIASING").finish(),
            brush_alpha_features.with("ANTIALIASING").finish(),
            "ANTIALIASING,DEBUG_OVERDRAW".to_string(),
            "DEBUG_OVERDRAW".to_string(),
        ];
        shaders.insert("brush_opacity", features);
    }

    // Image brush shaders
    let mut texture_types = vec!["TEXTURE_2D"];
    if flags.contains(ShaderFeatureFlags::GL) {
        texture_types.push("TEXTURE_RECT");
    }
    if flags.contains(ShaderFeatureFlags::TEXTURE_EXTERNAL) {
        texture_types.push("TEXTURE_EXTERNAL");
    }
    if flags.contains(ShaderFeatureFlags::TEXTURE_EXTERNAL_BT709) {
        texture_types.push("TEXTURE_EXTERNAL_BT709");
    }
    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_texture_types = texture_types.clone();
    if flags.contains(ShaderFeatureFlags::TEXTURE_EXTERNAL_ESSL1) {
        composite_texture_types.push("TEXTURE_EXTERNAL_ESSL1");
    }
    let mut composite_features: Vec<String> = Vec::new();
    for texture_type in &composite_texture_types {
        let base = texture_type.to_string();
        composite_features.push(base);
    }
    shaders.insert("cs_scale", composite_features.clone());

    // YUV image brush and composite 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("brush_yuv_image", yuv_features);

    // Fast path composite shaders
    for texture_type in &composite_texture_types {
        let mut list = FeatureList::new();
        if !texture_type.is_empty() {
            list.add(texture_type);
        }
        list.add("FAST_PATH");
        composite_features.push(list.finish());
    }
    shaders.insert("composite", composite_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_quad_textured", vec![base_prim_features.finish()]);

    shaders.insert("ps_quad_radial_gradient", vec![base_prim_features.finish()]);

    shaders.insert("ps_quad_conic_gradient", vec![base_prim_features.finish()]);

    shaders.insert("ps_clear", vec![base_prim_features.finish()]);

    shaders.insert("ps_copy", vec![base_prim_features.finish()]);

    if flags.contains(ShaderFeatureFlags::DEBUG) {
        for name in &["debug_color", "debug_font"] {
            shaders.insert(name, vec![String::new()]);
        }
    }

    shaders
}


[ Dauer der Verarbeitung: 0.30 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge