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