refactor: try to use async dmabuf importing

Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
Schmarni
2025-07-13 03:36:42 +02:00
parent c59198b4a2
commit 0ec465ac39
4 changed files with 63 additions and 89 deletions

6
Cargo.lock generated
View File

@@ -591,9 +591,7 @@ dependencies = [
[[package]]
name = "bevy-dmabuf"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4af0a7897ed821f1e8fd5e1782711b8b54722f49a9398c9713f7f72ec2c5c0e"
version = "0.2.0"
dependencies = [
"ash",
"bevy",
@@ -4014,7 +4012,7 @@ version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d"
dependencies = [
"proc-macro-crate 3.3.0",
"proc-macro-crate 1.3.1",
"proc-macro2",
"quote",
"syn 2.0.104",

View File

@@ -105,7 +105,8 @@ bevy_mod_xr = "0.3"
bevy_mod_openxr = "0.3"
# bevy_sk.git = "https://github.com/MalekiRe/bevy_sk"
bevy_sk = { git = "https://github.com/technobaboo/bevy_sk", branch = "stochastic" }
bevy-dmabuf = "0.1.0"
# bevy-dmabuf = "0.2.0"
bevy-dmabuf.path = "../bevy-dmabuf"
# bevy-mesh-text-3d.git = "https://github.com/terhechte/bevy-mesh-text-3d"
# use my fork until my pr to use minimal bevy features was merged

View File

@@ -1,18 +1,20 @@
use super::buffer_params::BufferParams;
use crate::wayland::{Message, MessageSink, core::buffer::Buffer};
use crate::wayland::{MessageSink, RENDER_DEVICE, core::buffer::Buffer};
use bevy::{
asset::{Assets, Handle},
image::Image,
};
use bevy_dmabuf::{
dmatex::{Dmatex, DmatexPlane, Resolution},
import::{ImportedDmatexs, ImportedTexture},
dmatex::{Dmatex, Resolution},
import::{DropCallback, ImportError, ImportedDmatexs, ImportedTexture, import_texture},
};
use drm_fourcc::DrmFourcc;
use mint::Vector2;
use parking_lot::Mutex;
use std::sync::{Arc, OnceLock};
use waynest::server::protocol::stable::linux_dmabuf_v1::zwp_linux_buffer_params_v1::Flags;
use waynest::server::{
Client, protocol::stable::linux_dmabuf_v1::zwp_linux_buffer_params_v1::Flags,
};
/// Parameters for a shared memory buffer
pub struct DmabufBacking {
@@ -45,64 +47,33 @@ impl DmabufBacking {
size: Vector2<u32>,
format: DrmFourcc,
flags: Flags,
) -> Self {
tracing::info!("Creating new DmabufBacking",);
Self {
) -> Result<Self, ImportError> {
tracing::info!("Creating new DmabufBacking");
let mut planes = Vec::from_iter(std::mem::take(&mut *params.planes.lock()));
planes.sort_by_key(|(index, _)| *index);
let planes = planes.into_iter().map(|(_, tex)| tex).collect::<Vec<_>>();
let dmatex = Dmatex {
planes,
res: Resolution {
x: size.x,
y: size.y,
},
format: format as u32,
// TODO: impl this in bevy-dmabuf
flip_y: flags.contains(Flags::YInvert),
};
let dev = RENDER_DEVICE.wait();
let imported_tex = import_texture(dev, dmatex, DropCallback(None))?;
Ok(Self {
params,
message_sink,
size,
format,
_flags: flags,
tex: OnceLock::new(),
pending_imported_dmatex: Mutex::new(None),
}
}
fn import_dmabuf(
&self,
dmatexes: &ImportedDmatexs,
images: &mut Assets<Image>,
buffer: Arc<Buffer>,
) -> Option<Handle<Image>> {
let mut planes = std::mem::take(&mut *self.params.planes.lock());
// TODO: AAAAAA BAD HACK WHAT THE HELL FIX THIS
let key = *planes.keys().last().unwrap();
let plane = planes.remove(&key).unwrap();
let dmatex = Dmatex {
dmabuf_fd: plane.fd.into(),
planes: vec![DmatexPlane {
offset: plane.offset,
stride: plane.stride as i32,
}],
res: Resolution {
x: self.size.x,
y: self.size.y,
},
modifier: plane.modifier,
format: self.format as u32,
flip_y: self._flags.contains(Flags::YInvert),
};
let dmatex = dmatexes.set(images, dmatex, None);
match &dmatex {
Ok(_) => {
let _ = self
.message_sink
.as_ref()
.unwrap()
.send(Message::DmabufImportSuccess(self.params.clone(), buffer));
}
Err(e) => {
tracing::error!("Failed to import dmabuf because {e}");
let _ = self
.message_sink
.as_ref()
.unwrap()
.send(Message::DmabufImportFailure(self.params.clone()));
}
}
dmatex.ok()
pending_imported_dmatex: Mutex::new(Some(imported_tex)),
})
}
pub fn update_tex(
@@ -115,12 +86,9 @@ impl DmabufBacking {
.lock()
.take()
.map(|tex| dmatexes.insert_imported_dmatex(images, tex))
// if self.tex.get().is_none()
// && let Some(dmatex) = self.import_dmabuf(dmatexes, images, buffer)
// {
// let _ = self.tex.set(dmatex);
// }
// self.tex.get().cloned()
.inspect(|handle| {
_ = self.tex.set(handle.clone());
})
}
pub fn is_transparent(&self) -> bool {

View File

@@ -3,6 +3,7 @@ use crate::wayland::{
core::buffer::{Buffer, BufferBacking},
util::ClientExt,
};
use bevy_dmabuf::dmatex::DmatexPlane;
use drm_fourcc::DrmFourcc;
use parking_lot::Mutex;
use rustc_hash::FxHashMap;
@@ -17,15 +18,6 @@ use waynest::{
wire::ObjectId,
};
/// A single plane in a DMA-BUF buffer
#[derive(Debug)]
pub struct DmabufPlane {
pub fd: OwnedFd,
pub offset: u32,
pub stride: u32,
pub modifier: u64,
}
/// Parameters for creating a DMA-BUF-based wl_buffer
///
/// This is a temporary object that collects dmabufs and other parameters
@@ -34,7 +26,7 @@ pub struct DmabufPlane {
#[derive(Debug, Dispatcher)]
pub struct BufferParams {
pub id: ObjectId,
pub(super) planes: Mutex<FxHashMap<u32, DmabufPlane>>,
pub(super) planes: Mutex<FxHashMap<u32, DmatexPlane>>,
}
impl BufferParams {
@@ -85,10 +77,10 @@ impl ZwpLinuxBufferParamsV1 for BufferParams {
}
// Create plane with the provided parameters
let plane = DmabufPlane {
fd,
let plane = DmatexPlane {
dmabuf_fd: fd.into(),
offset,
stride,
stride: stride as i32,
modifier: ((modifier_hi as u64) << 32) | (modifier_lo as u64),
};
@@ -109,17 +101,26 @@ impl ZwpLinuxBufferParamsV1 for BufferParams {
tracing::info!("Creating buffer from BufferParams {:?}", self.id);
// Create the buffer with DMA-BUF backing using self as the backing
let size = [width as u32, height as u32].into();
let backing = DmabufBacking::new(
let buffer = DmabufBacking::new(
client.get::<Self>(self.id).unwrap(),
Some(client.display().message_sink.clone()),
size,
DrmFourcc::try_from(format).unwrap(),
flags,
);
let id = client.display().next_server_id();
Buffer::new(client, id, BufferBacking::Dmabuf(backing));
)
.inspect_err(|e| tracing::error!("Failed to import dmabuf because {e}"))
.map(|backing| {
let id = client.display().next_server_id();
Buffer::new(client, id, BufferBacking::Dmabuf(backing))
});
Ok(())
match buffer {
Ok(buffer) => self.created(client, self.id, buffer.id).await,
Err(_) => {
client.remove(self.id);
self.failed(client, self.id).await
}
}
}
async fn create_immed(
@@ -132,15 +133,17 @@ impl ZwpLinuxBufferParamsV1 for BufferParams {
format: u32,
flags: Flags,
) -> Result<()> {
// TODO: terminate client on fail, or send a fail event or something
// Create the buffer with DMA-BUF backing using self as the backing
let backing = DmabufBacking::new(
_ = DmabufBacking::new(
client.get::<Self>(self.id).unwrap(),
None,
[width as u32, height as u32].into(),
DrmFourcc::try_from(format).unwrap(),
flags,
);
Buffer::new(client, buffer_id, BufferBacking::Dmabuf(backing));
)
.inspect_err(|e| tracing::error!("Failed to import dmabuf because {e}"))
.map(|backing| Buffer::new(client, buffer_id, BufferBacking::Dmabuf(backing)));
Ok(())
}
@@ -151,7 +154,11 @@ impl Drop for BufferParams {
let planes = self.planes.get_mut();
tracing::info!("BufferParams being dropped with {} planes", planes.len());
for (idx, plane) in planes.iter() {
tracing::info!("Dropping plane {} with fd {}", idx, plane.fd.as_raw_fd());
tracing::info!(
"Dropping plane {} with fd {}",
idx,
plane.dmabuf_fd.as_raw_fd()
);
}
planes.clear();
}