mirror of
https://gitlab.com/marcandre.lureau/qemu-display.git
synced 2025-01-03 03:05:18 +00:00
Implement experimental D3D Texture2D sharing
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
parent
4126bd092c
commit
8b9a70505b
@ -50,6 +50,28 @@ pub struct UpdateMap {
|
||||
pub h: i32,
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[derive(Debug)]
|
||||
pub struct ScanoutD3dTexture2d {
|
||||
pub handle: u64,
|
||||
pub tex_width: u32,
|
||||
pub tex_height: u32,
|
||||
pub y0_top: bool,
|
||||
pub x: u32,
|
||||
pub y: u32,
|
||||
pub w: u32,
|
||||
pub h: u32,
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct UpdateD3dTexture2d {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub w: i32,
|
||||
pub h: i32,
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[derive(Debug)]
|
||||
pub struct ScanoutDMABUF {
|
||||
@ -122,6 +144,12 @@ pub trait ConsoleListenerHandler: 'static + Send + Sync {
|
||||
#[cfg(windows)]
|
||||
async fn update_map(&mut self, update: UpdateMap);
|
||||
|
||||
#[cfg(windows)]
|
||||
async fn scanout_d3d11_texture2d(&mut self, scanout: ScanoutD3dTexture2d);
|
||||
|
||||
#[cfg(windows)]
|
||||
async fn update_d3d11_texture2d(&mut self, update: UpdateD3dTexture2d);
|
||||
|
||||
#[cfg(unix)]
|
||||
async fn scanout_dmabuf(&mut self, scanout: ScanoutDMABUF);
|
||||
|
||||
@ -237,6 +265,75 @@ impl<H: ConsoleListenerHandler> ConsoleListener<H> {
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
async fn scanout_d3d11_texture2d(
|
||||
&mut self,
|
||||
handle: u64,
|
||||
tex_width: u32,
|
||||
tex_height: u32,
|
||||
y0_top: bool,
|
||||
x: u32,
|
||||
y: u32,
|
||||
w: u32,
|
||||
h: u32,
|
||||
) -> zbus::fdo::Result<()> {
|
||||
let texture = ScanoutD3dTexture2d {
|
||||
handle,
|
||||
tex_width,
|
||||
tex_height,
|
||||
y0_top,
|
||||
x,
|
||||
y,
|
||||
w,
|
||||
h,
|
||||
};
|
||||
self.handler.scanout_d3d11_texture2d(texture).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
async fn scanout_d3d11_texture2d(
|
||||
&mut self,
|
||||
_handle: u64,
|
||||
_tex_width: u32,
|
||||
_tex_height: u32,
|
||||
_y0_top: bool,
|
||||
_x: u32,
|
||||
_y: u32,
|
||||
_w: u32,
|
||||
_h: u32,
|
||||
) -> zbus::fdo::Result<()> {
|
||||
Err(zbus::fdo::Error::NotSupported(
|
||||
"D3D is not support on !windows".into(),
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
async fn update_d3d11_texture2d(
|
||||
&mut self,
|
||||
x: i32,
|
||||
y: i32,
|
||||
w: i32,
|
||||
h: i32,
|
||||
) -> zbus::fdo::Result<()> {
|
||||
let up = UpdateD3dTexture2d { x, y, w, h };
|
||||
self.handler.update_d3d11_texture2d(up).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
async fn update_d3d11_texture2d(
|
||||
&mut self,
|
||||
_x: i32,
|
||||
_y: i32,
|
||||
_w: i32,
|
||||
_h: i32,
|
||||
) -> zbus::fdo::Result<()> {
|
||||
Err(zbus::fdo::Error::NotSupported(
|
||||
"D3d is not support on !windows".into(),
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
#[dbus_interface(name = "ScanoutDMABUF")]
|
||||
async fn scanout_dmabuf(
|
||||
|
@ -248,6 +248,26 @@ mod imp {
|
||||
let bytes = map.as_bytes();
|
||||
this.obj().update_area(u.x as _, u.y as _, u.w as _, u.h as _, stride as _, &bytes[u.y as usize * stride as usize + u.x as usize * 4..]);
|
||||
}
|
||||
#[cfg(windows)]
|
||||
ScanoutD3dTexture2d(s) => {
|
||||
log::debug!("{s:?}");
|
||||
this.obj().set_display_size(Some((s.w as _, s.h as _)));
|
||||
this.obj().set_d3d11_texture2d_scanout(rdw::RdwD3d11Texture2dScanout {
|
||||
handle: s.handle as _,
|
||||
tex_width: s.tex_width,
|
||||
tex_height: s.tex_height,
|
||||
y0_top: s.y0_top,
|
||||
x: s.x,
|
||||
y: s.y,
|
||||
w: s.w,
|
||||
h: s.h,
|
||||
});
|
||||
}
|
||||
#[cfg(windows)]
|
||||
UpdateD3dTexture2d { wait_tx, .. } => {
|
||||
this.obj().render();
|
||||
let _ = wait_tx.send(());
|
||||
}
|
||||
#[cfg(unix)]
|
||||
ScanoutDMABUF(s) => {
|
||||
log::trace!("{s:?}");
|
||||
@ -337,6 +357,13 @@ enum ConsoleEvent {
|
||||
ScanoutMap(qemu_display::ScanoutMap),
|
||||
#[cfg(windows)]
|
||||
UpdateMap(qemu_display::UpdateMap),
|
||||
#[cfg(windows)]
|
||||
ScanoutD3dTexture2d(qemu_display::ScanoutD3dTexture2d),
|
||||
#[cfg(windows)]
|
||||
UpdateD3dTexture2d {
|
||||
_update: qemu_display::UpdateD3dTexture2d,
|
||||
wait_tx: futures::channel::oneshot::Sender<()>,
|
||||
},
|
||||
#[cfg(unix)]
|
||||
ScanoutDMABUF(qemu_display::ScanoutDMABUF),
|
||||
#[cfg(unix)]
|
||||
@ -382,6 +409,20 @@ impl ConsoleListenerHandler for ConsoleHandler {
|
||||
self.send(ConsoleEvent::UpdateMap(update));
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
async fn scanout_d3d11_texture2d(&mut self, scanout: qemu_display::ScanoutD3dTexture2d) {
|
||||
self.send(ConsoleEvent::ScanoutD3dTexture2d(scanout));
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
async fn update_d3d11_texture2d(&mut self, _update: qemu_display::UpdateD3dTexture2d) {
|
||||
let (wait_tx, wait_rx) = futures::channel::oneshot::channel();
|
||||
self.send(ConsoleEvent::UpdateD3dTexture2d { _update, wait_tx });
|
||||
if let Err(e) = wait_rx.await {
|
||||
log::warn!("wait update d3d texture2d failed: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
async fn scanout_dmabuf(&mut self, scanout: qemu_display::ScanoutDMABUF) {
|
||||
self.send(ConsoleEvent::ScanoutDMABUF(scanout));
|
||||
|
Loading…
Reference in New Issue
Block a user