diff --git a/Cargo.lock b/Cargo.lock index ff6fe88..290aa3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/Cargo.toml b/Cargo.toml index 968cd96..d231acc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 diff --git a/src/wayland/dmabuf/buffer_backing.rs b/src/wayland/dmabuf/buffer_backing.rs index f3994d5..ed6c5ef 100644 --- a/src/wayland/dmabuf/buffer_backing.rs +++ b/src/wayland/dmabuf/buffer_backing.rs @@ -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, format: DrmFourcc, flags: Flags, - ) -> Self { - tracing::info!("Creating new DmabufBacking",); - Self { + ) -> Result { + 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::>(); + 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, - buffer: Arc, - ) -> Option> { - 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 { diff --git a/src/wayland/dmabuf/buffer_params.rs b/src/wayland/dmabuf/buffer_params.rs index 59efb2c..2755db5 100644 --- a/src/wayland/dmabuf/buffer_params.rs +++ b/src/wayland/dmabuf/buffer_params.rs @@ -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>, + pub(super) planes: Mutex>, } 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.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.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(); }