ferroui_base/rendering/composition/composition_external_memory.rs
1use super::ServerJobTask;
2use crate::platform::{IPlatformHandle, PlatformGraphicsDrmFormat, PlatformGraphicsExternalImageProperties};
3use bitflags::bitflags;
4use std::rc::Rc;
5use std::sync::Arc;
6
7/// The import of GPU objects created outside of the framework into the
8/// compositor.
9pub trait ICompositionGpuInterop {
10 /// Returns the list of image handle types supported by the current GPU backend, see [`KnownPlatformGraphicsExternalImageHandleTypes`](crate::platform::KnownPlatformGraphicsExternalImageHandleTypes)
11 fn supported_image_handle_types(&self) -> Vec<String>;
12
13 /// Returns the list of semaphore types supported by the current GPU backend, see [`KnownPlatformGraphicsExternalSemaphoreHandleTypes`](crate::platform::KnownPlatformGraphicsExternalSemaphoreHandleTypes)
14 fn supported_semaphore_types(&self) -> Vec<String>;
15
16 /// Returns the DRM format/modifier pairs the current GPU backend can import as
17 /// [`KnownPlatformGraphicsExternalImageHandleTypes::DMA_BUF_FILE_DESCRIPTOR`](crate::platform::KnownPlatformGraphicsExternalImageHandleTypes::DMA_BUF_FILE_DESCRIPTOR) images,
18 /// or `None` when the backend cannot enumerate them.
19 fn supported_dma_buf_formats(&self) -> Option<Vec<PlatformGraphicsDrmFormat>> {
20 None
21 }
22
23 /// Returns the supported ways to synchronize access to the imported GPU image
24 fn get_synchronization_capabilities(&self, image_handle_type: &str)
25 -> CompositionGpuImportedImageSynchronizationCapabilities;
26
27 /// Asynchronously imports a texture. The returned object is immediately usable.
28 fn import_image(
29 &self,
30 handle: Rc<dyn IPlatformHandle>,
31 properties: PlatformGraphicsExternalImageProperties,
32 ) -> Rc<dyn ICompositionImportedGpuImage>;
33
34 /// Asynchronously imports a texture. The returned object is immediately usable.
35 /// If import operation fails, the caller is responsible for destroying the handle
36 ///
37 /// `image` is an image that belongs to the same GPU context or the same GPU context sharing group as one used by compositor
38 fn import_shared_image(&self, image: Arc<dyn ICompositionImportableSharedGpuContextImage>)
39 -> Rc<dyn ICompositionImportedGpuImage>;
40
41 /// Asynchronously imports a semaphore object. The returned object is immediately usable.
42 /// If import operation fails, the caller is responsible for destroying the handle
43 fn import_semaphore(&self, handle: Rc<dyn IPlatformHandle>) -> Rc<dyn ICompositionImportedGpuSemaphore>;
44
45 /// Asynchronously imports a semaphore object. The returned object is immediately usable.
46 ///
47 /// `image` is a semaphore that belongs to the same GPU context or the same GPU context sharing group as one used by compositor
48 fn import_shared_semaphore(
49 &self,
50 image: Rc<dyn ICompositionImportableSharedGpuContextSemaphore>,
51 ) -> Rc<dyn ICompositionImportedGpuImage>;
52
53 /// Indicates if the device context this instance is associated with is no longer available
54 fn is_lost(&self) -> bool;
55
56 /// The LUID of the graphics adapter used by the compositor
57 fn device_luid(&self) -> Option<Vec<u8>>;
58
59 fn set_device_luid(&self, value: Option<Vec<u8>>);
60
61 /// The UUID of the graphics adapter used by the compositor
62 fn device_uuid(&self) -> Option<Vec<u8>>;
63
64 fn set_device_uuid(&self, value: Option<Vec<u8>>);
65}
66
67bitflags! {
68 /// The ways the access to an imported GPU image can be synchronized.
69 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
70 pub struct CompositionGpuImportedImageSynchronizationCapabilities: i32 {
71 /// Pre-render and after-render semaphores must be provided alongside with the image
72 const SEMAPHORES = 1;
73 /// Image must be created with D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX or in other compatible way
74 const KEYED_MUTEX = 2;
75 /// Synchronization and ordering is somehow handled by the underlying platform
76 const AUTOMATIC = 4;
77 /// Pre-render and after-render timeline semaphores must be provided alongside with the image
78 const TIMELINE_SEMAPHORES = 8;
79 }
80}
81
82/// An imported GPU object that's usable by composition APIs
83pub trait ICompositionGpuImportedObject {
84 /// Tracks the import status of the object. Once the task is completed,
85 /// the user code is allowed to free the resource owner in case when a non-owning
86 /// sharing handle was used.
87 fn import_completed(&self) -> ServerJobTask<()>;
88
89 /// Indicates if the device context this instance is associated with is no longer available
90 fn is_lost(&self) -> bool;
91
92 /// Releases the object on the render thread (`DisposeAsync`).
93 fn dispose_async(&self) -> ServerJobTask<()>;
94}
95
96/// An imported GPU image object that's usable by composition APIs
97pub trait ICompositionImportedGpuImage: ICompositionGpuImportedObject {
98 /// The concrete object behind the interface (the cast to the class
99 /// upstream performs on it).
100 #[doc(hidden)]
101 fn as_imported_gpu_image(&self) -> Option<&super::CompositionImportedGpuImage> {
102 None
103 }
104}
105
106/// An imported GPU semaphore object that's usable by composition APIs
107pub trait ICompositionImportedGpuSemaphore: ICompositionGpuImportedObject {
108 /// The concrete object behind the interface (the cast to the class
109 /// upstream performs on it).
110 #[doc(hidden)]
111 fn as_imported_gpu_semaphore(&self) -> Option<&super::CompositionImportedGpuSemaphore> {
112 None
113 }
114}
115
116/// An GPU object descriptor obtained from a context from the same share group as one used by the compositor
117pub trait ICompositionImportableSharedGpuContextObject {
118 fn dispose(&self);
119}
120
121/// An GPU image descriptor obtained from a context from the same share group as one used by the compositor
122///
123/// The image is shared between two threads, as upstream, where that is a
124/// convention: the thread of the caller makes it, keeps it and disposes it,
125/// and the thread that renders reads it during the import and may dispose it
126/// with the imported image. Here the type says so: what both threads read
127/// is a plain value or is behind a lock, and what belongs to the context of
128/// the caller (the context itself) is bound to its thread inside the
129/// implementation and is not touched from the other one.
130pub trait ICompositionImportableSharedGpuContextImage: Send + Sync {
131 /// Releases the image. Either thread may call it, more than once.
132 fn dispose(&self);
133
134 /// Lets the backend that made the image recover its concrete type (the
135 /// cast upstream performs on the image it is asked to import).
136 fn as_any(&self) -> &dyn std::any::Any;
137}
138
139/// An GPU semaphore descriptor obtained from a context from the same share group as one used by the compositor
140pub trait ICompositionImportableSharedGpuContextSemaphore {
141 fn dispose(&self);
142}