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