webrender/prim_store/gradient/
conic.rs1use api::{ExtendMode, GradientStop};
12use api::units::*;
13use crate::pattern::gradient::{conic_gradient_pattern};
14use crate::pattern::{Pattern, PatternBuilder, PatternBuilderContext, PatternBuilderState};
15use crate::scene_building::IsVisible;
16use crate::intern::{Internable, InternDebug, Handle as InternHandle};
17use crate::internal_types::LayoutPrimitiveInfo;
18use crate::prim_store::{PrimitiveKind, PrimitiveOpacity};
19use crate::prim_store::{PrimKeyCommonData, PrimTemplateCommonData, PrimitiveStore};
20use crate::prim_store::{NinePatchDescriptor, PointKey, SizeKey, InternablePrimitive};
21
22use std::{hash, ops::{Deref, DerefMut}};
23use super::{stops_and_min_alpha, GradientStopKey};
24
25#[cfg_attr(feature = "capture", derive(Serialize))]
27#[cfg_attr(feature = "replay", derive(Deserialize))]
28#[derive(Debug, Clone, MallocSizeOf, PartialEq)]
29pub struct ConicGradientParams {
30 pub angle: f32, pub start_offset: f32,
32 pub end_offset: f32,
33}
34
35impl Eq for ConicGradientParams {}
36
37impl hash::Hash for ConicGradientParams {
38 fn hash<H: hash::Hasher>(&self, state: &mut H) {
39 self.angle.to_bits().hash(state);
40 self.start_offset.to_bits().hash(state);
41 self.end_offset.to_bits().hash(state);
42 }
43}
44
45#[cfg_attr(feature = "capture", derive(Serialize))]
47#[cfg_attr(feature = "replay", derive(Deserialize))]
48#[derive(Debug, Clone, Eq, PartialEq, Hash, MallocSizeOf)]
49pub struct ConicGradientKey {
50 pub common: PrimKeyCommonData,
51 pub extend_mode: ExtendMode,
52 pub center: PointKey,
53 pub params: ConicGradientParams,
54 pub stretch_ratio: SizeKey,
57 pub stops: Vec<GradientStopKey>,
58 pub tile_spacing: SizeKey,
59 pub nine_patch: Option<Box<NinePatchDescriptor>>,
60}
61
62impl ConicGradientKey {
63 pub fn new(
64 info: &LayoutPrimitiveInfo,
65 conic_grad: ConicGradient,
66 ) -> Self {
67 ConicGradientKey {
68 common: info.into(),
69 extend_mode: conic_grad.extend_mode,
70 center: conic_grad.center,
71 params: conic_grad.params,
72 stretch_ratio: conic_grad.stretch_ratio,
73 stops: conic_grad.stops,
74 tile_spacing: conic_grad.tile_spacing,
75 nine_patch: conic_grad.nine_patch,
76 }
77 }
78}
79
80impl InternDebug for ConicGradientKey {}
81
82#[cfg_attr(feature = "capture", derive(Serialize))]
83#[cfg_attr(feature = "replay", derive(Deserialize))]
84#[derive(MallocSizeOf)]
85pub struct ConicGradientTemplate {
86 pub common: PrimTemplateCommonData,
87 pub extend_mode: ExtendMode,
88 pub center: LayoutPoint,
89 pub params: ConicGradientParams,
90 pub stretch_ratio: LayoutSize,
94 pub tile_spacing: LayoutSize,
95 pub border_nine_patch: Option<Box<NinePatchDescriptor>>,
96 pub stops_opacity: PrimitiveOpacity,
97 pub stops: Vec<GradientStop>,
98}
99
100impl PatternBuilder for ConicGradientTemplate {
101 fn build(
102 &self,
103 _sub_rect: Option<DeviceRect>,
104 offset: LayoutVector2D,
105 ctx: &PatternBuilderContext,
106 state: &mut PatternBuilderState,
107 ) -> Pattern {
108 let no_scale = DeviceVector2D::one();
111
112 let center = self.center + ctx.prim_origin.to_vector() + offset;
116
117 conic_gradient_pattern(
118 center,
119 no_scale,
120 self.params.angle,
121 self.params.start_offset,
122 self.params.end_offset,
123 self.extend_mode,
124 &self.stops,
125 state.frame_gpu_data,
126 )
127 }
128}
129
130impl Deref for ConicGradientTemplate {
131 type Target = PrimTemplateCommonData;
132 fn deref(&self) -> &Self::Target {
133 &self.common
134 }
135}
136
137impl DerefMut for ConicGradientTemplate {
138 fn deref_mut(&mut self) -> &mut Self::Target {
139 &mut self.common
140 }
141}
142
143impl From<ConicGradientKey> for ConicGradientTemplate {
144 fn from(item: ConicGradientKey) -> Self {
145 let common = PrimTemplateCommonData::with_key_common(item.common);
146
147 let (stops, min_alpha) = stops_and_min_alpha(&item.stops);
148
149 let stops_opacity = PrimitiveOpacity::from_alpha(min_alpha);
153
154 ConicGradientTemplate {
155 common,
156 center: item.center.into(),
157 extend_mode: item.extend_mode,
158 params: item.params,
159 stretch_ratio: item.stretch_ratio.into(),
160 tile_spacing: item.tile_spacing.into(),
161 border_nine_patch: item.nine_patch,
162 stops_opacity,
163 stops,
164 }
165 }
166}
167
168pub type ConicGradientDataHandle = InternHandle<ConicGradient>;
169
170#[derive(Debug, MallocSizeOf)]
171#[cfg_attr(feature = "capture", derive(Serialize))]
172#[cfg_attr(feature = "replay", derive(Deserialize))]
173pub struct ConicGradient {
174 pub extend_mode: ExtendMode,
175 pub center: PointKey,
176 pub params: ConicGradientParams,
177 pub stretch_ratio: SizeKey,
180 pub stops: Vec<GradientStopKey>,
181 pub tile_spacing: SizeKey,
182 pub nine_patch: Option<Box<NinePatchDescriptor>>,
183}
184
185impl Internable for ConicGradient {
186 type Key = ConicGradientKey;
187 type StoreData = ConicGradientTemplate;
188 type InternData = ();
189 const PROFILE_COUNTER: usize = crate::profiler::INTERNED_CONIC_GRADIENTS;
190}
191
192impl InternablePrimitive for ConicGradient {
193 fn into_key(
194 self,
195 info: &LayoutPrimitiveInfo,
196 ) -> ConicGradientKey {
197 ConicGradientKey::new(info, self)
198 }
199
200 fn make_instance_kind(
201 _key: ConicGradientKey,
202 data_handle: ConicGradientDataHandle,
203 _prim_store: &mut PrimitiveStore,
204 ) -> PrimitiveKind {
205 PrimitiveKind::ConicGradient {
206 data_handle,
207 }
208 }
209}
210
211impl IsVisible for ConicGradient {
212 fn is_visible(&self) -> bool {
213 true
214 }
215}
216