Skip to main content

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}