Skip to main content

webrender/prim_store/
rectangle.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::{PropertyBinding, ColorU, ColorF, Shadow, RasterSpace};
6use crate::scene_building::{CreateShadow, IsVisible};
7use crate::intern;
8use crate::internal_types::LayoutPrimitiveInfo;
9use crate::prim_store::{
10    PrimKey, InternablePrimitive, PrimitiveStore, PrimitiveKind,
11    PrimTemplate, PrimTemplateCommonData, PrimitiveOpacity,
12};
13use crate::frame_builder::FrameBuildingState;
14use crate::scene::SceneProperties;
15use std::ops;
16
17#[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash)]
18#[cfg_attr(feature = "capture", derive(Serialize))]
19#[cfg_attr(feature = "replay", derive(Deserialize))]
20pub struct RectanglePrim {
21    pub color: PropertyBinding<ColorU>,
22}
23
24pub type RectangleKey = PrimKey<RectanglePrim>;
25
26pub type RectangleDataHandle = intern::Handle<RectanglePrim>;
27
28impl RectangleKey {
29    pub fn new(info: &LayoutPrimitiveInfo, kind: RectanglePrim) -> Self {
30        RectangleKey { common: info.into(), kind }
31    }
32}
33
34impl intern::InternDebug for RectangleKey {}
35
36impl intern::Internable for RectanglePrim {
37    type Key = RectangleKey;
38    type StoreData = RectangleTemplate;
39    type InternData = ();
40    const PROFILE_COUNTER: usize = crate::profiler::INTERNED_PRIMITIVES;
41}
42
43impl InternablePrimitive for RectanglePrim {
44    fn into_key(
45        self,
46        info: &LayoutPrimitiveInfo,
47    ) -> RectangleKey {
48        RectangleKey::new(info, self)
49    }
50
51    fn make_instance_kind(
52        _key: RectangleKey,
53        data_handle: RectangleDataHandle,
54        _prim_store: &mut PrimitiveStore,
55    ) -> PrimitiveKind {
56        PrimitiveKind::Rectangle {
57            data_handle,
58        }
59    }
60}
61
62impl IsVisible for RectanglePrim {
63    fn is_visible(&self) -> bool {
64        match self.color {
65            PropertyBinding::Value(value) => value.a > 0,
66            PropertyBinding::Binding(..) => true,
67        }
68    }
69}
70
71impl CreateShadow for RectanglePrim {
72    fn create_shadow(
73        &self,
74        shadow: &Shadow,
75        _: bool,
76        _: RasterSpace,
77    ) -> RectanglePrim {
78        RectanglePrim {
79            color: PropertyBinding::Value(shadow.color.into()),
80        }
81    }
82}
83
84#[cfg_attr(feature = "capture", derive(Serialize))]
85#[cfg_attr(feature = "replay", derive(Deserialize))]
86#[derive(MallocSizeOf)]
87pub struct RectangleData {
88    pub color: PropertyBinding<ColorF>,
89}
90
91pub type RectangleTemplate = PrimTemplate<RectangleData>;
92
93impl RectangleTemplate {
94    pub fn resolve(&self, scene_properties: &SceneProperties) -> ColorF {
95        scene_properties.resolve_color(&self.kind.color)
96    }
97}
98
99impl ops::Deref for RectangleTemplate {
100    type Target = PrimTemplateCommonData;
101    fn deref(&self) -> &Self::Target {
102        &self.common
103    }
104}
105
106impl ops::DerefMut for RectangleTemplate {
107    fn deref_mut(&mut self) -> &mut Self::Target {
108        &mut self.common
109    }
110}
111
112impl From<RectangleKey> for RectangleTemplate {
113    fn from(item: RectangleKey) -> Self {
114        RectangleTemplate {
115            common: PrimTemplateCommonData::with_key_common(item.common),
116            kind: RectangleData { color: item.kind.color.into() },
117        }
118    }
119}
120
121impl RectangleTemplate {
122    pub fn update(
123        &mut self,
124        frame_state: &mut FrameBuildingState,
125        scene_properties: &SceneProperties,
126    ) {
127        let mut writer = frame_state.frame_gpu_data.f32.write_blocks(1);
128        writer.push_one(scene_properties.resolve_color(&self.kind.color).premultiplied());
129        self.common.gpu_buffer_address = writer.finish();
130        self.opacity = PrimitiveOpacity::from_alpha(
131            scene_properties.resolve_color(&self.kind.color).a
132        );
133    }
134}
135
136#[test]
137#[cfg(target_pointer_width = "64")]
138fn test_struct_sizes() {
139    use std::mem;
140    assert_eq!(mem::size_of::<RectanglePrim>(), 16, "RectanglePrim size changed");
141    assert_eq!(mem::size_of::<RectangleTemplate>(), 36, "RectangleTemplate size changed");
142    assert_eq!(mem::size_of::<RectangleKey>(), 20, "RectangleKey size changed");
143}