mirror of
https://gitlab.com/marcandre.lureau/qemu-display.git
synced 2025-01-05 03:55:19 +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,
|
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)]
|
#[cfg(unix)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ScanoutDMABUF {
|
pub struct ScanoutDMABUF {
|
||||||
@ -122,6 +144,12 @@ pub trait ConsoleListenerHandler: 'static + Send + Sync {
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
async fn update_map(&mut self, update: UpdateMap);
|
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)]
|
#[cfg(unix)]
|
||||||
async fn scanout_dmabuf(&mut self, scanout: ScanoutDMABUF);
|
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))]
|
#[cfg(not(unix))]
|
||||||
#[dbus_interface(name = "ScanoutDMABUF")]
|
#[dbus_interface(name = "ScanoutDMABUF")]
|
||||||
async fn scanout_dmabuf(
|
async fn scanout_dmabuf(
|
||||||
|
@ -248,6 +248,26 @@ mod imp {
|
|||||||
let bytes = map.as_bytes();
|
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..]);
|
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)]
|
#[cfg(unix)]
|
||||||
ScanoutDMABUF(s) => {
|
ScanoutDMABUF(s) => {
|
||||||
log::trace!("{s:?}");
|
log::trace!("{s:?}");
|
||||||
@ -337,6 +357,13 @@ enum ConsoleEvent {
|
|||||||
ScanoutMap(qemu_display::ScanoutMap),
|
ScanoutMap(qemu_display::ScanoutMap),
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
UpdateMap(qemu_display::UpdateMap),
|
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)]
|
#[cfg(unix)]
|
||||||
ScanoutDMABUF(qemu_display::ScanoutDMABUF),
|
ScanoutDMABUF(qemu_display::ScanoutDMABUF),
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@ -382,6 +409,20 @@ impl ConsoleListenerHandler for ConsoleHandler {
|
|||||||
self.send(ConsoleEvent::UpdateMap(update));
|
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)]
|
#[cfg(unix)]
|
||||||
async fn scanout_dmabuf(&mut self, scanout: qemu_display::ScanoutDMABUF) {
|
async fn scanout_dmabuf(&mut self, scanout: qemu_display::ScanoutDMABUF) {
|
||||||
self.send(ConsoleEvent::ScanoutDMABUF(scanout));
|
self.send(ConsoleEvent::ScanoutDMABUF(scanout));
|
||||||
|
Loading…
Reference in New Issue
Block a user