1use api::{BorderRadius, ColorF, ExternalImageId, ImageBufferKind, ImageKey, ImageRendering, YuvFormat, YuvRangedColorSpace};
6use api::units::*;
7use api::ColorDepth;
8use crate::image_source::resolve_image;
9use euclid::Box2D;
10use crate::gpu_cache::GpuCache;
11use crate::gpu_types::{ZBufferId, ZBufferIdGenerator};
12use crate::internal_types::{FrameAllocator, FrameMemory, FrameVec, TextureSource};
13use crate::picture::{ImageDependency, ResolvedSurfaceTexture, TileCacheInstance, TileId, TileSurface};
14use crate::prim_store::DeferredResolve;
15use crate::resource_cache::{ImageRequest, ResourceCache};
16use crate::util::{extract_inner_rect_safe, Preallocator, ScaleOffset};
17use crate::tile_cache::PictureCacheDebugInfo;
18use crate::device::Device;
19use crate::space::SpaceMapper;
20use std::{ops, u64, os::raw::c_void};
21use std::num::NonZeroUsize;
22
23#[cfg_attr(feature = "capture", derive(Serialize))]
30#[cfg_attr(feature = "replay", derive(Deserialize))]
31#[derive(Debug, Copy, Clone, MallocSizeOf, PartialEq)]
32pub enum CompositorSurfaceKind {
33 Blit,
35 Underlay,
37 Overlay,
39}
40
41#[derive(Debug, Clone)]
43#[cfg_attr(feature = "capture", derive(Serialize))]
44#[cfg_attr(feature = "replay", derive(Deserialize))]
45pub enum NativeSurfaceOperationDetails {
46 CreateSurface {
47 id: NativeSurfaceId,
48 virtual_offset: DeviceIntPoint,
49 tile_size: DeviceIntSize,
50 is_opaque: bool,
51 },
52 CreateExternalSurface {
53 id: NativeSurfaceId,
54 is_opaque: bool,
55 },
56 CreateBackdropSurface {
57 id: NativeSurfaceId,
58 color: ColorF,
59 },
60 DestroySurface {
61 id: NativeSurfaceId,
62 },
63 CreateTile {
64 id: NativeTileId,
65 },
66 DestroyTile {
67 id: NativeTileId,
68 },
69 AttachExternalImage {
70 id: NativeSurfaceId,
71 external_image: ExternalImageId,
72 }
73}
74
75#[derive(Debug, Clone)]
77#[cfg_attr(feature = "capture", derive(Serialize))]
78#[cfg_attr(feature = "replay", derive(Deserialize))]
79pub struct NativeSurfaceOperation {
80 pub details: NativeSurfaceOperationDetails,
81}
82
83#[cfg_attr(feature = "capture", derive(Serialize))]
87#[cfg_attr(feature = "replay", derive(Deserialize))]
88#[derive(Clone)]
89pub enum CompositeTileSurface {
90 Texture {
91 surface: ResolvedSurfaceTexture,
92 },
93 Color {
94 color: ColorF,
95 },
96 Clear,
97 ExternalSurface {
98 external_surface_index: ResolvedExternalSurfaceIndex,
99 },
100}
101
102#[derive(Debug, Copy, Clone, PartialEq)]
104pub enum CompositeSurfaceFormat {
105 Rgba,
106 Yuv,
107}
108
109bitflags! {
110 #[derive(Debug, Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
113 pub struct CompositeFeatures: u8 {
114 const NO_UV_CLAMP = 1 << 0;
117 const NO_COLOR_MODULATION = 1 << 1;
119 const NO_CLIP_MASK = 1 << 2;
121 }
122}
123
124#[derive(Copy, Clone, Debug, PartialEq)]
125#[cfg_attr(feature = "capture", derive(Serialize))]
126#[cfg_attr(feature = "replay", derive(Deserialize))]
127pub enum TileKind {
128 Opaque,
129 Alpha,
130 Clear,
131}
132
133#[cfg_attr(feature = "capture", derive(Serialize))]
135#[cfg_attr(feature = "replay", derive(Deserialize))]
136#[derive(Debug, Copy, Clone)]
137pub struct CompositorTransformIndex(usize);
138
139impl CompositorTransformIndex {
140 pub const INVALID: CompositorTransformIndex = CompositorTransformIndex(!0);
141}
142
143#[cfg_attr(feature = "capture", derive(Serialize))]
145#[cfg_attr(feature = "replay", derive(Deserialize))]
146#[derive(Debug, Copy, Clone)]
147pub struct CompositorClipIndex(NonZeroUsize);
148
149#[cfg_attr(feature = "capture", derive(Serialize))]
151#[cfg_attr(feature = "replay", derive(Deserialize))]
152#[derive(Clone)]
153pub struct CompositeTile {
154 pub surface: CompositeTileSurface,
155 pub local_rect: PictureRect,
156 pub local_valid_rect: PictureRect,
157 pub local_dirty_rect: PictureRect,
158 pub device_clip_rect: DeviceRect,
159 pub z_id: ZBufferId,
160 pub kind: TileKind,
161 pub transform_index: CompositorTransformIndex,
162 pub clip_index: Option<CompositorClipIndex>,
163}
164
165pub fn tile_kind(surface: &CompositeTileSurface, is_opaque: bool) -> TileKind {
166 match surface {
167 CompositeTileSurface::Color { .. } => TileKind::Opaque,
170 CompositeTileSurface::Clear => TileKind::Clear,
172 CompositeTileSurface::Texture { .. }
173 | CompositeTileSurface::ExternalSurface { .. } => {
174 if is_opaque {
177 TileKind::Opaque
178 } else {
179 TileKind::Alpha
180 }
181 }
182 }
183}
184
185pub enum ExternalSurfaceDependency {
186 Yuv {
187 image_dependencies: [ImageDependency; 3],
188 color_space: YuvRangedColorSpace,
189 format: YuvFormat,
190 channel_bit_depth: u32,
191 },
192 Rgb {
193 image_dependency: ImageDependency,
194 },
195}
196
197pub struct ExternalSurfaceDescriptor {
201 pub local_surface_size: LayoutSize,
204 pub local_rect: PictureRect,
205 pub local_clip_rect: PictureRect,
206 pub clip_rect: DeviceRect,
207 pub transform_index: CompositorTransformIndex,
208 pub image_rendering: ImageRendering,
209 pub z_id: ZBufferId,
210 pub dependency: ExternalSurfaceDependency,
211 pub native_surface_id: Option<NativeSurfaceId>,
214 pub update_params: Option<DeviceIntSize>,
217 pub external_image_id: Option<ExternalImageId>,
219}
220
221impl ExternalSurfaceDescriptor {
222 pub fn get_occluder_rect(
224 &self,
225 local_clip_rect: &PictureRect,
226 map_pic_to_world: &SpaceMapper<PicturePixel, WorldPixel>,
227 ) -> Option<WorldRect> {
228 let local_surface_rect = self
229 .local_rect
230 .intersection(&self.local_clip_rect)
231 .and_then(|r| {
232 r.intersection(local_clip_rect)
233 });
234
235 local_surface_rect.map(|local_surface_rect| {
236 map_pic_to_world
237 .map(&local_surface_rect)
238 .expect("bug: unable to map external surface to world space")
239 })
240 }
241}
242
243#[cfg_attr(feature = "capture", derive(Serialize))]
245#[cfg_attr(feature = "replay", derive(Deserialize))]
246#[derive(Debug, Copy, Clone)]
247pub struct ExternalPlaneDescriptor {
248 pub texture: TextureSource,
249 pub uv_rect: TexelRect,
250}
251
252impl ExternalPlaneDescriptor {
253 fn invalid() -> Self {
254 ExternalPlaneDescriptor {
255 texture: TextureSource::Invalid,
256 uv_rect: TexelRect::invalid(),
257 }
258 }
259}
260
261#[cfg_attr(feature = "capture", derive(Serialize))]
262#[cfg_attr(feature = "replay", derive(Deserialize))]
263#[derive(Debug, Copy, Clone, PartialEq)]
264pub struct ResolvedExternalSurfaceIndex(pub usize);
265
266impl ResolvedExternalSurfaceIndex {
267 pub const INVALID: ResolvedExternalSurfaceIndex = ResolvedExternalSurfaceIndex(usize::MAX);
268}
269
270#[cfg_attr(feature = "capture", derive(Serialize))]
271#[cfg_attr(feature = "replay", derive(Deserialize))]
272pub enum ResolvedExternalSurfaceColorData {
273 Yuv {
274 image_dependencies: [ImageDependency; 3],
276 planes: [ExternalPlaneDescriptor; 3],
277 color_space: YuvRangedColorSpace,
278 format: YuvFormat,
279 channel_bit_depth: u32,
280 },
281 Rgb {
282 image_dependency: ImageDependency,
283 plane: ExternalPlaneDescriptor,
284 },
285}
286
287#[cfg_attr(feature = "capture", derive(Serialize))]
292#[cfg_attr(feature = "replay", derive(Deserialize))]
293pub struct ResolvedExternalSurface {
294 pub color_data: ResolvedExternalSurfaceColorData,
295 pub image_buffer_kind: ImageBufferKind,
296 pub update_params: Option<(NativeSurfaceId, DeviceIntSize)>,
298 pub external_image_id: Option<ExternalImageId>,
300}
301
302pub enum CompositorConfig {
305 Draw {
307 max_partial_present_rects: usize,
312 draw_previous_partial_present_regions: bool,
316 partial_present: Option<Box<dyn PartialPresentCompositor>>,
319 },
320 Layer {
321 compositor: Box<dyn LayerCompositor>,
325 },
326 Native {
330 compositor: Box<dyn Compositor>,
332 }
333}
334
335impl CompositorConfig {
336 pub fn compositor(&mut self) -> Option<&mut Box<dyn Compositor>> {
337 match self {
338 CompositorConfig::Native { ref mut compositor, .. } => {
339 Some(compositor)
340 }
341 CompositorConfig::Draw { .. } | CompositorConfig::Layer { .. } => {
342 None
343 }
344 }
345 }
346
347 pub fn partial_present(&mut self) -> Option<&mut Box<dyn PartialPresentCompositor>> {
348 match self {
349 CompositorConfig::Native { .. } => {
350 None
351 }
352 CompositorConfig::Draw { ref mut partial_present, .. } => {
353 partial_present.as_mut()
354 }
355 CompositorConfig::Layer { .. } => {
356 None
357 }
358 }
359 }
360
361 pub fn layer_compositor(&mut self) -> Option<&mut Box<dyn LayerCompositor>> {
362 match self {
363 CompositorConfig::Native { .. } => {
364 None
365 }
366 CompositorConfig::Draw { .. } => {
367 None
368 }
369 CompositorConfig::Layer { ref mut compositor } => {
370 Some(compositor)
371 }
372 }
373 }
374}
375
376impl Default for CompositorConfig {
377 fn default() -> Self {
379 CompositorConfig::Draw {
380 max_partial_present_rects: 0,
381 draw_previous_partial_present_regions: false,
382 partial_present: None,
383 }
384 }
385}
386
387#[cfg_attr(feature = "capture", derive(Serialize))]
391#[cfg_attr(feature = "replay", derive(Deserialize))]
392#[derive(Debug, Copy, Clone, PartialEq)]
393pub enum CompositorKind {
394 Draw {
396 max_partial_present_rects: usize,
398 draw_previous_partial_present_regions: bool,
400 },
401 Layer {
402
403 },
404 Native {
406 capabilities: CompositorCapabilities,
408 },
409}
410
411impl Default for CompositorKind {
412 fn default() -> Self {
414 CompositorKind::Draw {
415 max_partial_present_rects: 0,
416 draw_previous_partial_present_regions: false,
417 }
418 }
419}
420
421impl CompositorKind {
422 pub fn get_virtual_surface_size(&self) -> i32 {
423 match self {
424 CompositorKind::Draw { .. } | CompositorKind::Layer { .. }=> 0,
425 CompositorKind::Native { capabilities, .. } => capabilities.virtual_surface_size,
426 }
427 }
428
429 pub fn should_redraw_on_invalidation(&self) -> bool {
430 match self {
431 CompositorKind::Draw { max_partial_present_rects, .. } => {
432 *max_partial_present_rects > 0
434 }
435 CompositorKind::Layer { } => false, CompositorKind::Native { capabilities, .. } => capabilities.redraw_on_invalidation,
437 }
438 }
439}
440
441#[cfg_attr(feature = "capture", derive(Serialize))]
444#[cfg_attr(feature = "replay", derive(Deserialize))]
445#[derive(PartialEq, Clone)]
446pub enum TileSurfaceKind {
447 Texture,
448 Color {
449 color: ColorF,
450 },
451 Clear,
452}
453
454impl From<&TileSurface> for TileSurfaceKind {
455 fn from(surface: &TileSurface) -> Self {
456 match surface {
457 TileSurface::Texture { .. } => TileSurfaceKind::Texture,
458 TileSurface::Color { color } => TileSurfaceKind::Color { color: *color },
459 TileSurface::Clear => TileSurfaceKind::Clear,
460 }
461 }
462}
463
464#[cfg_attr(feature = "capture", derive(Serialize))]
467#[cfg_attr(feature = "replay", derive(Deserialize))]
468#[derive(PartialEq, Clone)]
469pub struct CompositeTileDescriptor {
470 pub tile_id: TileId,
471 pub surface_kind: TileSurfaceKind,
472}
473
474#[cfg_attr(feature = "capture", derive(Serialize))]
477#[cfg_attr(feature = "replay", derive(Deserialize))]
478#[derive(Debug, Copy, Clone)]
479pub enum CompositorSurfaceUsage {
480 Content,
481 External {
482 image_key: ImageKey,
483 external_image_id: ExternalImageId,
484 transform_index: CompositorTransformIndex,
485 },
486 DebugOverlay,
487}
488
489impl CompositorSurfaceUsage {
490 pub fn matches(&self, other: &CompositorSurfaceUsage) -> bool {
492 match (self, other) {
493 (CompositorSurfaceUsage::Content, CompositorSurfaceUsage::Content) => true,
495
496 (CompositorSurfaceUsage::Content, CompositorSurfaceUsage::External { .. }) |
497 (CompositorSurfaceUsage::External { .. }, CompositorSurfaceUsage::Content) => false,
498
499 (CompositorSurfaceUsage::External { image_key: key1, .. }, CompositorSurfaceUsage::External { image_key: key2, .. }) => {
501 key1 == key2
502 }
503
504 (CompositorSurfaceUsage::DebugOverlay, CompositorSurfaceUsage::DebugOverlay) => true,
505
506 (CompositorSurfaceUsage::DebugOverlay, _) | (_, CompositorSurfaceUsage::DebugOverlay) => false,
507 }
508 }
509}
510
511#[cfg_attr(feature = "capture", derive(Serialize))]
513#[cfg_attr(feature = "replay", derive(Deserialize))]
514#[derive(PartialEq, Clone)]
515pub struct CompositeSurfaceDescriptor {
516 pub surface_id: Option<NativeSurfaceId>,
517 pub clip_rect: DeviceRect,
518 pub transform: CompositorSurfaceTransform,
519 pub image_dependencies: [ImageDependency; 3],
524 pub image_rendering: ImageRendering,
525 pub tile_descriptors: Vec<CompositeTileDescriptor>,
527 pub rounded_clip_rect: DeviceRect,
528 pub rounded_clip_radii: ClipRadius,
529}
530
531#[cfg_attr(feature = "capture", derive(Serialize))]
534#[cfg_attr(feature = "replay", derive(Deserialize))]
535#[derive(PartialEq, Clone)]
536pub struct CompositeDescriptor {
537 pub surfaces: Vec<CompositeSurfaceDescriptor>,
538 pub external_surfaces_rect: DeviceRect,
539}
540
541impl CompositeDescriptor {
542 pub fn empty() -> Self {
544 CompositeDescriptor {
545 surfaces: Vec::new(),
546 external_surfaces_rect: DeviceRect::zero(),
547 }
548 }
549}
550
551pub struct CompositeStatePreallocator {
552 tiles: Preallocator,
553 external_surfaces: Preallocator,
554 occluders: Preallocator,
555 occluders_events: Preallocator,
556 occluders_active: Preallocator,
557 descriptor_surfaces: Preallocator,
558}
559
560impl CompositeStatePreallocator {
561 pub fn record(&mut self, state: &CompositeState) {
562 self.tiles.record_vec(&state.tiles);
563 self.external_surfaces.record_vec(&state.external_surfaces);
564 self.occluders.record_vec(&state.occluders.occluders);
565 self.occluders_events.record_vec(&state.occluders.scratch.events);
566 self.occluders_active.record_vec(&state.occluders.scratch.active);
567 self.descriptor_surfaces.record_vec(&state.descriptor.surfaces);
568 }
569
570 pub fn preallocate(&self, state: &mut CompositeState) {
571 self.tiles.preallocate_framevec(&mut state.tiles);
572 self.external_surfaces.preallocate_framevec(&mut state.external_surfaces);
573 self.occluders.preallocate_framevec(&mut state.occluders.occluders);
574 self.occluders_events.preallocate_framevec(&mut state.occluders.scratch.events);
575 self.occluders_active.preallocate_framevec(&mut state.occluders.scratch.active);
576 self.descriptor_surfaces.preallocate_vec(&mut state.descriptor.surfaces);
577 }
578}
579
580impl Default for CompositeStatePreallocator {
581 fn default() -> Self {
582 CompositeStatePreallocator {
583 tiles: Preallocator::new(56),
584 external_surfaces: Preallocator::new(0),
585 occluders: Preallocator::new(16),
586 occluders_events: Preallocator::new(32),
587 occluders_active: Preallocator::new(16),
588 descriptor_surfaces: Preallocator::new(8),
589 }
590 }
591}
592
593#[cfg_attr(feature = "capture", derive(Serialize))]
600#[cfg_attr(feature = "replay", derive(Deserialize))]
601pub struct CompositorTransform {
602 local_to_raster: ScaleOffset,
604 raster_to_device: ScaleOffset,
606 local_to_device: ScaleOffset,
608}
609
610#[cfg_attr(feature = "capture", derive(Serialize))]
611#[cfg_attr(feature = "replay", derive(Deserialize))]
612pub struct CompositorClip {
613 pub rect: DeviceRect,
614 pub radius: BorderRadius,
615}
616
617#[cfg_attr(feature = "capture", derive(Serialize))]
619#[cfg_attr(feature = "replay", derive(Deserialize))]
620pub struct CompositeState {
621 pub tiles: FrameVec<CompositeTile>,
628 pub external_surfaces: FrameVec<ResolvedExternalSurface>,
630 pub z_generator: ZBufferIdGenerator,
632 pub dirty_rects_are_valid: bool,
639 pub compositor_kind: CompositorKind,
641 pub occluders: Occluders,
643 pub descriptor: CompositeDescriptor,
645 pub picture_cache_debug: PictureCacheDebugInfo,
647 pub transforms: FrameVec<CompositorTransform>,
649 low_quality_pinch_zoom: bool,
651 pub clips: FrameVec<CompositorClip>,
653}
654
655impl CompositeState {
656 pub fn new(
659 compositor_kind: CompositorKind,
660 max_depth_ids: i32,
661 dirty_rects_are_valid: bool,
662 low_quality_pinch_zoom: bool,
663 memory: &FrameMemory,
664 ) -> Self {
665 let mut clips = memory.new_vec();
668 clips.push(CompositorClip {
669 rect: DeviceRect::zero(),
670 radius: BorderRadius::zero(),
671 });
672
673 CompositeState {
674 tiles: memory.new_vec(),
675 z_generator: ZBufferIdGenerator::new(max_depth_ids),
676 dirty_rects_are_valid,
677 compositor_kind,
678 occluders: Occluders::new(memory),
679 descriptor: CompositeDescriptor::empty(),
680 external_surfaces: memory.new_vec(),
681 picture_cache_debug: PictureCacheDebugInfo::new(),
682 transforms: memory.new_vec(),
683 low_quality_pinch_zoom,
684 clips,
685 }
686 }
687
688 fn compositor_clip_params(
689 &self,
690 clip_index: Option<CompositorClipIndex>,
691 default_rect: DeviceRect,
692 ) -> (DeviceRect, ClipRadius) {
693 match clip_index {
694 Some(clip_index) => {
695 let clip = self.get_compositor_clip(clip_index);
696
697 (
698 clip.rect.cast_unit(),
699 ClipRadius {
700 top_left: clip.radius.top_left.width,
701 top_right: clip.radius.top_right.width,
702 bottom_left: clip.radius.bottom_left.width,
703 bottom_right: clip.radius.bottom_right.width,
704 }
705 )
706 }
707 None => {
708 (default_rect, ClipRadius::EMPTY)
709 }
710 }
711 }
712
713 pub fn register_transform(
715 &mut self,
716 local_to_raster: ScaleOffset,
717 raster_to_device: ScaleOffset,
718 ) -> CompositorTransformIndex {
719 let index = CompositorTransformIndex(self.transforms.len());
720
721 let local_to_device = local_to_raster.then(&raster_to_device);
722
723 self.transforms.push(CompositorTransform {
724 local_to_raster,
725 raster_to_device,
726 local_to_device,
727 });
728
729 index
730 }
731
732 pub fn register_clip(
734 &mut self,
735 rect: DeviceRect,
736 radius: BorderRadius,
737 ) -> CompositorClipIndex {
738 let index = CompositorClipIndex(NonZeroUsize::new(self.clips.len()).expect("bug"));
739
740 self.clips.push(CompositorClip {
741 rect,
742 radius,
743 });
744
745 index
746 }
747
748 pub fn get_device_rect(
750 &self,
751 local_rect: &PictureRect,
752 transform_index: CompositorTransformIndex,
753 ) -> DeviceRect {
754 let transform = &self.transforms[transform_index.0];
755 transform.local_to_device.map_rect(&local_rect).round()
756 }
757
758 pub fn get_surface_rect<T>(
761 &self,
762 local_sub_rect: &Box2D<f32, T>,
763 local_bounds: &Box2D<f32, T>,
764 transform_index: CompositorTransformIndex,
765 ) -> DeviceRect {
766 let transform = &self.transforms[transform_index.0];
767
768 let surface_bounds = transform.local_to_raster.map_rect(&local_bounds);
769 let surface_rect = transform.local_to_raster.map_rect(&local_sub_rect);
770
771 surface_rect
772 .round_out()
773 .translate(-surface_bounds.min.to_vector())
774 .round_out()
775 .intersection(&surface_bounds.size().round().into())
776 .unwrap_or_else(DeviceRect::zero)
777 }
778
779 pub fn get_device_transform(
781 &self,
782 transform_index: CompositorTransformIndex,
783 ) -> ScaleOffset {
784 let transform = &self.transforms[transform_index.0];
785 transform.local_to_device
786 }
787
788 pub fn get_compositor_transform(
790 &self,
791 transform_index: CompositorTransformIndex,
792 ) -> ScaleOffset {
793 let transform = &self.transforms[transform_index.0];
794 transform.raster_to_device
795 }
796
797 pub fn get_compositor_clip(
799 &self,
800 clip_index: CompositorClipIndex,
801 ) -> &CompositorClip {
802 &self.clips[clip_index.0.get()]
803 }
804
805 pub fn register_occluder(
808 &mut self,
809 z_id: ZBufferId,
810 rect: WorldRect,
811 compositor_clip: Option<CompositorClipIndex>,
812 ) {
813 let rect = match compositor_clip {
814 Some(clip_index) => {
815 let clip = self.get_compositor_clip(clip_index);
816
817 let inner_rect = match extract_inner_rect_safe(
818 &clip.rect,
819 &clip.radius,
820 ) {
821 Some(rect) => rect,
822 None => return,
823 };
824
825 match inner_rect.cast_unit().intersection(&rect) {
826 Some(rect) => rect,
827 None => return,
828 }
829 }
830 None => {
831 rect
832 }
833 };
834
835 let world_rect = rect.round().to_i32();
836
837 self.occluders.push(world_rect, z_id);
838 }
839
840 fn push_compositor_surface(
842 &mut self,
843 external_surface: &ExternalSurfaceDescriptor,
844 is_opaque: bool,
845 device_clip_rect: DeviceRect,
846 resource_cache: &ResourceCache,
847 gpu_cache: &mut GpuCache,
848 deferred_resolves: &mut FrameVec<DeferredResolve>,
849 clip_index: Option<CompositorClipIndex>,
850 ) {
851 let clip_rect = external_surface
852 .clip_rect
853 .intersection(&device_clip_rect)
854 .unwrap_or_else(DeviceRect::zero);
855
856 if clip_rect.is_empty() {
858 return;
859 }
860
861 let required_plane_count =
862 match external_surface.dependency {
863 ExternalSurfaceDependency::Yuv { format, .. } => {
864 format.get_plane_num()
865 },
866 ExternalSurfaceDependency::Rgb { .. } => {
867 1
868 }
869 };
870
871 let mut image_dependencies = [ImageDependency::INVALID; 3];
872
873 for i in 0 .. required_plane_count {
874 let dependency = match external_surface.dependency {
875 ExternalSurfaceDependency::Yuv { image_dependencies, .. } => {
876 image_dependencies[i]
877 },
878 ExternalSurfaceDependency::Rgb { image_dependency, .. } => {
879 image_dependency
880 }
881 };
882 image_dependencies[i] = dependency;
883 }
884
885 let needs_external_surface_update = match self.compositor_kind {
889 CompositorKind::Draw { .. } | CompositorKind::Layer { .. } => true,
890 _ => external_surface.update_params.is_some(),
891 };
892 let external_surface_index = if needs_external_surface_update {
893 let external_surface_index = self.compute_external_surface_dependencies(
894 &external_surface,
895 &image_dependencies,
896 required_plane_count,
897 resource_cache,
898 gpu_cache,
899 deferred_resolves,
900 );
901 if external_surface_index == ResolvedExternalSurfaceIndex::INVALID {
902 return;
903 }
904 external_surface_index
905 } else {
906 ResolvedExternalSurfaceIndex::INVALID
907 };
908
909 let surface = CompositeTileSurface::ExternalSurface { external_surface_index };
910 let local_rect = external_surface.local_surface_size.cast_unit().into();
911
912 let tile = CompositeTile {
913 kind: tile_kind(&surface, is_opaque),
914 surface,
915 local_rect,
916 local_valid_rect: local_rect,
917 local_dirty_rect: local_rect,
918 device_clip_rect: clip_rect,
919 z_id: external_surface.z_id,
920 transform_index: external_surface.transform_index,
921 clip_index,
922 };
923
924 let (rounded_clip_rect, rounded_clip_radii) = self.compositor_clip_params(
925 clip_index,
926 clip_rect,
927 );
928
929 self.descriptor.surfaces.push(
933 CompositeSurfaceDescriptor {
934 surface_id: external_surface.native_surface_id,
935 clip_rect,
936 transform: self.get_compositor_transform(external_surface.transform_index),
937 image_dependencies: image_dependencies,
938 image_rendering: external_surface.image_rendering,
939 tile_descriptors: Vec::new(),
940 rounded_clip_rect,
941 rounded_clip_radii,
942 }
943 );
944
945 let device_rect =
946 self.get_device_rect(&local_rect, external_surface.transform_index);
947 self.descriptor.external_surfaces_rect =
948 self.descriptor.external_surfaces_rect.union(&device_rect);
949
950 self.tiles.push(tile);
951 }
952
953 pub fn push_surface(
955 &mut self,
956 tile_cache: &TileCacheInstance,
957 device_clip_rect: DeviceRect,
958 resource_cache: &ResourceCache,
959 gpu_cache: &mut GpuCache,
960 deferred_resolves: &mut FrameVec<DeferredResolve>,
961 ) {
962 let slice_transform = self.get_compositor_transform(tile_cache.transform_index);
963
964 let image_rendering = if self.low_quality_pinch_zoom {
965 ImageRendering::Auto
966 } else {
967 ImageRendering::CrispEdges
968 };
969
970 if let Some(backdrop_surface) = &tile_cache.backdrop_surface {
971 let (rounded_clip_rect, rounded_clip_radii) = self.compositor_clip_params(
972 tile_cache.compositor_clip,
973 backdrop_surface.device_rect,
974 );
975
976 self.descriptor.surfaces.push(
978 CompositeSurfaceDescriptor {
979 surface_id: Some(backdrop_surface.id),
980 clip_rect: backdrop_surface.device_rect,
981 transform: slice_transform,
982 image_dependencies: [ImageDependency::INVALID; 3],
983 image_rendering,
984 tile_descriptors: Vec::new(),
985 rounded_clip_rect,
986 rounded_clip_radii,
987 }
988 );
989 }
990
991 for underlay in &tile_cache.underlays {
993 self.push_compositor_surface(
994 underlay,
995 true,
996 device_clip_rect,
997 resource_cache,
998 gpu_cache,
999 deferred_resolves,
1000 tile_cache.compositor_clip,
1001 );
1002 }
1003
1004 for sub_slice in &tile_cache.sub_slices {
1005 let mut surface_device_rect = DeviceRect::zero();
1006
1007 for tile in sub_slice.tiles.values() {
1008 if !tile.is_visible {
1009 continue;
1011 }
1012
1013 surface_device_rect = surface_device_rect.union(&tile.device_valid_rect);
1023 }
1024
1025 self.tiles.extend_from_slice(&sub_slice.composite_tiles);
1027
1028 let surface_clip_rect = device_clip_rect
1033 .intersection(&surface_device_rect)
1034 .unwrap_or(DeviceRect::zero());
1035
1036 if !surface_clip_rect.is_empty() {
1038 let (rounded_clip_rect, rounded_clip_radii) = self.compositor_clip_params(
1039 tile_cache.compositor_clip,
1040 surface_clip_rect,
1041 );
1042
1043 if !sub_slice.opaque_tile_descriptors.is_empty() {
1045 self.descriptor.surfaces.push(
1046 CompositeSurfaceDescriptor {
1047 surface_id: sub_slice.native_surface.as_ref().map(|s| s.opaque),
1048 clip_rect: surface_clip_rect,
1049 transform: slice_transform,
1050 image_dependencies: [ImageDependency::INVALID; 3],
1051 image_rendering,
1052 tile_descriptors: sub_slice.opaque_tile_descriptors.clone(),
1053 rounded_clip_rect,
1054 rounded_clip_radii,
1055 }
1056 );
1057 }
1058
1059 if !sub_slice.alpha_tile_descriptors.is_empty() {
1061 self.descriptor.surfaces.push(
1062 CompositeSurfaceDescriptor {
1063 surface_id: sub_slice.native_surface.as_ref().map(|s| s.alpha),
1064 clip_rect: surface_clip_rect,
1065 transform: slice_transform,
1066 image_dependencies: [ImageDependency::INVALID; 3],
1067 image_rendering,
1068 tile_descriptors: sub_slice.alpha_tile_descriptors.clone(),
1069 rounded_clip_rect,
1070 rounded_clip_radii,
1071 }
1072 );
1073 }
1074 }
1075
1076 for compositor_surface in &sub_slice.compositor_surfaces {
1079 self.push_compositor_surface(
1080 &compositor_surface.descriptor,
1081 compositor_surface.is_opaque,
1082 device_clip_rect,
1083 resource_cache,
1084 gpu_cache,
1085 deferred_resolves,
1086 tile_cache.compositor_clip,
1087 );
1088 }
1089 }
1090 }
1091
1092 pub fn update_dirty_rect_validity(
1095 &mut self,
1096 old_descriptor: &CompositeDescriptor,
1097 ) {
1098 if old_descriptor.surfaces.len() != self.descriptor.surfaces.len() {
1104 self.dirty_rects_are_valid = false;
1105 return;
1106 }
1107
1108 if !self
1113 .descriptor
1114 .external_surfaces_rect
1115 .contains_box(&old_descriptor.external_surfaces_rect)
1116 {
1117 self.dirty_rects_are_valid = false;
1118 return;
1119 }
1120 }
1121
1122 fn compute_external_surface_dependencies(
1123 &mut self,
1124 external_surface: &ExternalSurfaceDescriptor,
1125 image_dependencies: &[ImageDependency; 3],
1126 required_plane_count: usize,
1127 resource_cache: &ResourceCache,
1128 gpu_cache: &mut GpuCache,
1129 deferred_resolves: &mut FrameVec<DeferredResolve>,
1130 ) -> ResolvedExternalSurfaceIndex {
1131 let mut planes = [
1132 ExternalPlaneDescriptor::invalid(),
1133 ExternalPlaneDescriptor::invalid(),
1134 ExternalPlaneDescriptor::invalid(),
1135 ];
1136
1137 let mut valid_plane_count = 0;
1138 for i in 0 .. required_plane_count {
1139 let request = ImageRequest {
1140 key: image_dependencies[i].key,
1141 rendering: external_surface.image_rendering,
1142 tile: None,
1143 };
1144
1145 let cache_item = resolve_image(
1146 request,
1147 resource_cache,
1148 gpu_cache,
1149 deferred_resolves,
1150 );
1151
1152 if cache_item.texture_id != TextureSource::Invalid {
1153 valid_plane_count += 1;
1154 let plane = &mut planes[i];
1155 *plane = ExternalPlaneDescriptor {
1156 texture: cache_item.texture_id,
1157 uv_rect: cache_item.uv_rect.into(),
1158 };
1159 }
1160 }
1161
1162 if valid_plane_count < required_plane_count {
1164 warn!("Warnings: skip a YUV/RGB compositor surface, found {}/{} valid images",
1165 valid_plane_count,
1166 required_plane_count,
1167 );
1168 return ResolvedExternalSurfaceIndex::INVALID;
1169 }
1170
1171 let external_surface_index = ResolvedExternalSurfaceIndex(self.external_surfaces.len());
1172
1173 let update_params = external_surface.update_params.map(|surface_size| {
1177 (
1178 external_surface.native_surface_id.expect("bug: no native surface!"),
1179 surface_size
1180 )
1181 });
1182
1183 match external_surface.dependency {
1184 ExternalSurfaceDependency::Yuv{ color_space, format, channel_bit_depth, .. } => {
1185
1186 let image_buffer_kind = planes[0].texture.image_buffer_kind();
1187
1188 self.external_surfaces.push(ResolvedExternalSurface {
1189 color_data: ResolvedExternalSurfaceColorData::Yuv {
1190 image_dependencies: *image_dependencies,
1191 planes,
1192 color_space,
1193 format,
1194 channel_bit_depth,
1195 },
1196 image_buffer_kind,
1197 update_params,
1198 external_image_id: external_surface.external_image_id,
1199 });
1200 },
1201 ExternalSurfaceDependency::Rgb { .. } => {
1202 let image_buffer_kind = planes[0].texture.image_buffer_kind();
1203
1204 self.external_surfaces.push(ResolvedExternalSurface {
1205 color_data: ResolvedExternalSurfaceColorData::Rgb {
1206 image_dependency: image_dependencies[0],
1207 plane: planes[0],
1208 },
1209 image_buffer_kind,
1210 update_params,
1211 external_image_id: external_surface.external_image_id,
1212 });
1213 },
1214 }
1215 external_surface_index
1216 }
1217
1218 pub fn end_frame(&mut self) {
1219 self.tiles.sort_by_key(|tile| tile.z_id.0);
1221 }
1222}
1223
1224#[repr(C)]
1226#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
1227#[cfg_attr(feature = "capture", derive(Serialize))]
1228#[cfg_attr(feature = "replay", derive(Deserialize))]
1229pub struct NativeSurfaceId(pub u64);
1230
1231impl NativeSurfaceId {
1232 pub const DEBUG_OVERLAY: NativeSurfaceId = NativeSurfaceId(u64::MAX);
1234}
1235
1236#[repr(C)]
1237#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
1238#[cfg_attr(feature = "capture", derive(Serialize))]
1239#[cfg_attr(feature = "replay", derive(Deserialize))]
1240pub struct NativeTileId {
1241 pub surface_id: NativeSurfaceId,
1242 pub x: i32,
1243 pub y: i32,
1244}
1245
1246impl NativeTileId {
1247 pub const DEBUG_OVERLAY: NativeTileId = NativeTileId {
1249 surface_id: NativeSurfaceId::DEBUG_OVERLAY,
1250 x: 0,
1251 y: 0,
1252 };
1253}
1254
1255#[repr(C)]
1258#[derive(Copy, Clone)]
1259pub struct NativeSurfaceInfo {
1260 pub origin: DeviceIntPoint,
1266 pub fbo_id: u32,
1274}
1275
1276#[repr(C)]
1277#[derive(Debug, Copy, Clone)]
1278pub struct WindowProperties {
1279 pub is_opaque: bool,
1280}
1281
1282impl Default for WindowProperties {
1283 fn default() -> Self {
1284 WindowProperties {
1285 is_opaque: true,
1286 }
1287 }
1288}
1289
1290#[repr(C)]
1291#[derive(Debug, Copy, Clone, PartialEq)]
1292#[cfg_attr(feature = "capture", derive(Serialize))]
1293#[cfg_attr(feature = "replay", derive(Deserialize))]
1294pub struct CompositorCapabilities {
1295 pub virtual_surface_size: i32,
1297 pub redraw_on_invalidation: bool,
1299 pub max_update_rects: usize,
1303 pub supports_surface_for_backdrop: bool,
1305 pub supports_external_compositor_surface_negative_scaling: bool,
1307}
1308
1309impl Default for CompositorCapabilities {
1310 fn default() -> Self {
1311 CompositorCapabilities {
1316 virtual_surface_size: 0,
1317 redraw_on_invalidation: false,
1318 max_update_rects: 1,
1321 supports_surface_for_backdrop: false,
1322 supports_external_compositor_surface_negative_scaling: true,
1323 }
1324 }
1325}
1326
1327#[repr(C)]
1328#[derive(Copy, Clone, Debug)]
1329pub struct WindowVisibility {
1330 pub is_fully_occluded: bool,
1331}
1332
1333impl Default for WindowVisibility {
1334 fn default() -> Self {
1335 WindowVisibility {
1336 is_fully_occluded: false,
1337 }
1338 }
1339}
1340
1341pub type CompositorSurfaceTransform = ScaleOffset;
1348
1349#[repr(C)]
1350#[cfg_attr(feature = "capture", derive(Serialize))]
1351#[cfg_attr(feature = "replay", derive(Deserialize))]
1352#[derive(PartialEq, Copy, Clone, Debug)]
1353pub struct ClipRadius {
1354 top_left: f32,
1355 top_right: f32,
1356 bottom_left: f32,
1357 bottom_right: f32,
1358}
1359
1360impl ClipRadius {
1361 pub const EMPTY: ClipRadius = ClipRadius { top_left: 0.0, top_right: 0.0, bottom_left: 0.0, bottom_right: 0.0 };
1362}
1363
1364pub trait Compositor {
1368 fn create_surface(
1370 &mut self,
1371 device: &mut Device,
1372 id: NativeSurfaceId,
1373 virtual_offset: DeviceIntPoint,
1374 tile_size: DeviceIntSize,
1375 is_opaque: bool,
1376 );
1377
1378 fn create_external_surface(
1383 &mut self,
1384 device: &mut Device,
1385 id: NativeSurfaceId,
1386 is_opaque: bool,
1387 );
1388
1389 fn create_backdrop_surface(
1391 &mut self,
1392 device: &mut Device,
1393 id: NativeSurfaceId,
1394 color: ColorF,
1395 );
1396
1397 fn destroy_surface(
1404 &mut self,
1405 device: &mut Device,
1406 id: NativeSurfaceId,
1407 );
1408
1409 fn create_tile(
1411 &mut self,
1412 device: &mut Device,
1413 id: NativeTileId,
1414 );
1415
1416 fn destroy_tile(
1418 &mut self,
1419 device: &mut Device,
1420 id: NativeTileId,
1421 );
1422
1423 fn attach_external_image(
1428 &mut self,
1429 device: &mut Device,
1430 id: NativeSurfaceId,
1431 external_image: ExternalImageId
1432 );
1433
1434 fn invalidate_tile(
1439 &mut self,
1440 _device: &mut Device,
1441 _id: NativeTileId,
1442 _valid_rect: DeviceIntRect
1443 ) {}
1444
1445 fn bind(
1457 &mut self,
1458 device: &mut Device,
1459 id: NativeTileId,
1460 dirty_rect: DeviceIntRect,
1461 valid_rect: DeviceIntRect,
1462 ) -> NativeSurfaceInfo;
1463
1464 fn unbind(
1467 &mut self,
1468 device: &mut Device,
1469 );
1470
1471 fn begin_frame(&mut self, device: &mut Device);
1473
1474 fn add_surface(
1484 &mut self,
1485 device: &mut Device,
1486 id: NativeSurfaceId,
1487 transform: CompositorSurfaceTransform,
1488 clip_rect: DeviceIntRect,
1489 image_rendering: ImageRendering,
1490 rounded_clip_rect: DeviceIntRect,
1491 rounded_clip_radii: ClipRadius,
1492 );
1493
1494 fn start_compositing(
1501 &mut self,
1502 _device: &mut Device,
1503 _clear_color: ColorF,
1504 _dirty_rects: &[DeviceIntRect],
1505 _opaque_rects: &[DeviceIntRect],
1506 ) {}
1507
1508 fn end_frame(&mut self, device: &mut Device);
1512
1513 fn enable_native_compositor(&mut self, device: &mut Device, enable: bool);
1515
1516 fn deinit(&mut self, device: &mut Device);
1518
1519 fn get_capabilities(&self, device: &mut Device) -> CompositorCapabilities;
1523
1524 fn get_window_visibility(&self, device: &mut Device) -> WindowVisibility;
1525}
1526
1527#[derive(Debug)]
1530pub struct CompositorInputLayer {
1531 pub offset: DeviceIntPoint,
1533 pub clip_rect: DeviceIntRect,
1535 pub usage: CompositorSurfaceUsage,
1537 pub is_opaque: bool,
1539}
1540
1541#[derive(Debug)]
1544pub struct CompositorInputConfig<'a> {
1545 pub layers: &'a [CompositorInputLayer],
1546}
1547
1548pub trait LayerCompositor {
1551 fn begin_frame(
1554 &mut self,
1555 input: &CompositorInputConfig,
1556 );
1557
1558 fn bind_layer(&mut self, index: usize);
1561
1562 fn present_layer(&mut self, index: usize);
1564
1565 fn add_surface(
1566 &mut self,
1567 index: usize,
1568 transform: CompositorSurfaceTransform,
1569 clip_rect: DeviceIntRect,
1570 image_rendering: ImageRendering,
1571 );
1572
1573 fn end_frame(&mut self);
1575
1576 fn get_window_properties(&self) -> WindowProperties;
1578}
1579
1580#[repr(C)]
1582#[derive(Copy, Clone)]
1583pub struct MappedTileInfo {
1584 pub data: *mut c_void,
1585 pub stride: i32,
1586}
1587
1588#[repr(C)]
1590pub struct SWGLCompositeSurfaceInfo {
1591 pub yuv_planes: u32,
1594 pub textures: [u32; 3],
1596 pub color_space: YuvRangedColorSpace,
1598 pub color_depth: ColorDepth,
1600 pub size: DeviceIntSize,
1602}
1603
1604pub trait MappableCompositor: Compositor {
1606 fn map_tile(
1611 &mut self,
1612 device: &mut Device,
1613 id: NativeTileId,
1614 dirty_rect: DeviceIntRect,
1615 valid_rect: DeviceIntRect,
1616 ) -> Option<MappedTileInfo>;
1617
1618 fn unmap_tile(&mut self, device: &mut Device);
1621
1622 fn lock_composite_surface(
1623 &mut self,
1624 device: &mut Device,
1625 ctx: *mut c_void,
1626 external_image_id: ExternalImageId,
1627 composite_info: *mut SWGLCompositeSurfaceInfo,
1628 ) -> bool;
1629 fn unlock_composite_surface(&mut self, device: &mut Device, ctx: *mut c_void, external_image_id: ExternalImageId);
1630}
1631
1632pub trait PartialPresentCompositor {
1637 fn set_buffer_damage_region(&mut self, rects: &[DeviceIntRect]);
1642}
1643
1644#[cfg_attr(feature = "capture", derive(Serialize))]
1646#[cfg_attr(feature = "replay", derive(Deserialize))]
1647struct Occluder {
1648 z_id: ZBufferId,
1649 world_rect: WorldIntRect,
1650}
1651
1652#[derive(Debug)]
1654enum OcclusionEventKind {
1655 Begin,
1656 End,
1657}
1658
1659#[derive(Debug)]
1661struct OcclusionEvent {
1662 y: i32,
1663 x_range: ops::Range<i32>,
1664 kind: OcclusionEventKind,
1665}
1666
1667impl OcclusionEvent {
1668 fn new(y: i32, kind: OcclusionEventKind, x0: i32, x1: i32) -> Self {
1669 OcclusionEvent {
1670 y,
1671 x_range: ops::Range {
1672 start: x0,
1673 end: x1,
1674 },
1675 kind,
1676 }
1677 }
1678}
1679
1680pub struct OccludersScratchBuffers {
1684 events: FrameVec<OcclusionEvent>,
1685 active: FrameVec<ops::Range<i32>>,
1686}
1687
1688impl Default for OccludersScratchBuffers {
1689 fn default() -> Self {
1690 OccludersScratchBuffers {
1691 events: FrameVec::new_in(FrameAllocator::fallback()),
1692 active: FrameVec::new_in(FrameAllocator::fallback()),
1693 }
1694 }
1695}
1696
1697#[cfg_attr(feature = "capture", derive(Serialize))]
1701#[cfg_attr(feature = "replay", derive(Deserialize))]
1702pub struct Occluders {
1703 occluders: FrameVec<Occluder>,
1704
1705 #[cfg_attr(any(feature = "capture", feature = "replay"), serde(skip))]
1707 scratch: OccludersScratchBuffers,
1708}
1709
1710impl Occluders {
1711 fn new(memory: &FrameMemory) -> Self {
1712 Occluders {
1713 occluders: memory.new_vec(),
1714 scratch: OccludersScratchBuffers {
1715 events: memory.new_vec(),
1716 active: memory.new_vec(),
1717 }
1718 }
1719 }
1720
1721 fn push(&mut self, world_rect: WorldIntRect, z_id: ZBufferId) {
1722 self.occluders.push(Occluder { world_rect, z_id });
1723 }
1724
1725 pub fn is_tile_occluded(
1728 &mut self,
1729 z_id: ZBufferId,
1730 world_rect: WorldRect,
1731 ) -> bool {
1732 let world_rect = world_rect.round().to_i32();
1746 let ref_area = world_rect.area();
1747
1748 let cover_area = self.area(z_id, &world_rect);
1750 debug_assert!(cover_area <= ref_area);
1751
1752 ref_area == cover_area
1754 }
1755
1756 fn area(
1759 &mut self,
1760 z_id: ZBufferId,
1761 clip_rect: &WorldIntRect,
1762 ) -> i32 {
1763 self.scratch.events.clear();
1768 self.scratch.active.clear();
1769
1770 let mut area = 0;
1771
1772 for occluder in &self.occluders {
1774 if occluder.z_id.0 < z_id.0 {
1776 if let Some(rect) = occluder.world_rect.intersection(clip_rect) {
1779 let x0 = rect.min.x;
1780 let x1 = x0 + rect.width();
1781 self.scratch.events.push(OcclusionEvent::new(rect.min.y, OcclusionEventKind::Begin, x0, x1));
1782 self.scratch.events.push(OcclusionEvent::new(rect.min.y + rect.height(), OcclusionEventKind::End, x0, x1));
1783 }
1784 }
1785 }
1786
1787 if self.scratch.events.is_empty() {
1789 return 0;
1790 }
1791
1792 self.scratch.events.sort_by_key(|e| e.y);
1794 let mut cur_y = self.scratch.events[0].y;
1795
1796 for event in &self.scratch.events {
1798 let dy = event.y - cur_y;
1800
1801 if dy != 0 && !self.scratch.active.is_empty() {
1803 assert!(dy > 0);
1804
1805 self.scratch.active.sort_by_key(|i| i.start);
1807 let mut query = 0;
1808 let mut cur = self.scratch.active[0].start;
1809
1810 for interval in &self.scratch.active {
1812 cur = interval.start.max(cur);
1813 query += (interval.end - cur).max(0);
1814 cur = cur.max(interval.end);
1815 }
1816
1817 area += query * dy;
1819 }
1820
1821 match event.kind {
1823 OcclusionEventKind::Begin => {
1824 self.scratch.active.push(event.x_range.clone());
1825 }
1826 OcclusionEventKind::End => {
1827 let index = self.scratch.active.iter().position(|i| *i == event.x_range).unwrap();
1828 self.scratch.active.remove(index);
1829 }
1830 }
1831
1832 cur_y = event.y;
1833 }
1834
1835 area
1836 }
1837}