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