use super::server::{IServerObject, LockBound, ServerCompositionDrawingSurface, ServerCompositor, ServerObjectId};
use super::{
CompositionSurface, Compositor, ICompositionImportedGpuImage, ICompositionImportedGpuSemaphore, ServerImportedGpuImage,
ServerImportedGpuSemaphore, ServerJobTask,
};
use std::ops::Deref;
use std::rc::Rc;
use std::sync::Arc;
#[derive(Clone)]
pub struct CompositionDrawingSurface(Rc<CompositionSurface>);
impl Deref for CompositionDrawingSurface {
type Target = Rc<CompositionSurface>;
fn deref(&self) -> &Rc<CompositionSurface> {
&self.0
}
}
fn imported_image(image: &dyn ICompositionImportedGpuImage) -> Arc<LockBound<ServerImportedGpuImage>> {
match image.as_imported_gpu_image() {
Some(image) => image.server(),
None => panic!("the image was not imported by a composition interop"),
}
}
fn imported_semaphore(semaphore: &dyn ICompositionImportedGpuSemaphore) -> Arc<LockBound<ServerImportedGpuSemaphore>> {
match semaphore.as_imported_gpu_semaphore() {
Some(semaphore) => semaphore.server(),
None => panic!("the semaphore was not imported by a composition interop"),
}
}
impl CompositionDrawingSurface {
pub(crate) fn new(compositor: &Rc<Compositor>) -> CompositionDrawingSurface {
let server = compositor.create_server_object(|compositor, _| ServerCompositionDrawingSurface::new(compositor));
CompositionDrawingSurface(CompositionSurface::new(compositor, server))
}
fn server_id(&self) -> ServerObjectId {
super::ICompositionObject::server(&*self.0)
}
fn invoke(
&self,
update: impl FnOnce(&ServerCompositor, &ServerCompositionDrawingSurface) -> Result<(), crate::rendering::composition::ServerJobError>
+ Send
+ 'static,
) -> ServerJobTask<()> {
self.compositor().invoke_server_object_job_async(
self.server_id(),
move |compositor, server: Option<Rc<dyn IServerObject>>| {
let server = server.and_then(|server| server.into_any_rc().downcast::<ServerCompositionDrawingSurface>().ok());
match server {
Some(server) => update(compositor, &server),
None => panic!("the server object of a live drawing surface is not a drawing surface"),
}
},
false,
)
}
pub fn update_with_keyed_mutex_async(
&self,
image: &dyn ICompositionImportedGpuImage,
acquire_index: u32,
release_index: u32,
) -> ServerJobTask<()> {
let img = imported_image(image);
self.invoke(move |compositor, server| {
server.update_with_keyed_mutex(img.get(compositor), acquire_index, release_index)
})
}
pub fn update_with_semaphores_async(
&self,
image: &dyn ICompositionImportedGpuImage,
wait_for_semaphore: &dyn ICompositionImportedGpuSemaphore,
signal_semaphore: &dyn ICompositionImportedGpuSemaphore,
) -> ServerJobTask<()> {
let img = imported_image(image);
let wait = imported_semaphore(wait_for_semaphore);
let signal = imported_semaphore(signal_semaphore);
self.invoke(move |compositor, server| {
server.update_with_semaphores(img.get(compositor), wait.get(compositor), signal.get(compositor))
})
}
pub fn update_with_timeline_semaphores_async(
&self,
image: &dyn ICompositionImportedGpuImage,
wait_for_semaphore: &dyn ICompositionImportedGpuSemaphore,
wait_for_value: u64,
signal_semaphore: &dyn ICompositionImportedGpuSemaphore,
signal_value: u64,
) -> ServerJobTask<()> {
let img = imported_image(image);
let wait = imported_semaphore(wait_for_semaphore);
let signal = imported_semaphore(signal_semaphore);
self.invoke(move |compositor, server| {
server.update_with_timeline_semaphores(
img.get(compositor),
wait.get(compositor),
wait_for_value,
signal.get(compositor),
signal_value,
)
})
}
pub fn update_async(&self, image: &dyn ICompositionImportedGpuImage) -> ServerJobTask<()> {
let img = imported_image(image);
self.invoke(move |compositor, server| server.update_with_automatic_sync(img.get(compositor)))
}
pub fn dispose(&self) {
self.0.dispose()
}
}