/* 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/. */ pub mod gradient; pub mod box_shadow; use api::{ColorF, units::DeviceRect}; use crate::clip::{ClipIntern, ClipStore}; use crate::frame_builder::FrameBuilderConfig; use crate::intern::DataStore; use crate::render_task_graph::{RenderTaskGraphBuilder, RenderTaskId}; use crate::renderer::GpuBufferBuilder; use crate::scene::SceneProperties; use crate::spatial_tree::SpatialTree; use crate::transform::TransformPalette; #[repr(u32)] #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum PatternKind { ColorOrTexture = 0, Gradient = 1, Mask = 2, // When adding patterns, don't forget to update the NUM_PATTERNS constant. } pub const NUM_PATTERNS: u32 = 3; impl PatternKind { pub fn from_u32(val: u32) -> Self { assert!(val < NUM_PATTERNS); unsafe { std::mem::transmute(val) } } } /// A 32bit payload used as input for the pattern-specific logic in the shader. /// /// Patterns typically use it as a GpuBuffer offset to fetch their data. #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct PatternShaderInput(pub i32, pub i32); impl Default for PatternShaderInput { fn default() -> Self { PatternShaderInput(0, 0) } } #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct PatternTextureInput { pub task_id: RenderTaskId, } impl Default for PatternTextureInput { fn default() -> Self { PatternTextureInput { task_id: RenderTaskId::INVALID, } } } impl PatternTextureInput { pub fn new(task_id: RenderTaskId) -> Self { PatternTextureInput { task_id, } } } pub struct PatternBuilderContext<'a> { pub scene_properties: &'a SceneProperties, pub spatial_tree: &'a SpatialTree, pub interned_clips: &'a DataStore, pub fb_config: &'a FrameBuilderConfig, } pub struct PatternBuilderState<'a> { pub frame_gpu_data: &'a mut GpuBufferBuilder, pub transforms: &'a mut TransformPalette, pub rg_builder: &'a mut RenderTaskGraphBuilder, pub clip_store: &'a mut ClipStore, } pub trait PatternBuilder { fn build( &self, _sub_rect: Option, _ctx: &PatternBuilderContext, _state: &mut PatternBuilderState, ) -> Pattern; fn get_base_color( &self, _ctx: &PatternBuilderContext, ) -> ColorF; fn use_shared_pattern( &self, ) -> bool; fn can_use_nine_patch(&self) -> bool { true } } #[cfg_attr(feature = "capture", derive(Serialize))] #[derive(Clone, Debug)] pub struct Pattern { pub kind: PatternKind, pub shader_input: PatternShaderInput, pub texture_input: PatternTextureInput, pub base_color: ColorF, pub is_opaque: bool, } impl Pattern { pub fn texture(task_id: RenderTaskId, color: ColorF) -> Self { Pattern { kind: PatternKind::ColorOrTexture, shader_input: PatternShaderInput::default(), texture_input: PatternTextureInput::new(task_id), base_color: color, // TODO(gw): We may want to add support to render tasks to query // if they are known to be opaque. is_opaque: false, } } pub fn color(color: ColorF) -> Self { Pattern { kind: PatternKind::ColorOrTexture, shader_input: PatternShaderInput::default(), texture_input: PatternTextureInput::default(), base_color: color, is_opaque: color.a >= 1.0, } } }