1use api::{AlphaType, PremultipliedColorF, YuvFormat, YuvRangedColorSpace};
6use api::units::*;
7use crate::composite::{CompositeFeatures, CompositorClip};
8use crate::segment::EdgeAaSegmentMask;
9use crate::spatial_tree::{SpatialTree, SpatialNodeIndex};
10use crate::gpu_cache::{GpuCacheAddress, GpuDataRequest};
11use crate::internal_types::{FastHashMap, FrameVec, FrameMemory};
12use crate::prim_store::ClipData;
13use crate::render_task::RenderTaskAddress;
14use crate::render_task_graph::RenderTaskId;
15use crate::renderer::{ShaderColorMode, GpuBufferAddress};
16use std::i32;
17use crate::util::{MatrixHelpers, TransformedRectKind};
18use glyph_rasterizer::SubpixelDirection;
19use crate::util::{ScaleOffset, pack_as_float};
20
21
22pub const VECS_PER_TRANSFORM: usize = 8;
25
26#[derive(Copy, Clone, Debug, PartialEq)]
27#[repr(C)]
28#[cfg_attr(feature = "capture", derive(Serialize))]
29#[cfg_attr(feature = "replay", derive(Deserialize))]
30pub struct ZBufferId(pub i32);
31
32impl ZBufferId {
33 pub fn invalid() -> Self {
34 ZBufferId(i32::MAX)
35 }
36}
37
38#[derive(Debug)]
39#[cfg_attr(feature = "capture", derive(Serialize))]
40#[cfg_attr(feature = "replay", derive(Deserialize))]
41pub struct ZBufferIdGenerator {
42 next: i32,
43 max_depth_ids: i32,
44}
45
46impl ZBufferIdGenerator {
47 pub fn new(max_depth_ids: i32) -> Self {
48 ZBufferIdGenerator {
49 next: 0,
50 max_depth_ids,
51 }
52 }
53
54 pub fn next(&mut self) -> ZBufferId {
55 debug_assert!(self.next < self.max_depth_ids);
56 let id = ZBufferId(self.next);
57 self.next += 1;
58 id
59 }
60}
61
62#[derive(Clone, Debug)]
63#[repr(C)]
64#[cfg_attr(feature = "capture", derive(Serialize))]
65#[cfg_attr(feature = "replay", derive(Deserialize))]
66pub struct CopyInstance {
67 pub src_rect: DeviceRect,
68 pub dst_rect: DeviceRect,
69 pub dst_texture_size: DeviceSize,
70}
71
72#[derive(Debug, Copy, Clone)]
73#[cfg_attr(feature = "capture", derive(Serialize))]
74#[cfg_attr(feature = "replay", derive(Deserialize))]
75#[repr(C)]
76pub enum RasterizationSpace {
77 Local = 0,
78 Screen = 1,
79}
80
81#[derive(Debug, Copy, Clone, MallocSizeOf)]
82#[cfg_attr(feature = "capture", derive(Serialize))]
83#[cfg_attr(feature = "replay", derive(Deserialize))]
84#[repr(C)]
85pub enum BoxShadowStretchMode {
86 Stretch = 0,
87 Simple = 1,
88}
89
90#[repr(i32)]
91#[derive(Debug, Copy, Clone)]
92#[cfg_attr(feature = "capture", derive(Serialize))]
93#[cfg_attr(feature = "replay", derive(Deserialize))]
94pub enum BlurDirection {
95 Horizontal = 0,
96 Vertical,
97}
98
99impl BlurDirection {
100 pub fn as_int(self) -> i32 {
101 match self {
102 BlurDirection::Horizontal => 0,
103 BlurDirection::Vertical => 1,
104 }
105 }
106}
107
108#[derive(Clone, Debug)]
109#[repr(C)]
110#[cfg_attr(feature = "capture", derive(Serialize))]
111#[cfg_attr(feature = "replay", derive(Deserialize))]
112pub struct BlurInstance {
113 pub task_address: RenderTaskAddress,
114 pub src_task_address: RenderTaskAddress,
115 pub blur_direction: i32,
116 pub blur_std_deviation: f32,
117 pub blur_region: DeviceSize,
118}
119
120#[derive(Clone, Debug)]
121#[repr(C)]
122#[cfg_attr(feature = "capture", derive(Serialize))]
123#[cfg_attr(feature = "replay", derive(Deserialize))]
124pub struct ScalingInstance {
125 pub target_rect: DeviceRect,
126 pub source_rect: DeviceRect,
127 source_rect_type: f32,
128}
129
130impl ScalingInstance {
131 pub fn new(target_rect: DeviceRect, source_rect: DeviceRect, source_rect_normalized: bool) -> Self {
132 let source_rect_type = match source_rect_normalized {
133 true => UV_TYPE_NORMALIZED,
134 false => UV_TYPE_UNNORMALIZED,
135 };
136 Self {
137 target_rect,
138 source_rect,
139 source_rect_type: pack_as_float(source_rect_type),
140 }
141 }
142}
143
144#[derive(Clone, Debug)]
145#[repr(C)]
146#[cfg_attr(feature = "capture", derive(Serialize))]
147#[cfg_attr(feature = "replay", derive(Deserialize))]
148pub struct SvgFilterInstance {
149 pub task_address: RenderTaskAddress,
150 pub input_1_task_address: RenderTaskAddress,
151 pub input_2_task_address: RenderTaskAddress,
152 pub kind: u16,
153 pub input_count: u16,
154 pub generic_int: u16,
155 pub padding: u16,
156 pub extra_data_address: GpuCacheAddress,
157}
158
159#[derive(Clone, Debug)]
160#[repr(C)]
161#[cfg_attr(feature = "capture", derive(Serialize))]
162#[cfg_attr(feature = "replay", derive(Deserialize))]
163pub struct SVGFEFilterInstance {
164 pub target_rect: DeviceRect,
165 pub input_1_content_scale_and_offset: [f32; 4],
166 pub input_2_content_scale_and_offset: [f32; 4],
167 pub input_1_task_address: RenderTaskAddress,
168 pub input_2_task_address: RenderTaskAddress,
169 pub kind: u16,
170 pub input_count: u16,
171 pub extra_data_address: GpuCacheAddress,
172}
173
174#[derive(Copy, Clone, Debug, Hash, MallocSizeOf, PartialEq, Eq)]
175#[repr(C)]
176#[cfg_attr(feature = "capture", derive(Serialize))]
177#[cfg_attr(feature = "replay", derive(Deserialize))]
178pub enum BorderSegment {
179 TopLeft,
180 TopRight,
181 BottomRight,
182 BottomLeft,
183 Left,
184 Top,
185 Right,
186 Bottom,
187}
188
189#[derive(Debug, Clone)]
190#[repr(C)]
191#[cfg_attr(feature = "capture", derive(Serialize))]
192#[cfg_attr(feature = "replay", derive(Deserialize))]
193pub struct BorderInstance {
194 pub task_origin: DevicePoint,
195 pub local_rect: DeviceRect,
196 pub color0: PremultipliedColorF,
197 pub color1: PremultipliedColorF,
198 pub flags: i32,
199 pub widths: DeviceSize,
200 pub radius: DeviceSize,
201 pub clip_params: [f32; 8],
202}
203
204#[derive(Copy, Clone, Debug)]
205#[cfg_attr(feature = "capture", derive(Serialize))]
206#[cfg_attr(feature = "replay", derive(Deserialize))]
207#[repr(C)]
208pub struct ClipMaskInstanceCommon {
209 pub sub_rect: DeviceRect,
210 pub task_origin: DevicePoint,
211 pub screen_origin: DevicePoint,
212 pub device_pixel_scale: f32,
213 pub clip_transform_id: TransformPaletteId,
214 pub prim_transform_id: TransformPaletteId,
215}
216
217#[derive(Clone, Debug)]
218#[cfg_attr(feature = "capture", derive(Serialize))]
219#[cfg_attr(feature = "replay", derive(Deserialize))]
220#[repr(C)]
221pub struct ClipMaskInstanceRect {
222 pub common: ClipMaskInstanceCommon,
223 pub local_pos: LayoutPoint,
224 pub clip_data: ClipData,
225}
226
227#[derive(Clone, Debug)]
228#[cfg_attr(feature = "capture", derive(Serialize))]
229#[cfg_attr(feature = "replay", derive(Deserialize))]
230#[repr(C)]
231pub struct BoxShadowData {
232 pub src_rect_size: LayoutSize,
233 pub clip_mode: i32,
234 pub stretch_mode_x: i32,
235 pub stretch_mode_y: i32,
236 pub dest_rect: LayoutRect,
237}
238
239#[derive(Clone, Debug)]
240#[cfg_attr(feature = "capture", derive(Serialize))]
241#[cfg_attr(feature = "replay", derive(Deserialize))]
242#[repr(C)]
243pub struct ClipMaskInstanceBoxShadow {
244 pub common: ClipMaskInstanceCommon,
245 pub resource_address: GpuCacheAddress,
246 pub shadow_data: BoxShadowData,
247}
248
249#[repr(C)]
251#[derive(Debug, Clone)]
252#[cfg_attr(feature = "capture", derive(Serialize))]
253#[cfg_attr(feature = "replay", derive(Deserialize))]
254pub struct PrimitiveInstanceData {
255 data: [i32; 4],
256}
257
258const UV_TYPE_NORMALIZED: u32 = 0;
261const UV_TYPE_UNNORMALIZED: u32 = 1;
263
264#[derive(Clone, Debug)]
266#[repr(C)]
267pub struct CompositorTransform {
268 pub sx: f32,
269 pub sy: f32,
270 pub tx: f32,
271 pub ty: f32,
272}
273
274impl From<ScaleOffset> for CompositorTransform {
275 fn from(scale_offset: ScaleOffset) -> Self {
276 CompositorTransform {
277 sx: scale_offset.scale.x,
278 sy: scale_offset.scale.y,
279 tx: scale_offset.offset.x,
280 ty: scale_offset.offset.y,
281 }
282 }
283}
284
285#[derive(Clone, Debug)]
289#[repr(C)]
290pub struct CompositeInstance {
291 rect: DeviceRect,
293 clip_rect: DeviceRect,
295 color: PremultipliedColorF,
297
298 _padding: f32,
300 color_space_or_uv_type: f32, yuv_format: f32, yuv_channel_bit_depth: f32,
304
305 uv_rects: [TexelRect; 3],
307
308 flip: (f32, f32),
310
311 rounded_clip_rect: DeviceRect,
313 rounded_clip_radii: [f32; 4],
314}
315
316impl CompositeInstance {
317 pub fn new(
318 rect: DeviceRect,
319 clip_rect: DeviceRect,
320 color: PremultipliedColorF,
321 flip: (bool, bool),
322 clip: Option<&CompositorClip>,
323 ) -> Self {
324 let uv = TexelRect::new(0.0, 0.0, 1.0, 1.0);
325
326 let (rounded_clip_rect, rounded_clip_radii) = Self::vertex_clip_params(clip, rect);
327
328 CompositeInstance {
329 rect,
330 clip_rect,
331 color,
332 _padding: 0.0,
333 color_space_or_uv_type: pack_as_float(UV_TYPE_NORMALIZED),
334 yuv_format: 0.0,
335 yuv_channel_bit_depth: 0.0,
336 uv_rects: [uv, uv, uv],
337 flip: (flip.0.into(), flip.1.into()),
338 rounded_clip_rect,
339 rounded_clip_radii,
340 }
341 }
342
343 pub fn new_rgb(
344 rect: DeviceRect,
345 clip_rect: DeviceRect,
346 color: PremultipliedColorF,
347 uv_rect: TexelRect,
348 normalized_uvs: bool,
349 flip: (bool, bool),
350 clip: Option<&CompositorClip>,
351 ) -> Self {
352 let (rounded_clip_rect, rounded_clip_radii) = Self::vertex_clip_params(clip, rect);
353
354 let uv_type = match normalized_uvs {
355 true => UV_TYPE_NORMALIZED,
356 false => UV_TYPE_UNNORMALIZED,
357 };
358 CompositeInstance {
359 rect,
360 clip_rect,
361 color,
362 _padding: 0.0,
363 color_space_or_uv_type: pack_as_float(uv_type),
364 yuv_format: 0.0,
365 yuv_channel_bit_depth: 0.0,
366 uv_rects: [uv_rect, uv_rect, uv_rect],
367 flip: (flip.0.into(), flip.1.into()),
368 rounded_clip_rect,
369 rounded_clip_radii,
370 }
371 }
372
373 pub fn new_yuv(
374 rect: DeviceRect,
375 clip_rect: DeviceRect,
376 yuv_color_space: YuvRangedColorSpace,
377 yuv_format: YuvFormat,
378 yuv_channel_bit_depth: u32,
379 uv_rects: [TexelRect; 3],
380 flip: (bool, bool),
381 clip: Option<&CompositorClip>,
382 ) -> Self {
383
384 let (rounded_clip_rect, rounded_clip_radii) = Self::vertex_clip_params(clip, rect);
385
386 CompositeInstance {
387 rect,
388 clip_rect,
389 color: PremultipliedColorF::WHITE,
390 _padding: 0.0,
391 color_space_or_uv_type: pack_as_float(yuv_color_space as u32),
392 yuv_format: pack_as_float(yuv_format as u32),
393 yuv_channel_bit_depth: pack_as_float(yuv_channel_bit_depth),
394 uv_rects,
395 flip: (flip.0.into(), flip.1.into()),
396 rounded_clip_rect,
397 rounded_clip_radii,
398 }
399 }
400
401 pub fn get_rgb_features(&self) -> CompositeFeatures {
404 let mut features = CompositeFeatures::empty();
405
406 if self.color_space_or_uv_type == pack_as_float(UV_TYPE_NORMALIZED)
409 && self.uv_rects[0] == TexelRect::new(0.0, 0.0, 1.0, 1.0)
410 {
411 features |= CompositeFeatures::NO_UV_CLAMP;
412 }
413
414 if self.color == PremultipliedColorF::WHITE {
415 features |= CompositeFeatures::NO_COLOR_MODULATION
416 }
417
418 if self.rounded_clip_radii.iter().all(|r| *r <= 0.0) {
420 features |= CompositeFeatures::NO_CLIP_MASK
421 }
422
423 features
424 }
425
426 pub fn get_yuv_features(&self) -> CompositeFeatures {
429 let mut features = CompositeFeatures::empty();
430
431 if self.rounded_clip_radii.iter().all(|r| *r <= 0.0) {
433 features |= CompositeFeatures::NO_CLIP_MASK
434 }
435
436 features
437 }
438
439 fn vertex_clip_params(
440 clip: Option<&CompositorClip>,
441 default_rect: DeviceRect,
442 ) -> (DeviceRect, [f32; 4]) {
443 match clip {
444 Some(clip) => {
445 (
446 clip.rect.cast_unit(),
447 [
448 clip.radius.top_left.width,
449 clip.radius.bottom_left.width,
450 clip.radius.top_right.width,
451 clip.radius.bottom_right.width,
452 ],
453 )
454 }
455 None => {
456 (default_rect, [0.0; 4])
457 }
458 }
459 }
460}
461
462#[derive(Debug, Clone)]
464#[repr(C)]
465pub struct ClearInstance {
466 pub rect: [f32; 4],
467 pub color: [f32; 4],
468}
469
470#[derive(Debug, Copy, Clone)]
471#[cfg_attr(feature = "capture", derive(Serialize))]
472#[cfg_attr(feature = "replay", derive(Deserialize))]
473pub struct PrimitiveHeaderIndex(pub i32);
474
475#[derive(Debug)]
476#[repr(C)]
477#[cfg_attr(feature = "capture", derive(Serialize))]
478#[cfg_attr(feature = "replay", derive(Deserialize))]
479pub struct PrimitiveHeaders {
480 pub headers_int: FrameVec<PrimitiveHeaderI>,
482 pub headers_float: FrameVec<PrimitiveHeaderF>,
484}
485
486impl PrimitiveHeaders {
487 pub fn new(memory: &FrameMemory) -> PrimitiveHeaders {
488 PrimitiveHeaders {
489 headers_int: memory.new_vec(),
490 headers_float: memory.new_vec(),
491 }
492 }
493
494 pub fn push(
496 &mut self,
497 prim_header: &PrimitiveHeader,
498 z: ZBufferId,
499 render_task_address: RenderTaskAddress,
500 user_data: [i32; 4],
501 ) -> PrimitiveHeaderIndex {
502 debug_assert_eq!(self.headers_int.len(), self.headers_float.len());
503 let id = self.headers_float.len();
504
505 self.headers_float.push(PrimitiveHeaderF {
506 local_rect: prim_header.local_rect,
507 local_clip_rect: prim_header.local_clip_rect,
508 });
509
510 self.headers_int.push(PrimitiveHeaderI {
511 z,
512 render_task_address,
513 specific_prim_address: prim_header.specific_prim_address.as_int(),
514 transform_id: prim_header.transform_id,
515 user_data,
516 });
517
518 PrimitiveHeaderIndex(id as i32)
519 }
520}
521
522#[derive(Debug)]
525pub struct PrimitiveHeader {
526 pub local_rect: LayoutRect,
527 pub local_clip_rect: LayoutRect,
528 pub specific_prim_address: GpuCacheAddress,
529 pub transform_id: TransformPaletteId,
530}
531
532#[derive(Debug)]
534#[repr(C)]
535#[cfg_attr(feature = "capture", derive(Serialize))]
536#[cfg_attr(feature = "replay", derive(Deserialize))]
537pub struct PrimitiveHeaderF {
538 pub local_rect: LayoutRect,
539 pub local_clip_rect: LayoutRect,
540}
541
542#[derive(Debug)]
545#[repr(C)]
546#[cfg_attr(feature = "capture", derive(Serialize))]
547#[cfg_attr(feature = "replay", derive(Deserialize))]
548pub struct PrimitiveHeaderI {
549 pub z: ZBufferId,
550 pub specific_prim_address: i32,
551 pub transform_id: TransformPaletteId,
552 pub render_task_address: RenderTaskAddress,
553 pub user_data: [i32; 4],
554}
555
556pub struct GlyphInstance {
557 pub prim_header_index: PrimitiveHeaderIndex,
558}
559
560impl GlyphInstance {
561 pub fn new(
562 prim_header_index: PrimitiveHeaderIndex,
563 ) -> Self {
564 GlyphInstance {
565 prim_header_index,
566 }
567 }
568
569 pub fn build(&self,
573 clip_task: RenderTaskAddress,
574 subpx_dir: SubpixelDirection,
575 glyph_index_in_text_run: i32,
576 glyph_uv_rect: GpuCacheAddress,
577 color_mode: ShaderColorMode,
578 ) -> PrimitiveInstanceData {
579 PrimitiveInstanceData {
580 data: [
581 self.prim_header_index.0 as i32,
582 clip_task.0 as i32,
583 (subpx_dir as u32 as i32) << 24
584 | (color_mode as u32 as i32) << 16
585 | glyph_index_in_text_run,
586 glyph_uv_rect.as_int(),
587 ],
588 }
589 }
590}
591
592pub struct SplitCompositeInstance {
593 pub prim_header_index: PrimitiveHeaderIndex,
594 pub polygons_address: i32,
595 pub z: ZBufferId,
596 pub render_task_address: RenderTaskAddress,
597}
598
599impl From<SplitCompositeInstance> for PrimitiveInstanceData {
600 fn from(instance: SplitCompositeInstance) -> Self {
601 PrimitiveInstanceData {
602 data: [
603 instance.prim_header_index.0,
604 instance.polygons_address,
605 instance.z.0,
606 instance.render_task_address.0,
607 ],
608 }
609 }
610}
611
612#[derive(Copy, Clone)]
613#[cfg_attr(feature = "capture", derive(Serialize))]
614#[cfg_attr(feature = "replay", derive(Deserialize))]
615pub struct QuadInstance {
616 pub dst_task_address: RenderTaskAddress,
617 pub prim_address_i: GpuBufferAddress,
618 pub prim_address_f: GpuBufferAddress,
619 pub quad_flags: u8,
620 pub edge_flags: u8,
621 pub part_index: u8,
622 pub segment_index: u8,
623}
624
625impl From<QuadInstance> for PrimitiveInstanceData {
626 fn from(instance: QuadInstance) -> Self {
627 PrimitiveInstanceData {
635 data: [
636 instance.prim_address_i.as_int(),
637 instance.prim_address_f.as_int(),
638
639 ((instance.quad_flags as i32) << 24) |
640 ((instance.edge_flags as i32) << 16) |
641 ((instance.part_index as i32) << 8) |
642 ((instance.segment_index as i32) << 0),
643
644 instance.dst_task_address.0,
645 ],
646 }
647 }
648}
649
650#[derive(Debug)]
651#[cfg_attr(feature = "capture", derive(Serialize))]
652pub struct QuadSegment {
653 pub rect: LayoutRect,
654 pub task_id: RenderTaskId,
655}
656
657#[derive(Copy, Debug, Clone, PartialEq)]
658#[cfg_attr(feature = "capture", derive(Serialize))]
659#[cfg_attr(feature = "replay", derive(Deserialize))]
660#[repr(u32)]
661pub enum ClipSpace {
662 Raster = 0,
663 Primitive = 1,
664}
665
666impl ClipSpace {
667 pub fn as_int(self) -> u32 {
668 match self {
669 ClipSpace::Raster => 0,
670 ClipSpace::Primitive => 1,
671 }
672 }
673}
674
675#[repr(C)]
676#[derive(Clone)]
677#[cfg_attr(feature = "capture", derive(Serialize))]
678#[cfg_attr(feature = "replay", derive(Deserialize))]
679pub struct MaskInstance {
680 pub prim: PrimitiveInstanceData,
681 pub clip_transform_id: TransformPaletteId,
682 pub clip_address: i32,
683 pub clip_space: u32,
684 pub unused: i32,
685}
686
687
688#[cfg_attr(feature = "capture", derive(Serialize))]
694#[cfg_attr(feature = "replay", derive(Deserialize))]
695#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, MallocSizeOf)]
696pub struct BrushFlags(u16);
697
698bitflags! {
699 impl BrushFlags: u16 {
700 const PERSPECTIVE_INTERPOLATION = 1;
702 const SEGMENT_RELATIVE = 2;
705 const SEGMENT_REPEAT_X = 4;
707 const SEGMENT_REPEAT_Y = 8;
709 const SEGMENT_REPEAT_X_ROUND = 16;
711 const SEGMENT_REPEAT_Y_ROUND = 32;
713 const SEGMENT_REPEAT_X_CENTERED = 64;
716 const SEGMENT_REPEAT_Y_CENTERED = 128;
719 const SEGMENT_NINEPATCH_MIDDLE = 256;
721 const SEGMENT_TEXEL_RECT = 512;
723 const FORCE_AA = 1024;
726 const NORMALIZED_UVS = 2048;
728 }
729}
730
731impl core::fmt::Debug for BrushFlags {
732 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
733 if self.is_empty() {
734 write!(f, "{:#x}", Self::empty().bits())
735 } else {
736 bitflags::parser::to_writer(self, f)
737 }
738 }
739}
740
741pub struct BrushInstance {
743 pub prim_header_index: PrimitiveHeaderIndex,
744 pub clip_task_address: RenderTaskAddress,
745 pub segment_index: i32,
746 pub edge_flags: EdgeAaSegmentMask,
747 pub brush_flags: BrushFlags,
748 pub resource_address: i32,
749}
750
751impl From<BrushInstance> for PrimitiveInstanceData {
752 fn from(instance: BrushInstance) -> Self {
753 PrimitiveInstanceData {
754 data: [
755 instance.prim_header_index.0,
756 instance.clip_task_address.0,
757 instance.segment_index
758 | ((instance.brush_flags.bits() as i32) << 16)
759 | ((instance.edge_flags.bits() as i32) << 28),
760 instance.resource_address,
761 ]
762 }
763 }
764}
765
766#[derive(Copy, Clone, Debug)]
768pub struct ImageBrushData {
769 pub color_mode: ShaderColorMode,
770 pub alpha_type: AlphaType,
771 pub raster_space: RasterizationSpace,
772 pub opacity: f32,
773}
774
775impl ImageBrushData {
776 #[inline]
777 pub fn encode(&self) -> [i32; 4] {
778 [
779 self.color_mode as i32 | ((self.alpha_type as i32) << 16),
780 self.raster_space as i32,
781 get_shader_opacity(self.opacity),
782 0,
783 ]
784 }
785}
786
787#[derive(Copy, Debug, Clone, PartialEq)]
794#[cfg_attr(feature = "capture", derive(Serialize))]
795#[cfg_attr(feature = "replay", derive(Deserialize))]
796#[repr(C)]
797pub struct TransformPaletteId(pub u32);
798
799impl TransformPaletteId {
800 pub const IDENTITY: Self = TransformPaletteId(0);
802
803 pub fn transform_kind(&self) -> TransformedRectKind {
805 if (self.0 >> 23) == 0 {
806 TransformedRectKind::AxisAligned
807 } else {
808 TransformedRectKind::Complex
809 }
810 }
811
812 pub fn override_transform_kind(&self, kind: TransformedRectKind) -> Self {
817 TransformPaletteId((self.0 & 0x7FFFFFu32) | ((kind as u32) << 23))
818 }
819}
820
821#[derive(Debug, Clone)]
823#[cfg_attr(feature = "capture", derive(Serialize))]
824#[cfg_attr(feature = "replay", derive(Deserialize))]
825#[repr(C)]
826pub struct TransformData {
827 transform: LayoutToPictureTransform,
828 inv_transform: PictureToLayoutTransform,
829}
830
831impl TransformData {
832 fn invalid() -> Self {
833 TransformData {
834 transform: LayoutToPictureTransform::identity(),
835 inv_transform: PictureToLayoutTransform::identity(),
836 }
837 }
838}
839
840#[derive(Clone)]
842pub struct TransformMetadata {
843 transform_kind: TransformedRectKind,
844}
845
846impl TransformMetadata {
847 pub fn invalid() -> Self {
848 TransformMetadata {
849 transform_kind: TransformedRectKind::AxisAligned,
850 }
851 }
852}
853
854#[derive(Debug, Hash, Eq, PartialEq)]
855struct RelativeTransformKey {
856 from_index: SpatialNodeIndex,
857 to_index: SpatialNodeIndex,
858}
859
860pub struct TransformPalette {
868 transforms: FrameVec<TransformData>,
869 metadata: Vec<TransformMetadata>,
870 map: FastHashMap<RelativeTransformKey, usize>,
871}
872
873impl TransformPalette {
874 pub fn new(
875 count: usize,
876 memory: &FrameMemory,
877 ) -> Self {
878 let _ = VECS_PER_TRANSFORM;
879
880 let mut transforms = memory.new_vec_with_capacity(count);
881 let mut metadata = Vec::with_capacity(count);
882
883 transforms.push(TransformData::invalid());
884 metadata.push(TransformMetadata::invalid());
885
886 TransformPalette {
887 transforms,
888 metadata,
889 map: FastHashMap::default(),
890 }
891 }
892
893 pub fn finish(self) -> FrameVec<TransformData> {
894 self.transforms
895 }
896
897 fn get_index(
898 &mut self,
899 child_index: SpatialNodeIndex,
900 parent_index: SpatialNodeIndex,
901 spatial_tree: &SpatialTree,
902 ) -> usize {
903 if child_index == parent_index {
904 0
905 } else {
906 let key = RelativeTransformKey {
907 from_index: child_index,
908 to_index: parent_index,
909 };
910
911 let metadata = &mut self.metadata;
912 let transforms = &mut self.transforms;
913
914 *self.map
915 .entry(key)
916 .or_insert_with(|| {
917 let transform = spatial_tree.get_relative_transform(
918 child_index,
919 parent_index,
920 )
921 .into_transform()
922 .with_destination::<PicturePixel>();
923
924 register_transform(
925 metadata,
926 transforms,
927 transform,
928 )
929 })
930 }
931 }
932
933 pub fn get_id(
938 &mut self,
939 from_index: SpatialNodeIndex,
940 to_index: SpatialNodeIndex,
941 spatial_tree: &SpatialTree,
942 ) -> TransformPaletteId {
943 let index = self.get_index(
944 from_index,
945 to_index,
946 spatial_tree,
947 );
948 let transform_kind = self.metadata[index].transform_kind as u32;
949 TransformPaletteId(
950 (index as u32) |
951 (transform_kind << 23)
952 )
953 }
954
955 pub fn get_custom(
956 &mut self,
957 transform: LayoutToPictureTransform,
958 ) -> TransformPaletteId {
959 let index = register_transform(
960 &mut self.metadata,
961 &mut self.transforms,
962 transform,
963 );
964
965 let transform_kind = self.metadata[index].transform_kind as u32;
966 TransformPaletteId(
967 (index as u32) |
968 (transform_kind << 23)
969 )
970 }
971}
972
973#[derive(Debug, Copy, Clone)]
978#[cfg_attr(feature = "capture", derive(Serialize))]
979#[cfg_attr(feature = "replay", derive(Deserialize))]
980pub enum UvRectKind {
981 Rect,
984 Quad {
989 top_left: DeviceHomogeneousVector,
990 top_right: DeviceHomogeneousVector,
991 bottom_left: DeviceHomogeneousVector,
992 bottom_right: DeviceHomogeneousVector,
993 },
994}
995
996#[derive(Debug, Copy, Clone)]
997#[cfg_attr(feature = "capture", derive(Serialize))]
998#[cfg_attr(feature = "replay", derive(Deserialize))]
999pub struct ImageSource {
1000 pub p0: DevicePoint,
1001 pub p1: DevicePoint,
1002 pub user_data: [f32; 4],
1007 pub uv_rect_kind: UvRectKind,
1008}
1009
1010impl ImageSource {
1011 pub fn write_gpu_blocks(&self, request: &mut GpuDataRequest) {
1012 request.push([
1015 self.p0.x,
1016 self.p0.y,
1017 self.p1.x,
1018 self.p1.y,
1019 ]);
1020 request.push(self.user_data);
1021
1022 if let UvRectKind::Quad { top_left, top_right, bottom_left, bottom_right } = self.uv_rect_kind {
1024 request.push(top_left);
1027 request.push(top_right);
1028 request.push(bottom_left);
1029 request.push(bottom_right);
1030 }
1031 }
1032}
1033
1034fn register_transform(
1037 metadatas: &mut Vec<TransformMetadata>,
1038 transforms: &mut FrameVec<TransformData>,
1039 transform: LayoutToPictureTransform,
1040) -> usize {
1041 let inv_transform = transform
1044 .inverse()
1045 .unwrap_or_else(PictureToLayoutTransform::identity);
1046
1047 let metadata = TransformMetadata {
1048 transform_kind: transform.transform_kind()
1049 };
1050 let data = TransformData {
1051 transform,
1052 inv_transform,
1053 };
1054
1055 let index = transforms.len();
1056 metadatas.push(metadata);
1057 transforms.push(data);
1058
1059 index
1060}
1061
1062pub fn get_shader_opacity(opacity: f32) -> i32 {
1063 (opacity * 65535.0).round() as i32
1064}