Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,14 @@ harness = false
[profile.release-with-debug]
inherits = "release"
debug = true

[patch."crates-io"]
wayland-server = { git = "https://github.com/smithay/wayland-rs" }
wayland-egl = { git = "https://github.com/smithay/wayland-rs" }
wayland-client = { git = "https://github.com/smithay/wayland-rs" }
wayland-cursor = { git = "https://github.com/smithay/wayland-rs" }
wayland-protocols = { git = "https://github.com/smithay/wayland-rs" }
wayland-protocols-wlr = { git = "https://github.com/smithay/wayland-rs" }
wayland-protocols-misc = { git = "https://github.com/smithay/wayland-rs" }
wayland-sys = { git = "https://github.com/smithay/wayland-rs" }
wayland-backend = { git = "https://github.com/smithay/wayland-rs" }
21 changes: 18 additions & 3 deletions src/backend/renderer/utils/wayland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use std::{

use super::{CommitCounter, DamageBag, DamageSet, DamageSnapshot, SurfaceView};
use tracing::{error, instrument, warn};
use wayland_server::protocol::{wl_buffer::WlBuffer, wl_surface::WlSurface};
use wayland_server::protocol::{wl_buffer::WlBuffer, wl_callback::WlCallback, wl_surface::WlSurface};

/// Type stored in WlSurface states data_map
///
Expand Down Expand Up @@ -59,6 +59,7 @@ unsafe impl Sync for RendererSurfaceState {}
#[derive(Debug)]
struct InnerBuffer {
buffer: WlBuffer,
release_callback: Option<WlCallback>,
#[cfg(feature = "backend_drm")]
acquire_point: Option<DrmSyncPoint>,
#[cfg(feature = "backend_drm")]
Expand All @@ -69,6 +70,9 @@ impl Drop for InnerBuffer {
#[inline]
fn drop(&mut self) {
self.buffer.release();
if let Some(callback) = &self.release_callback {
callback.done(0);
}
#[cfg(feature = "backend_drm")]
if let Some(release_point) = &self.release_point {
if let Err(err) = release_point.signal() {
Expand All @@ -86,10 +90,11 @@ pub struct Buffer {

impl Buffer {
/// Create a buffer with implicit sync
pub fn with_implicit(buffer: WlBuffer) -> Self {
pub fn with_implicit(buffer: WlBuffer, release_callback: Option<WlCallback>) -> Self {
Self {
inner: Arc::new(InnerBuffer {
buffer,
release_callback,
#[cfg(feature = "backend_drm")]
acquire_point: None,
#[cfg(feature = "backend_drm")]
Expand All @@ -100,9 +105,15 @@ impl Buffer {

/// Create a buffer with explicit acquire and release sync points
#[cfg(feature = "backend_drm")]
pub fn with_explicit(buffer: WlBuffer, acquire_point: DrmSyncPoint, release_point: DrmSyncPoint) -> Self {
pub fn with_explicit(
buffer: WlBuffer,
release_callback: Option<WlCallback>,
acquire_point: DrmSyncPoint,
release_point: DrmSyncPoint,
) -> Self {
Self {
inner: Arc::new(InnerBuffer {
release_callback,
buffer,
acquire_point: Some(acquire_point),
release_point: Some(release_point),
Expand Down Expand Up @@ -154,6 +165,9 @@ impl RendererSurfaceState {
let new_buffer = matches!(attrs.buffer, Some(BufferAssignment::NewBuffer(_)));
match attrs.buffer.take() {
Some(BufferAssignment::NewBuffer(buffer)) => {
// TODO protocol error if set without buffer
let release_callback = attrs.release_callback.take();

self.buffer_dimensions = buffer_dimensions(&buffer);
if self.buffer_dimensions.is_none() {
// This results in us rendering nothing (can happen e.g. for failed egl-buffer-calls),
Expand All @@ -169,6 +183,7 @@ impl RendererSurfaceState {
self.buffer = Some(Buffer {
inner: Arc::new(InnerBuffer {
buffer,
release_callback,
#[cfg(feature = "backend_drm")]
acquire_point: syncobj_state.acquire_point.take(),
#[cfg(feature = "backend_drm")]
Expand Down
16 changes: 16 additions & 0 deletions src/wayland/compositor/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ where
},
);
}
wl_compositor::Request::Release => {}
_ => unreachable!(),
}
}
Expand All @@ -119,6 +120,7 @@ impl Cacheable for SurfaceAttributes {
opaque_region: self.opaque_region.clone(),
input_region: self.input_region.clone(),
frame_callbacks: std::mem::take(&mut self.frame_callbacks),
release_callback: self.release_callback.take(),
client_scale: self.client_scale,
}
}
Expand All @@ -137,6 +139,9 @@ impl Cacheable for SurfaceAttributes {
}
}
}
if let Some(release_callback) = &self.release_callback {
release_callback.done(0);
}
into.buffer_delta = self.buffer_delta;
into.buffer_scale = self.buffer_scale;
into.buffer_transform = self.buffer_transform;
Expand All @@ -145,6 +150,7 @@ impl Cacheable for SurfaceAttributes {
into.input_region = self.input_region;
into.frame_callbacks.extend(self.frame_callbacks);
into.client_scale = self.client_scale;
into.release_callback = self.release_callback;
}
}

Expand Down Expand Up @@ -334,6 +340,16 @@ where
);
});
}
wl_surface::Request::GetRelease { callback } => {
let callback = data_init.init(callback, ());
PrivateSurfaceData::with_states(surface, |states| {
states
.cached_state
.get::<SurfaceAttributes>()
.pending()
.release_callback = Some(callback);
});
}
wl_surface::Request::Destroy => {
// All is already handled by our destructor
}
Expand Down
6 changes: 5 additions & 1 deletion src/wayland/compositor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ pub struct SurfaceAttributes {
/// associated with this commit has been displayed on the screen.
pub frame_callbacks: Vec<wl_callback::WlCallback>,

/// Callback signalled when compositor no longer needs buffer for this surface.
pub release_callback: Option<wl_callback::WlCallback>,

pub(crate) client_scale: f64,
}

Expand All @@ -261,6 +264,7 @@ impl Default for SurfaceAttributes {
input_region: None,
damage: Vec::new(),
frame_callbacks: Vec::new(),
release_callback: None,
client_scale: 1.,
}
}
Expand Down Expand Up @@ -699,7 +703,7 @@ impl CompositorState {
where
D: GlobalDispatch<WlCompositor, ()> + GlobalDispatch<WlSubcompositor, ()> + 'static,
{
Self::new_with_version::<D>(display, 6)
Self::new_with_version::<D>(display, 7)
}

fn new_with_version<D>(display: &DisplayHandle, version: u32) -> Self
Expand Down
6 changes: 6 additions & 0 deletions src/wayland/compositor/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@ impl PrivateSurfaceData {
if let Some(BufferAssignment::NewBuffer(buffer)) = guard.pending().buffer.take() {
buffer.release();
};
if let Some(release_callback) = guard.current().release_callback.take() {
release_callback.done(0);
}
if let Some(release_callback) = guard.pending().release_callback.take() {
release_callback.done(0);
}

let hooks = my_data.destruction_hooks.clone();
// don't hold the mutex while the hooks are invoked
Expand Down
3 changes: 2 additions & 1 deletion src/wayland/selection/data_device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ impl DataDeviceState {
D: GlobalDispatch<WlDataDeviceManager, ()> + 'static,
D: DataDeviceHandler,
{
let manager_global = display.create_global::<D, WlDataDeviceManager, _>(3, ());
let manager_global = display.create_global::<D, WlDataDeviceManager, _>(4, ());

Self {
manager_global,
Expand Down Expand Up @@ -822,6 +822,7 @@ mod handlers {
}
}
}
wl_data_device_manager::Request::Release => {}
_ => unreachable!(),
}
}
Expand Down
Loading