1use api::{ColorF, YuvRangedColorSpace, YuvFormat, ImageRendering, ExternalImageId, ImageBufferKind};
6use api::units::*;
7use api::ColorDepth;
8use crate::image_source::resolve_image;
9use euclid::{Box2D, Transform3D};
10use crate::gpu_cache::GpuCache;
11use crate::gpu_types::{ZBufferId, ZBufferIdGenerator};
12use crate::internal_types::TextureSource;
13use crate::picture::{ImageDependency, ResolvedSurfaceTexture, TileCacheInstance, TileId, TileSurface};
14use crate::prim_store::DeferredResolve;
15use crate::resource_cache::{ImageRequest, ResourceCache};
16use crate::util::{Preallocator, ScaleOffset};
17use crate::tile_cache::PictureCacheDebugInfo;
18use std::{ops, u64, os::raw::c_void};
19
20#[derive(Debug, Clone)]
27#[cfg_attr(feature = "capture", derive(Serialize))]
28#[cfg_attr(feature = "replay", derive(Deserialize))]
29pub enum NativeSurfaceOperationDetails {
30 CreateSurface {
31 id: NativeSurfaceId,
32 virtual_offset: DeviceIntPoint,
33 tile_size: DeviceIntSize,
34 is_opaque: bool,
35 },
36 CreateExternalSurface {
37 id: NativeSurfaceId,
38 is_opaque: bool,
39 },
40 DestroySurface {
41 id: NativeSurfaceId,
42 },
43 CreateTile {
44 id: NativeTileId,
45 },
46 DestroyTile {
47 id: NativeTileId,
48 },
49 AttachExternalImage {
50 id: NativeSurfaceId,
51 external_image: ExternalImageId,
52 }
53}
54
55#[derive(Debug, Clone)]
57#[cfg_attr(feature = "capture", derive(Serialize))]
58#[cfg_attr(feature = "replay", derive(Deserialize))]
59pub struct NativeSurfaceOperation {
60 pub details: NativeSurfaceOperationDetails,
61}
62
63#[cfg_attr(feature = "capture", derive(Serialize))]
67#[cfg_attr(feature = "replay", derive(Deserialize))]
68#[derive(Clone)]
69pub enum CompositeTileSurface {
70 Texture {
71 surface: ResolvedSurfaceTexture,
72 },
73 Color {
74 color: ColorF,
75 },
76 Clear,
77 ExternalSurface {
78 external_surface_index: ResolvedExternalSurfaceIndex,
79 },
80}
81
82#[derive(Debug, Copy, Clone, PartialEq)]
84pub enum CompositeSurfaceFormat {
85 Rgba,
86 Yuv,
87}
88
89bitflags! {
90 pub struct CompositeFeatures: u8 {
93 const NO_UV_CLAMP = 1 << 0;
96 const NO_COLOR_MODULATION = 1 << 1;
98 }
99}
100
101#[derive(Copy, Clone, Debug, PartialEq)]
102#[cfg_attr(feature = "capture", derive(Serialize))]
103#[cfg_attr(feature = "replay", derive(Deserialize))]
104pub enum TileKind {
105 Opaque,
106 Alpha,
107 Clear,
108}
109
110#[cfg_attr(feature = "capture", derive(Serialize))]
112#[cfg_attr(feature = "replay", derive(Deserialize))]
113#[derive(Debug, Copy, Clone)]
114pub struct CompositorTransformIndex(usize);
115
116impl CompositorTransformIndex {
117 pub const INVALID: CompositorTransformIndex = CompositorTransformIndex(!0);
118}
119
120#[cfg_attr(feature = "capture", derive(Serialize))]
122#[cfg_attr(feature = "replay", derive(Deserialize))]
123#[derive(Clone)]
124pub struct CompositeTile {
125 pub surface: CompositeTileSurface,
126 pub local_rect: PictureRect,
127 pub local_valid_rect: PictureRect,
128 pub local_dirty_rect: PictureRect,
129 pub device_clip_rect: DeviceRect,
130 pub z_id: ZBufferId,
131 pub kind: TileKind,
132 pub transform_index: CompositorTransformIndex,
133}
134
135pub fn tile_kind(surface: &CompositeTileSurface, is_opaque: bool) -> TileKind {
136 match surface {
137 CompositeTileSurface::Color { .. } => TileKind::Opaque,
140 CompositeTileSurface::Clear => TileKind::Clear,
142 CompositeTileSurface::Texture { .. }
143 | CompositeTileSurface::ExternalSurface { .. } => {
144 if is_opaque {
147 TileKind::Opaque
148 } else {
149 TileKind::Alpha
150 }
151 }
152 }
153}
154
155pub enum ExternalSurfaceDependency {
156 Yuv {
157 image_dependencies: [ImageDependency; 3],
158 color_space: YuvRangedColorSpace,
159 format: YuvFormat,
160 channel_bit_depth: u32,
161 },
162 Rgb {
163 image_dependency: ImageDependency,
164 },
165}
166
167pub struct ExternalSurfaceDescriptor {
171 pub local_surface_size: LayoutSize,
174 pub local_rect: PictureRect,
175 pub local_clip_rect: PictureRect,
176 pub clip_rect: DeviceRect,
177 pub transform_index: CompositorTransformIndex,
178 pub image_rendering: ImageRendering,
179 pub z_id: ZBufferId,
180 pub dependency: ExternalSurfaceDependency,
181 pub native_surface_id: Option<NativeSurfaceId>,
184 pub update_params: Option<DeviceIntSize>,
187}
188
189#[cfg_attr(feature = "capture", derive(Serialize))]
191#[cfg_attr(feature = "replay", derive(Deserialize))]
192#[derive(Debug, Copy, Clone)]
193pub struct ExternalPlaneDescriptor {
194 pub texture: TextureSource,
195 pub uv_rect: TexelRect,
196}
197
198impl ExternalPlaneDescriptor {
199 fn invalid() -> Self {
200 ExternalPlaneDescriptor {
201 texture: TextureSource::Invalid,
202 uv_rect: TexelRect::invalid(),
203 }
204 }
205}
206
207#[cfg_attr(feature = "capture", derive(Serialize))]
208#[cfg_attr(feature = "replay", derive(Deserialize))]
209#[derive(Debug, Copy, Clone, PartialEq)]
210pub struct ResolvedExternalSurfaceIndex(pub usize);
211
212impl ResolvedExternalSurfaceIndex {
213 pub const INVALID: ResolvedExternalSurfaceIndex = ResolvedExternalSurfaceIndex(usize::MAX);
214}
215
216#[cfg_attr(feature = "capture", derive(Serialize))]
217#[cfg_attr(feature = "replay", derive(Deserialize))]
218pub enum ResolvedExternalSurfaceColorData {
219 Yuv {
220 image_dependencies: [ImageDependency; 3],
222 planes: [ExternalPlaneDescriptor; 3],
223 color_space: YuvRangedColorSpace,
224 format: YuvFormat,
225 channel_bit_depth: u32,
226 },
227 Rgb {
228 image_dependency: ImageDependency,
229 plane: ExternalPlaneDescriptor,
230 },
231}
232
233#[cfg_attr(feature = "capture", derive(Serialize))]
238#[cfg_attr(feature = "replay", derive(Deserialize))]
239pub struct ResolvedExternalSurface {
240 pub color_data: ResolvedExternalSurfaceColorData,
241 pub image_buffer_kind: ImageBufferKind,
242 pub update_params: Option<(NativeSurfaceId, DeviceIntSize)>,
244}
245
246pub enum CompositorConfig {
249 Draw {
251 max_partial_present_rects: usize,
256 draw_previous_partial_present_regions: bool,
260 partial_present: Option<Box<dyn PartialPresentCompositor>>,
263 },
264 Native {
268 compositor: Box<dyn Compositor>,
270 }
271}
272
273impl CompositorConfig {
274 pub fn compositor(&mut self) -> Option<&mut Box<dyn Compositor>> {
275 match self {
276 CompositorConfig::Native { ref mut compositor, .. } => {
277 Some(compositor)
278 }
279 CompositorConfig::Draw { .. } => {
280 None
281 }
282 }
283 }
284
285 pub fn partial_present(&mut self) -> Option<&mut Box<dyn PartialPresentCompositor>> {
286 match self {
287 CompositorConfig::Native { .. } => {
288 None
289 }
290 CompositorConfig::Draw { ref mut partial_present, .. } => {
291 partial_present.as_mut()
292 }
293 }
294 }
295
296}
297
298impl Default for CompositorConfig {
299 fn default() -> Self {
301 CompositorConfig::Draw {
302 max_partial_present_rects: 0,
303 draw_previous_partial_present_regions: false,
304 partial_present: None,
305 }
306 }
307}
308
309#[cfg_attr(feature = "capture", derive(Serialize))]
313#[cfg_attr(feature = "replay", derive(Deserialize))]
314#[derive(Debug, Copy, Clone, PartialEq)]
315pub enum CompositorKind {
316 Draw {
318 max_partial_present_rects: usize,
320 draw_previous_partial_present_regions: bool,
322 },
323 Native {
325 capabilities: CompositorCapabilities,
327 },
328}
329
330impl Default for CompositorKind {
331 fn default() -> Self {
333 CompositorKind::Draw {
334 max_partial_present_rects: 0,
335 draw_previous_partial_present_regions: false,
336 }
337 }
338}
339
340impl CompositorKind {
341 pub fn get_virtual_surface_size(&self) -> i32 {
342 match self {
343 CompositorKind::Draw { .. } => 0,
344 CompositorKind::Native { capabilities, .. } => capabilities.virtual_surface_size,
345 }
346 }
347
348 pub fn should_redraw_on_invalidation(&self) -> bool {
349 match self {
350 CompositorKind::Draw { max_partial_present_rects, .. } => {
351 *max_partial_present_rects > 0
353 }
354 CompositorKind::Native { capabilities, .. } => capabilities.redraw_on_invalidation,
355 }
356 }
357}
358
359#[cfg_attr(feature = "capture", derive(Serialize))]
362#[cfg_attr(feature = "replay", derive(Deserialize))]
363#[derive(PartialEq, Clone)]
364pub enum TileSurfaceKind {
365 Texture,
366 Color {
367 color: ColorF,
368 },
369 Clear,
370}
371
372impl From<&TileSurface> for TileSurfaceKind {
373 fn from(surface: &TileSurface) -> Self {
374 match surface {
375 TileSurface::Texture { .. } => TileSurfaceKind::Texture,
376 TileSurface::Color { color } => TileSurfaceKind::Color { color: *color },
377 TileSurface::Clear => TileSurfaceKind::Clear,
378 }
379 }
380}
381
382#[cfg_attr(feature = "capture", derive(Serialize))]
385#[cfg_attr(feature = "replay", derive(Deserialize))]
386#[derive(PartialEq, Clone)]
387pub struct CompositeTileDescriptor {
388 pub tile_id: TileId,
389 pub surface_kind: TileSurfaceKind,
390}
391
392#[cfg_attr(feature = "capture", derive(Serialize))]
394#[cfg_attr(feature = "replay", derive(Deserialize))]
395#[derive(PartialEq, Clone)]
396pub struct CompositeSurfaceDescriptor {
397 pub surface_id: Option<NativeSurfaceId>,
398 pub clip_rect: DeviceRect,
399 pub transform: CompositorSurfaceTransform,
400 pub image_dependencies: [ImageDependency; 3],
405 pub image_rendering: ImageRendering,
406 pub tile_descriptors: Vec<CompositeTileDescriptor>,
408}
409
410#[cfg_attr(feature = "capture", derive(Serialize))]
413#[cfg_attr(feature = "replay", derive(Deserialize))]
414#[derive(PartialEq, Clone)]
415pub struct CompositeDescriptor {
416 pub surfaces: Vec<CompositeSurfaceDescriptor>,
417}
418
419impl CompositeDescriptor {
420 pub fn empty() -> Self {
422 CompositeDescriptor {
423 surfaces: Vec::new(),
424 }
425 }
426}
427
428pub struct CompositeStatePreallocator {
429 tiles: Preallocator,
430 external_surfaces: Preallocator,
431 occluders: Preallocator,
432 occluders_events: Preallocator,
433 occluders_active: Preallocator,
434 descriptor_surfaces: Preallocator,
435}
436
437impl CompositeStatePreallocator {
438 pub fn record(&mut self, state: &CompositeState) {
439 self.tiles.record_vec(&state.tiles);
440 self.external_surfaces.record_vec(&state.external_surfaces);
441 self.occluders.record_vec(&state.occluders.occluders);
442 self.occluders_events.record_vec(&state.occluders.events);
443 self.occluders_active.record_vec(&state.occluders.active);
444 self.descriptor_surfaces.record_vec(&state.descriptor.surfaces);
445 }
446
447 pub fn preallocate(&self, state: &mut CompositeState) {
448 self.tiles.preallocate_vec(&mut state.tiles);
449 self.external_surfaces.preallocate_vec(&mut state.external_surfaces);
450 self.occluders.preallocate_vec(&mut state.occluders.occluders);
451 self.occluders_events.preallocate_vec(&mut state.occluders.events);
452 self.occluders_active.preallocate_vec(&mut state.occluders.active);
453 self.descriptor_surfaces.preallocate_vec(&mut state.descriptor.surfaces);
454 }
455}
456
457impl Default for CompositeStatePreallocator {
458 fn default() -> Self {
459 CompositeStatePreallocator {
460 tiles: Preallocator::new(56),
461 external_surfaces: Preallocator::new(0),
462 occluders: Preallocator::new(16),
463 occluders_events: Preallocator::new(32),
464 occluders_active: Preallocator::new(16),
465 descriptor_surfaces: Preallocator::new(8),
466 }
467 }
468}
469
470#[cfg_attr(feature = "capture", derive(Serialize))]
477#[cfg_attr(feature = "replay", derive(Deserialize))]
478pub struct CompositorTransform {
479 local_to_surface: ScaleOffset,
481 surface_to_device: ScaleOffset,
483 local_to_device: ScaleOffset,
485}
486
487#[cfg_attr(feature = "capture", derive(Serialize))]
489#[cfg_attr(feature = "replay", derive(Deserialize))]
490pub struct CompositeState {
491 pub tiles: Vec<CompositeTile>,
498 pub external_surfaces: Vec<ResolvedExternalSurface>,
500 pub z_generator: ZBufferIdGenerator,
502 pub dirty_rects_are_valid: bool,
509 pub compositor_kind: CompositorKind,
511 pub occluders: Occluders,
513 pub descriptor: CompositeDescriptor,
515 pub picture_cache_debug: PictureCacheDebugInfo,
517 pub transforms: Vec<CompositorTransform>,
519 low_quality_pinch_zoom: bool,
521}
522
523impl CompositeState {
524 pub fn new(
527 compositor_kind: CompositorKind,
528 max_depth_ids: i32,
529 dirty_rects_are_valid: bool,
530 low_quality_pinch_zoom: bool,
531 ) -> Self {
532 CompositeState {
533 tiles: Vec::new(),
534 z_generator: ZBufferIdGenerator::new(max_depth_ids),
535 dirty_rects_are_valid,
536 compositor_kind,
537 occluders: Occluders::new(),
538 descriptor: CompositeDescriptor::empty(),
539 external_surfaces: Vec::new(),
540 picture_cache_debug: PictureCacheDebugInfo::new(),
541 transforms: Vec::new(),
542 low_quality_pinch_zoom,
543 }
544 }
545
546 pub fn register_transform(
548 &mut self,
549 local_to_surface: ScaleOffset,
550 surface_to_device: ScaleOffset,
551 ) -> CompositorTransformIndex {
552 let index = CompositorTransformIndex(self.transforms.len());
553
554 let local_to_device = local_to_surface.accumulate(&surface_to_device);
555
556 self.transforms.push(CompositorTransform {
557 local_to_surface,
558 surface_to_device,
559 local_to_device,
560 });
561
562 index
563 }
564
565 pub fn get_device_rect(
567 &self,
568 local_rect: &PictureRect,
569 transform_index: CompositorTransformIndex,
570 ) -> DeviceRect {
571 let transform = &self.transforms[transform_index.0];
572 transform.local_to_device.map_rect(&local_rect).round()
573 }
574
575 pub fn get_surface_rect<T>(
578 &self,
579 local_sub_rect: &Box2D<f32, T>,
580 local_bounds: &Box2D<f32, T>,
581 transform_index: CompositorTransformIndex,
582 ) -> DeviceRect {
583 let transform = &self.transforms[transform_index.0];
584
585 let surface_bounds = transform.local_to_surface.map_rect(&local_bounds);
586 let surface_rect = transform.local_to_surface.map_rect(&local_sub_rect);
587
588 surface_rect
589 .translate(-surface_bounds.min.to_vector())
590 .round_out()
591 .intersection(&surface_bounds.size().round().into())
592 .unwrap_or_else(DeviceRect::zero)
593 }
594
595 pub fn get_device_transform(
597 &self,
598 transform_index: CompositorTransformIndex,
599 ) -> ScaleOffset {
600 let transform = &self.transforms[transform_index.0];
601 transform.local_to_device
602 }
603
604 pub fn get_compositor_transform(
606 &self,
607 transform_index: CompositorTransformIndex,
608 ) -> ScaleOffset {
609 let transform = &self.transforms[transform_index.0];
610 transform.surface_to_device
611 }
612
613 pub fn register_occluder(
616 &mut self,
617 z_id: ZBufferId,
618 rect: WorldRect,
619 ) {
620 let world_rect = rect.round().to_i32();
621
622 self.occluders.push(world_rect, z_id);
623 }
624
625 pub fn push_surface(
627 &mut self,
628 tile_cache: &TileCacheInstance,
629 device_clip_rect: DeviceRect,
630 resource_cache: &ResourceCache,
631 gpu_cache: &mut GpuCache,
632 deferred_resolves: &mut Vec<DeferredResolve>,
633 ) {
634 let slice_transform = self.get_compositor_transform(tile_cache.transform_index).to_transform();
635
636 let image_rendering = if self.low_quality_pinch_zoom {
637 ImageRendering::Auto
638 } else {
639 ImageRendering::CrispEdges
640 };
641
642 for sub_slice in &tile_cache.sub_slices {
643 let mut surface_device_rect = DeviceRect::zero();
644
645 for tile in sub_slice.tiles.values() {
646 if !tile.is_visible {
647 continue;
649 }
650
651 surface_device_rect = surface_device_rect.union(&tile.device_valid_rect);
661 }
662
663 self.tiles.extend_from_slice(&sub_slice.composite_tiles);
665
666 let surface_clip_rect = device_clip_rect
671 .intersection(&surface_device_rect)
672 .unwrap_or(DeviceRect::zero());
673
674 if !sub_slice.opaque_tile_descriptors.is_empty() {
676 self.descriptor.surfaces.push(
677 CompositeSurfaceDescriptor {
678 surface_id: sub_slice.native_surface.as_ref().map(|s| s.opaque),
679 clip_rect: surface_clip_rect,
680 transform: slice_transform,
681 image_dependencies: [ImageDependency::INVALID; 3],
682 image_rendering,
683 tile_descriptors: sub_slice.opaque_tile_descriptors.clone(),
684 }
685 );
686 }
687
688 if !sub_slice.alpha_tile_descriptors.is_empty() {
690 self.descriptor.surfaces.push(
691 CompositeSurfaceDescriptor {
692 surface_id: sub_slice.native_surface.as_ref().map(|s| s.alpha),
693 clip_rect: surface_clip_rect,
694 transform: slice_transform,
695 image_dependencies: [ImageDependency::INVALID; 3],
696 image_rendering,
697 tile_descriptors: sub_slice.alpha_tile_descriptors.clone(),
698 }
699 );
700 }
701
702 for compositor_surface in &sub_slice.compositor_surfaces {
705 let external_surface = &compositor_surface.descriptor;
706
707 let clip_rect = external_surface
708 .clip_rect
709 .intersection(&device_clip_rect)
710 .unwrap_or_else(DeviceRect::zero);
711
712 let required_plane_count =
713 match external_surface.dependency {
714 ExternalSurfaceDependency::Yuv { format, .. } => {
715 format.get_plane_num()
716 },
717 ExternalSurfaceDependency::Rgb { .. } => {
718 1
719 }
720 };
721
722 let mut image_dependencies = [ImageDependency::INVALID; 3];
723
724 for i in 0 .. required_plane_count {
725 let dependency = match external_surface.dependency {
726 ExternalSurfaceDependency::Yuv { image_dependencies, .. } => {
727 image_dependencies[i]
728 },
729 ExternalSurfaceDependency::Rgb { image_dependency, .. } => {
730 image_dependency
731 }
732 };
733 image_dependencies[i] = dependency;
734 }
735
736 let needs_external_surface_update = match self.compositor_kind {
740 CompositorKind::Draw { .. } => true,
741 _ => external_surface.update_params.is_some(),
742 };
743 let external_surface_index = if needs_external_surface_update {
744 let external_surface_index = self.compute_external_surface_dependencies(
745 &external_surface,
746 &image_dependencies,
747 required_plane_count,
748 resource_cache,
749 gpu_cache,
750 deferred_resolves,
751 );
752 if external_surface_index == ResolvedExternalSurfaceIndex::INVALID {
753 continue;
754 }
755 external_surface_index
756 } else {
757 ResolvedExternalSurfaceIndex::INVALID
758 };
759
760 let surface = CompositeTileSurface::ExternalSurface { external_surface_index };
761 let local_rect = external_surface.local_surface_size.cast_unit().into();
762
763 let tile = CompositeTile {
764 kind: tile_kind(&surface, compositor_surface.is_opaque),
765 surface,
766 local_rect,
767 local_valid_rect: local_rect,
768 local_dirty_rect: local_rect,
769 device_clip_rect: clip_rect,
770 z_id: external_surface.z_id,
771 transform_index: external_surface.transform_index,
772 };
773
774 self.descriptor.surfaces.push(
778 CompositeSurfaceDescriptor {
779 surface_id: external_surface.native_surface_id,
780 clip_rect,
781 transform: self.get_compositor_transform(external_surface.transform_index).to_transform(),
782 image_dependencies: image_dependencies,
783 image_rendering: external_surface.image_rendering,
784 tile_descriptors: Vec::new(),
785 }
786 );
787
788 self.tiles.push(tile);
789 }
790 }
791 }
792
793 fn compute_external_surface_dependencies(
794 &mut self,
795 external_surface: &ExternalSurfaceDescriptor,
796 image_dependencies: &[ImageDependency; 3],
797 required_plane_count: usize,
798 resource_cache: &ResourceCache,
799 gpu_cache: &mut GpuCache,
800 deferred_resolves: &mut Vec<DeferredResolve>,
801 ) -> ResolvedExternalSurfaceIndex {
802 let mut planes = [
803 ExternalPlaneDescriptor::invalid(),
804 ExternalPlaneDescriptor::invalid(),
805 ExternalPlaneDescriptor::invalid(),
806 ];
807
808 let mut valid_plane_count = 0;
809 for i in 0 .. required_plane_count {
810 let request = ImageRequest {
811 key: image_dependencies[i].key,
812 rendering: external_surface.image_rendering,
813 tile: None,
814 };
815
816 let cache_item = resolve_image(
817 request,
818 resource_cache,
819 gpu_cache,
820 deferred_resolves,
821 );
822
823 if cache_item.texture_id != TextureSource::Invalid {
824 valid_plane_count += 1;
825 let plane = &mut planes[i];
826 *plane = ExternalPlaneDescriptor {
827 texture: cache_item.texture_id,
828 uv_rect: cache_item.uv_rect.into(),
829 };
830 }
831 }
832
833 if valid_plane_count < required_plane_count {
835 warn!("Warnings: skip a YUV/RGB compositor surface, found {}/{} valid images",
836 valid_plane_count,
837 required_plane_count,
838 );
839 return ResolvedExternalSurfaceIndex::INVALID;
840 }
841
842 let external_surface_index = ResolvedExternalSurfaceIndex(self.external_surfaces.len());
843
844 let update_params = external_surface.update_params.map(|surface_size| {
848 (
849 external_surface.native_surface_id.expect("bug: no native surface!"),
850 surface_size
851 )
852 });
853
854 match external_surface.dependency {
855 ExternalSurfaceDependency::Yuv{ color_space, format, channel_bit_depth, .. } => {
856
857 let image_buffer_kind = planes[0].texture.image_buffer_kind();
858
859 self.external_surfaces.push(ResolvedExternalSurface {
860 color_data: ResolvedExternalSurfaceColorData::Yuv {
861 image_dependencies: *image_dependencies,
862 planes,
863 color_space,
864 format,
865 channel_bit_depth,
866 },
867 image_buffer_kind,
868 update_params,
869 });
870 },
871 ExternalSurfaceDependency::Rgb { .. } => {
872 let image_buffer_kind = planes[0].texture.image_buffer_kind();
873
874 self.external_surfaces.push(ResolvedExternalSurface {
875 color_data: ResolvedExternalSurfaceColorData::Rgb {
876 image_dependency: image_dependencies[0],
877 plane: planes[0],
878 },
879 image_buffer_kind,
880 update_params,
881 });
882 },
883 }
884 external_surface_index
885 }
886
887 pub fn end_frame(&mut self) {
888 self.tiles.sort_by_key(|tile| tile.z_id.0);
890 }
891}
892
893#[repr(C)]
895#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
896#[cfg_attr(feature = "capture", derive(Serialize))]
897#[cfg_attr(feature = "replay", derive(Deserialize))]
898pub struct NativeSurfaceId(pub u64);
899
900impl NativeSurfaceId {
901 pub const DEBUG_OVERLAY: NativeSurfaceId = NativeSurfaceId(u64::MAX);
903}
904
905#[repr(C)]
906#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
907#[cfg_attr(feature = "capture", derive(Serialize))]
908#[cfg_attr(feature = "replay", derive(Deserialize))]
909pub struct NativeTileId {
910 pub surface_id: NativeSurfaceId,
911 pub x: i32,
912 pub y: i32,
913}
914
915impl NativeTileId {
916 pub const DEBUG_OVERLAY: NativeTileId = NativeTileId {
918 surface_id: NativeSurfaceId::DEBUG_OVERLAY,
919 x: 0,
920 y: 0,
921 };
922}
923
924#[repr(C)]
927#[derive(Copy, Clone)]
928pub struct NativeSurfaceInfo {
929 pub origin: DeviceIntPoint,
935 pub fbo_id: u32,
943}
944
945#[repr(C)]
946#[derive(Debug, Copy, Clone, PartialEq)]
947#[cfg_attr(feature = "capture", derive(Serialize))]
948#[cfg_attr(feature = "replay", derive(Deserialize))]
949pub struct CompositorCapabilities {
950 pub virtual_surface_size: i32,
952 pub redraw_on_invalidation: bool,
954 pub max_update_rects: usize,
958}
959
960impl Default for CompositorCapabilities {
961 fn default() -> Self {
962 CompositorCapabilities {
967 virtual_surface_size: 0,
968 redraw_on_invalidation: false,
969 max_update_rects: 1,
972 }
973 }
974}
975
976pub type CompositorSurfaceTransform = Transform3D<f32, DevicePixel, DevicePixel>;
984
985pub trait Compositor {
989 fn create_surface(
991 &mut self,
992 id: NativeSurfaceId,
993 virtual_offset: DeviceIntPoint,
994 tile_size: DeviceIntSize,
995 is_opaque: bool,
996 );
997
998 fn create_external_surface(
1003 &mut self,
1004 id: NativeSurfaceId,
1005 is_opaque: bool,
1006 );
1007
1008 fn destroy_surface(
1015 &mut self,
1016 id: NativeSurfaceId,
1017 );
1018
1019 fn create_tile(
1021 &mut self,
1022 id: NativeTileId,
1023 );
1024
1025 fn destroy_tile(
1027 &mut self,
1028 id: NativeTileId,
1029 );
1030
1031 fn attach_external_image(
1036 &mut self,
1037 id: NativeSurfaceId,
1038 external_image: ExternalImageId
1039 );
1040
1041 fn invalidate_tile(
1046 &mut self,
1047 _id: NativeTileId,
1048 _valid_rect: DeviceIntRect
1049 ) {}
1050
1051 fn bind(
1063 &mut self,
1064 id: NativeTileId,
1065 dirty_rect: DeviceIntRect,
1066 valid_rect: DeviceIntRect,
1067 ) -> NativeSurfaceInfo;
1068
1069 fn unbind(
1072 &mut self,
1073 );
1074
1075 fn begin_frame(&mut self);
1077
1078 fn add_surface(
1088 &mut self,
1089 id: NativeSurfaceId,
1090 transform: CompositorSurfaceTransform,
1091 clip_rect: DeviceIntRect,
1092 image_rendering: ImageRendering,
1093 );
1094
1095 fn start_compositing(
1102 &mut self,
1103 _clear_color: ColorF,
1104 _dirty_rects: &[DeviceIntRect],
1105 _opaque_rects: &[DeviceIntRect],
1106 ) {}
1107
1108 fn end_frame(&mut self);
1112
1113 fn enable_native_compositor(&mut self, enable: bool);
1115
1116 fn deinit(&mut self);
1118
1119 fn get_capabilities(&self) -> CompositorCapabilities;
1123}
1124
1125#[repr(C)]
1127#[derive(Copy, Clone)]
1128pub struct MappedTileInfo {
1129 pub data: *mut c_void,
1130 pub stride: i32,
1131}
1132
1133#[repr(C)]
1135pub struct SWGLCompositeSurfaceInfo {
1136 pub yuv_planes: u32,
1139 pub textures: [u32; 3],
1141 pub color_space: YuvRangedColorSpace,
1143 pub color_depth: ColorDepth,
1145 pub size: DeviceIntSize,
1147}
1148
1149pub trait MappableCompositor: Compositor {
1151 fn map_tile(
1156 &mut self,
1157 id: NativeTileId,
1158 dirty_rect: DeviceIntRect,
1159 valid_rect: DeviceIntRect,
1160 ) -> Option<MappedTileInfo>;
1161
1162 fn unmap_tile(&mut self);
1165
1166 fn lock_composite_surface(
1167 &mut self,
1168 ctx: *mut c_void,
1169 external_image_id: ExternalImageId,
1170 composite_info: *mut SWGLCompositeSurfaceInfo,
1171 ) -> bool;
1172 fn unlock_composite_surface(&mut self, ctx: *mut c_void, external_image_id: ExternalImageId);
1173}
1174
1175pub trait PartialPresentCompositor {
1180 fn set_buffer_damage_region(&mut self, rects: &[DeviceIntRect]);
1185}
1186
1187#[cfg_attr(feature = "capture", derive(Serialize))]
1189#[cfg_attr(feature = "replay", derive(Deserialize))]
1190struct Occluder {
1191 z_id: ZBufferId,
1192 world_rect: WorldIntRect,
1193}
1194
1195#[derive(Debug)]
1197enum OcclusionEventKind {
1198 Begin,
1199 End,
1200}
1201
1202#[derive(Debug)]
1204struct OcclusionEvent {
1205 y: i32,
1206 x_range: ops::Range<i32>,
1207 kind: OcclusionEventKind,
1208}
1209
1210impl OcclusionEvent {
1211 fn new(y: i32, kind: OcclusionEventKind, x0: i32, x1: i32) -> Self {
1212 OcclusionEvent {
1213 y,
1214 x_range: ops::Range {
1215 start: x0,
1216 end: x1,
1217 },
1218 kind,
1219 }
1220 }
1221}
1222
1223#[cfg_attr(feature = "capture", derive(Serialize))]
1227#[cfg_attr(feature = "replay", derive(Deserialize))]
1228pub struct Occluders {
1229 occluders: Vec<Occluder>,
1230
1231 #[cfg_attr(feature = "serde", serde(skip))]
1234 events: Vec<OcclusionEvent>,
1235
1236 #[cfg_attr(feature = "serde", serde(skip))]
1237 active: Vec<ops::Range<i32>>,
1238}
1239
1240impl Occluders {
1241 fn new() -> Self {
1242 Occluders {
1243 occluders: Vec::new(),
1244 events: Vec::new(),
1245 active: Vec::new(),
1246 }
1247 }
1248
1249 fn push(&mut self, world_rect: WorldIntRect, z_id: ZBufferId) {
1250 self.occluders.push(Occluder { world_rect, z_id });
1251 }
1252
1253 pub fn is_tile_occluded(
1256 &mut self,
1257 z_id: ZBufferId,
1258 world_rect: WorldRect,
1259 ) -> bool {
1260 let world_rect = world_rect.round().to_i32();
1274 let ref_area = world_rect.area();
1275
1276 let cover_area = self.area(z_id, &world_rect);
1278 debug_assert!(cover_area <= ref_area);
1279
1280 ref_area == cover_area
1282 }
1283
1284 fn area(
1287 &mut self,
1288 z_id: ZBufferId,
1289 clip_rect: &WorldIntRect,
1290 ) -> i32 {
1291 self.events.clear();
1296 self.active.clear();
1297
1298 let mut area = 0;
1299
1300 for occluder in &self.occluders {
1302 if occluder.z_id.0 < z_id.0 {
1304 if let Some(rect) = occluder.world_rect.intersection(clip_rect) {
1307 let x0 = rect.min.x;
1308 let x1 = x0 + rect.width();
1309 self.events.push(OcclusionEvent::new(rect.min.y, OcclusionEventKind::Begin, x0, x1));
1310 self.events.push(OcclusionEvent::new(rect.min.y + rect.height(), OcclusionEventKind::End, x0, x1));
1311 }
1312 }
1313 }
1314
1315 if self.events.is_empty() {
1317 return 0;
1318 }
1319
1320 self.events.sort_by_key(|e| e.y);
1322 let mut cur_y = self.events[0].y;
1323
1324 for event in &self.events {
1326 let dy = event.y - cur_y;
1328
1329 if dy != 0 && !self.active.is_empty() {
1331 assert!(dy > 0);
1332
1333 self.active.sort_by_key(|i| i.start);
1335 let mut query = 0;
1336 let mut cur = self.active[0].start;
1337
1338 for interval in &self.active {
1340 cur = interval.start.max(cur);
1341 query += (interval.end - cur).max(0);
1342 cur = cur.max(interval.end);
1343 }
1344
1345 area += query * dy;
1347 }
1348
1349 match event.kind {
1351 OcclusionEventKind::Begin => {
1352 self.active.push(event.x_range.clone());
1353 }
1354 OcclusionEventKind::End => {
1355 let index = self.active.iter().position(|i| *i == event.x_range).unwrap();
1356 self.active.remove(index);
1357 }
1358 }
1359
1360 cur_y = event.y;
1361 }
1362
1363 area
1364 }
1365}