webrender/
pattern.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5use api::{units::DeviceRect, ColorF};
6
7use crate::{clip::ClipStore, render_task_graph::{RenderTaskGraphBuilder, RenderTaskId}, renderer::GpuBufferBuilder, scene::SceneProperties, spatial_tree::SpatialTree};
8
9#[repr(u32)]
10#[cfg_attr(feature = "capture", derive(Serialize))]
11#[cfg_attr(feature = "replay", derive(Deserialize))]
12#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
13pub enum PatternKind {
14    ColorOrTexture = 0,
15    RadialGradient = 1,
16    ConicGradient = 2,
17
18    Mask = 3,
19    // When adding patterns, don't forget to update the NUM_PATTERNS constant.
20}
21
22pub const NUM_PATTERNS: u32 = 4;
23
24impl PatternKind {
25    pub fn from_u32(val: u32) -> Self {
26        assert!(val < NUM_PATTERNS);
27        unsafe { std::mem::transmute(val) }
28    }
29}
30
31/// A 32bit payload used as input for the pattern-specific logic in the shader.
32///
33/// Patterns typically use it as a GpuBuffer offset to fetch their data.
34#[cfg_attr(feature = "capture", derive(Serialize))]
35#[cfg_attr(feature = "replay", derive(Deserialize))]
36#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
37pub struct PatternShaderInput(pub i32, pub i32);
38
39impl Default for PatternShaderInput {
40    fn default() -> Self {
41        PatternShaderInput(0, 0)
42    }
43}
44
45#[cfg_attr(feature = "capture", derive(Serialize))]
46#[cfg_attr(feature = "replay", derive(Deserialize))]
47#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
48pub struct PatternTextureInput {
49    pub task_id: RenderTaskId,
50}
51
52impl Default for PatternTextureInput {
53    fn default() -> Self {
54        PatternTextureInput {
55            task_id: RenderTaskId::INVALID,
56        }
57    }
58}
59
60impl PatternTextureInput {
61    pub fn new(task_id: RenderTaskId) -> Self {
62        PatternTextureInput {
63            task_id,
64        }
65    }
66}
67
68pub struct PatternBuilderContext<'a> {
69    pub scene_properties: &'a SceneProperties,
70    pub spatial_tree: &'a SpatialTree,
71}
72
73pub struct PatternBuilderState<'a> {
74    pub frame_gpu_data: &'a mut GpuBufferBuilder,
75    pub rg_builder: &'a mut RenderTaskGraphBuilder,
76    pub clip_store: &'a mut ClipStore,
77}
78
79pub trait PatternBuilder {
80    fn build(
81        &self,
82        _sub_rect: Option<DeviceRect>,
83        _ctx: &PatternBuilderContext,
84        _state: &mut PatternBuilderState,
85    ) -> Pattern;
86
87    fn get_base_color(
88        &self,
89        _ctx: &PatternBuilderContext,
90    ) -> ColorF;
91
92    fn use_shared_pattern(
93        &self,
94    ) -> bool;
95
96    fn can_use_nine_patch(&self) -> bool {
97        true
98    }
99}
100
101#[cfg_attr(feature = "capture", derive(Serialize))]
102#[derive(Clone, Debug)]
103pub struct Pattern {
104    pub kind: PatternKind,
105    pub shader_input: PatternShaderInput,
106    pub texture_input: PatternTextureInput,
107    pub base_color: ColorF,
108    pub is_opaque: bool,
109}
110
111impl Pattern {
112    pub fn texture(task_id: RenderTaskId, color: ColorF) -> Self {
113        Pattern {
114            kind: PatternKind::ColorOrTexture,
115            shader_input: PatternShaderInput::default(),
116            texture_input: PatternTextureInput::new(task_id),
117            base_color: color,
118            // TODO(gw): We may want to add support to render tasks to query
119            //           if they are known to be opaque.
120            is_opaque: false,
121        }
122    }
123
124    pub fn color(color: ColorF) -> Self {
125        Pattern {
126            kind: PatternKind::ColorOrTexture,
127            shader_input: PatternShaderInput::default(),
128            texture_input: PatternTextureInput::default(),
129            base_color: color,
130            is_opaque: color.a >= 1.0,
131        }
132    }
133
134    pub fn clear() -> Self {
135        // Opaque black with operator dest out
136        Pattern {
137            kind: PatternKind::ColorOrTexture,
138            shader_input: PatternShaderInput::default(),
139            texture_input: PatternTextureInput::default(),
140            base_color: ColorF::BLACK,
141            is_opaque: false,
142        }
143    }
144}