ferroui_base/rendering/composition/
composition_drawing_surface.rs1use super::server::{IServerObject, LockBound, ServerCompositionDrawingSurface, ServerCompositor, ServerObjectId};
2use super::{
3 CompositionSurface, Compositor, ICompositionImportedGpuImage, ICompositionImportedGpuSemaphore, ServerImportedGpuImage,
4 ServerImportedGpuSemaphore, ServerJobTask,
5};
6use std::ops::Deref;
7use std::rc::Rc;
8use std::sync::Arc;
9
10#[derive(Clone)]
12pub struct CompositionDrawingSurface(Rc<CompositionSurface>);
13
14impl Deref for CompositionDrawingSurface {
15 type Target = Rc<CompositionSurface>;
16
17 fn deref(&self) -> &Rc<CompositionSurface> {
18 &self.0
19 }
20}
21
22fn imported_image(image: &dyn ICompositionImportedGpuImage) -> Arc<LockBound<ServerImportedGpuImage>> {
25 match image.as_imported_gpu_image() {
26 Some(image) => image.server(),
27 None => panic!("the image was not imported by a composition interop"),
28 }
29}
30
31fn imported_semaphore(semaphore: &dyn ICompositionImportedGpuSemaphore) -> Arc<LockBound<ServerImportedGpuSemaphore>> {
33 match semaphore.as_imported_gpu_semaphore() {
34 Some(semaphore) => semaphore.server(),
35 None => panic!("the semaphore was not imported by a composition interop"),
36 }
37}
38
39impl CompositionDrawingSurface {
40 pub(crate) fn new(compositor: &Rc<Compositor>) -> CompositionDrawingSurface {
41 let server = compositor.create_server_object(|compositor, _| ServerCompositionDrawingSurface::new(compositor));
42 CompositionDrawingSurface(CompositionSurface::new(compositor, server))
43 }
44
45 fn server_id(&self) -> ServerObjectId {
46 super::ICompositionObject::server(&*self.0)
47 }
48
49 fn invoke(
57 &self,
58 update: impl FnOnce(&ServerCompositor, &ServerCompositionDrawingSurface) -> Result<(), crate::rendering::composition::ServerJobError>
59 + Send
60 + 'static,
61 ) -> ServerJobTask<()> {
62 self.compositor().invoke_server_object_job_async(
66 self.server_id(),
67 move |compositor, server: Option<Rc<dyn IServerObject>>| {
68 let server = server.and_then(|server| server.into_any_rc().downcast::<ServerCompositionDrawingSurface>().ok());
69 match server {
70 Some(server) => update(compositor, &server),
71 None => panic!("the server object of a live drawing surface is not a drawing surface"),
72 }
73 },
74 false,
75 )
76 }
77
78 pub fn update_with_keyed_mutex_async(
85 &self,
86 image: &dyn ICompositionImportedGpuImage,
87 acquire_index: u32,
88 release_index: u32,
89 ) -> ServerJobTask<()> {
90 let img = imported_image(image);
91 self.invoke(move |compositor, server| {
92 server.update_with_keyed_mutex(img.get(compositor), acquire_index, release_index)
93 })
94 }
95
96 pub fn update_with_semaphores_async(
102 &self,
103 image: &dyn ICompositionImportedGpuImage,
104 wait_for_semaphore: &dyn ICompositionImportedGpuSemaphore,
105 signal_semaphore: &dyn ICompositionImportedGpuSemaphore,
106 ) -> ServerJobTask<()> {
107 let img = imported_image(image);
108 let wait = imported_semaphore(wait_for_semaphore);
109 let signal = imported_semaphore(signal_semaphore);
110 self.invoke(move |compositor, server| {
111 server.update_with_semaphores(img.get(compositor), wait.get(compositor), signal.get(compositor))
112 })
113 }
114
115 pub fn update_with_timeline_semaphores_async(
121 &self,
122 image: &dyn ICompositionImportedGpuImage,
123 wait_for_semaphore: &dyn ICompositionImportedGpuSemaphore,
124 wait_for_value: u64,
125 signal_semaphore: &dyn ICompositionImportedGpuSemaphore,
126 signal_value: u64,
127 ) -> ServerJobTask<()> {
128 let img = imported_image(image);
129 let wait = imported_semaphore(wait_for_semaphore);
130 let signal = imported_semaphore(signal_semaphore);
131 self.invoke(move |compositor, server| {
132 server.update_with_timeline_semaphores(
133 img.get(compositor),
134 wait.get(compositor),
135 wait_for_value,
136 signal.get(compositor),
137 signal_value,
138 )
139 })
140 }
141
142 pub fn update_async(&self, image: &dyn ICompositionImportedGpuImage) -> ServerJobTask<()> {
145 let img = imported_image(image);
146 self.invoke(move |compositor, server| server.update_with_automatic_sync(img.get(compositor)))
147 }
148
149 pub fn dispose(&self) {
150 self.0.dispose()
151 }
152}