1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use crate::{
    DeviceError, DynCommandBuffer, DynFence, DynResource, DynSurface, DynSurfaceTexture,
    FenceValue, Queue, SurfaceError,
};

use super::DynResourceExt as _;

pub trait DynQueue: DynResource {
    unsafe fn submit(
        &self,
        command_buffers: &[&dyn DynCommandBuffer],
        surface_textures: &[&dyn DynSurfaceTexture],
        signal_fence: (&mut dyn DynFence, FenceValue),
    ) -> Result<(), DeviceError>;
    unsafe fn present(
        &self,
        surface: &dyn DynSurface,
        texture: Box<dyn DynSurfaceTexture>,
    ) -> Result<(), SurfaceError>;
    unsafe fn get_timestamp_period(&self) -> f32;
}

impl<Q: Queue + DynResource> DynQueue for Q {
    unsafe fn submit(
        &self,
        command_buffers: &[&dyn DynCommandBuffer],
        surface_textures: &[&dyn DynSurfaceTexture],
        signal_fence: (&mut dyn DynFence, FenceValue),
    ) -> Result<(), DeviceError> {
        let command_buffers = command_buffers
            .iter()
            .map(|cb| (*cb).expect_downcast_ref())
            .collect::<Vec<_>>();
        let surface_textures = surface_textures
            .iter()
            .map(|surface| (*surface).expect_downcast_ref())
            .collect::<Vec<_>>();
        let signal_fence = (signal_fence.0.expect_downcast_mut(), signal_fence.1);
        unsafe { Q::submit(self, &command_buffers, &surface_textures, signal_fence) }
    }

    unsafe fn present(
        &self,
        surface: &dyn DynSurface,
        texture: Box<dyn DynSurfaceTexture>,
    ) -> Result<(), SurfaceError> {
        let surface = surface.expect_downcast_ref();
        unsafe { Q::present(self, surface, texture.unbox()) }
    }

    unsafe fn get_timestamp_period(&self) -> f32 {
        unsafe { Q::get_timestamp_period(self) }
    }
}