refactor(wayland): continue implementing better buffer release

Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
Schmarni
2025-07-18 02:37:30 +02:00
parent eca5bb4bf2
commit 9466e97dd1
4 changed files with 46 additions and 24 deletions

View File

@@ -16,24 +16,22 @@ use waynest::{
#[derive(Debug)] #[derive(Debug)]
pub struct BufferUsage { pub struct BufferUsage {
pub buffer: Weak<Buffer>, pub buffer: Arc<Buffer>,
message_sink: MessageSink, message_sink: MessageSink,
} }
impl BufferUsage { impl BufferUsage {
pub fn new(client: &Client, buffer: &Arc<Buffer>) -> Arc<Self> { pub fn new(client: &Client, buffer: &Arc<Buffer>) -> Arc<Self> {
Arc::new(Self { Arc::new(Self {
buffer: Arc::downgrade(buffer), buffer: buffer.clone(),
message_sink: client.message_sink(), message_sink: client.message_sink(),
}) })
} }
} }
impl Drop for BufferUsage { impl Drop for BufferUsage {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(buffer) = self.buffer.upgrade() { self.message_sink
self.message_sink .send(Message::ReleaseBuffer(self.buffer.clone()))
.send(Message::ReleaseBuffer(buffer)) .unwrap();
.unwrap();
}
} }
} }
@@ -42,7 +40,6 @@ pub enum BufferBacking {
Shm(ShmBufferBacking), Shm(ShmBufferBacking),
Dmabuf(DmabufBacking), Dmabuf(DmabufBacking),
} }
impl BufferBacking {}
#[derive(Debug, Dispatcher)] #[derive(Debug, Dispatcher)]
pub struct Buffer { pub struct Buffer {
@@ -83,6 +80,9 @@ impl Buffer {
BufferBacking::Dmabuf(backing) => backing.size(), BufferBacking::Dmabuf(backing) => backing.size(),
} }
} }
pub fn uses_buffer_usage(&self) -> bool {
matches!(self.backing, BufferBacking::Dmabuf(_))
}
} }
impl WlBuffer for Buffer { impl WlBuffer for Buffer {

View File

@@ -38,7 +38,7 @@ pub enum SurfaceRole {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct BufferState { pub struct BufferState {
pub buffer: Arc<Buffer>, pub buffer: Arc<Buffer>,
pub usage: Arc<BufferUsage>, pub usage: Option<Arc<BufferUsage>>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -232,7 +232,9 @@ impl WlSurface for Surface {
self.state.lock().pending.buffer = buffer.and_then(|b| { self.state.lock().pending.buffer = buffer.and_then(|b| {
let buffer = client.get::<Buffer>(b)?; let buffer = client.get::<Buffer>(b)?;
Some(BufferState { Some(BufferState {
usage: BufferUsage::new(client, &buffer), usage: buffer
.uses_buffer_usage()
.then(|| BufferUsage::new(client, &buffer)),
buffer, buffer,
}) })
}); });

View File

@@ -1,8 +1,5 @@
use super::buffer_params::BufferParams; use super::buffer_params::BufferParams;
use crate::{ use crate::wayland::{MessageSink, RENDER_DEVICE};
core::registry::Registry,
wayland::{MessageSink, RENDER_DEVICE, core::buffer::BufferUsage},
};
use bevy::{ use bevy::{
asset::{Assets, Handle}, asset::{Assets, Handle},
image::Image, image::Image,
@@ -18,9 +15,6 @@ use std::sync::{Arc, OnceLock};
use tracing::info; use tracing::info;
use waynest::server::protocol::stable::linux_dmabuf_v1::zwp_linux_buffer_params_v1::Flags; use waynest::server::protocol::stable::linux_dmabuf_v1::zwp_linux_buffer_params_v1::Flags;
// clear this out on end frame, add to it whenever a commit with the surface with the buffer is present
const IN_USE_DMABUFS: Registry<BufferUsage> = Registry::new();
/// Parameters for a shared memory buffer /// Parameters for a shared memory buffer
pub struct DmabufBacking { pub struct DmabufBacking {
message_sink: Option<MessageSink>, message_sink: Option<MessageSink>,
@@ -88,9 +82,7 @@ impl DmabufBacking {
&self, &self,
dmatexes: &ImportedDmatexs, dmatexes: &ImportedDmatexs,
images: &mut Assets<Image>, images: &mut Assets<Image>,
usage: Arc<BufferUsage>,
) -> Option<Handle<Image>> { ) -> Option<Handle<Image>> {
IN_USE_DMABUFS.add_raw(usage);
info!("updating dmabuf tex"); info!("updating dmabuf tex");
self.pending_imported_dmatex self.pending_imported_dmatex
.lock() .lock()

View File

@@ -16,13 +16,17 @@ use crate::{
use bevy::app::{App, Plugin, Update}; use bevy::app::{App, Plugin, Update};
use bevy::ecs::schedule::IntoScheduleConfigs; use bevy::ecs::schedule::IntoScheduleConfigs;
use bevy::ecs::system::{Res, ResMut}; use bevy::ecs::system::{Res, ResMut};
use bevy::prelude::{Deref, DerefMut};
use bevy::render::renderer::RenderDevice; use bevy::render::renderer::RenderDevice;
use bevy::render::{Render, RenderApp}; use bevy::render::{Render, RenderApp};
use bevy::{asset::Assets, ecs::resource::Resource, image::Image}; use bevy::{asset::Assets, ecs::resource::Resource, image::Image};
use bevy_dmabuf::import::ImportedDmatexs; use bevy_dmabuf::import::ImportedDmatexs;
use bevy_mod_xr::session::XrRenderSet;
use cluFlock::{FlockLock, ToFlock}; use cluFlock::{FlockLock, ToFlock};
use core::buffer::BufferUsage;
use core::{buffer::Buffer, callback::Callback, display::Display, surface::WL_SURFACE_REGISTRY}; use core::{buffer::Buffer, callback::Callback, display::Display, surface::WL_SURFACE_REGISTRY};
use mint::Vector2; use mint::Vector2;
use rustc_hash::FxHashMap;
use std::fs::File; use std::fs::File;
use std::{ use std::{
fs::{self, OpenOptions}, fs::{self, OpenOptions},
@@ -285,17 +289,41 @@ impl Plugin for WaylandPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_systems(PreFrameWait, early_frame); app.add_systems(PreFrameWait, early_frame);
app.add_systems(Update, update_graphics); app.add_systems(Update, update_graphics);
app.sub_app_mut(RenderApp).add_systems( app.sub_app_mut(RenderApp)
Render, .init_resource::<UsedBuffers>()
init_render_device.run_if(|| RENDER_DEVICE.get().is_none()), .add_systems(
); Render,
init_render_device.run_if(|| RENDER_DEVICE.get().is_none()),
);
} }
fn finish(&self, app: &mut App) { fn finish(&self, app: &mut App) {
app.sub_app_mut(RenderApp) app.sub_app_mut(RenderApp)
.add_systems(Render, setup_vulkano_context); .add_systems(Render, setup_vulkano_context)
.add_systems(Render, push_used_buffers.in_set(XrRenderSet::PreRender))
.add_systems(
Render,
release_unneeded_buffers.in_set(XrRenderSet::PostRender),
);
} }
} }
#[derive(Resource, Default, Deref, DerefMut)]
struct UsedBuffers(FxHashMap<ObjectId, Arc<BufferUsage>>);
fn push_used_buffers(mut buffers: ResMut<UsedBuffers>) {
for surface in WL_SURFACE_REGISTRY.get_valid_contents() {
if let Some(buffer) = surface.current_state().buffer.and_then(|b| b.usage).clone() {
buffers.insert(buffer.buffer.id, buffer);
}
}
}
fn release_unneeded_buffers(mut buffers: ResMut<UsedBuffers>) {
dbg!(buffers.len());
buffers.retain(|_, v| Arc::downgrade(v).strong_count() > 1);
dbg!(buffers.len());
}
fn init_render_device(dev: Res<RenderDevice>) { fn init_render_device(dev: Res<RenderDevice>) {
_ = RENDER_DEVICE.set(dev.clone()); _ = RENDER_DEVICE.set(dev.clone());
} }