kms/surface: Define a PendingImageCopyData, instead of using tuple

Adding anything else to this tuple is awkward; defining a simple struct
makes this cleaner.

This also adds a `sync` property, which will come in handy later.
Containing simply the same-named argument that was passed to
`submit_buffer`.
This commit is contained in:
Ian Douglas Scott 2025-08-19 12:45:07 -07:00 committed by Victoria Brekenfeld
parent f0e0084608
commit 28e9024681
4 changed files with 34 additions and 24 deletions

View file

@ -8,7 +8,7 @@ use crate::{
config::{AdaptiveSync, EdidProduct, OutputConfig, OutputState, ScreenFilter}, config::{AdaptiveSync, EdidProduct, OutputConfig, OutputState, ScreenFilter},
shell::Shell, shell::Shell,
utils::{env::dev_list_var, prelude::*}, utils::{env::dev_list_var, prelude::*},
wayland::protocols::screencopy::Frame, wayland::handlers::screencopy::PendingImageCopyData,
}; };
use anyhow::{Context, Result}; use anyhow::{Context, Result};
@ -39,9 +39,7 @@ use smithay::{
rustix::fs::OFlags, rustix::fs::OFlags,
wayland_server::{protocol::wl_buffer::WlBuffer, DisplayHandle, Weak}, wayland_server::{protocol::wl_buffer::WlBuffer, DisplayHandle, Weak},
}, },
utils::{ utils::{Clock, DevPath, DeviceFd, Monotonic, Point, Transform},
Buffer as BufferCoords, Clock, DevPath, DeviceFd, Monotonic, Point, Rectangle, Transform,
},
wayland::drm_lease::{DrmLease, DrmLeaseState}, wayland::drm_lease::{DrmLease, DrmLeaseState},
}; };
use tracing::{error, info, warn}; use tracing::{error, info, warn};
@ -71,7 +69,7 @@ pub type LockedGbmDrmOutputManager<'a> = LockedDrmOutputManager<
GbmFramebufferExporter<DrmDeviceFd>, GbmFramebufferExporter<DrmDeviceFd>,
Option<( Option<(
OutputPresentationFeedback, OutputPresentationFeedback,
Receiver<(Frame, Vec<Rectangle<i32, BufferCoords>>)>, Receiver<PendingImageCopyData>,
Duration, Duration,
)>, )>,
DrmDeviceFd, DrmDeviceFd,
@ -82,7 +80,7 @@ pub type GbmDrmOutputManager = DrmOutputManager<
GbmFramebufferExporter<DrmDeviceFd>, GbmFramebufferExporter<DrmDeviceFd>,
Option<( Option<(
OutputPresentationFeedback, OutputPresentationFeedback,
Receiver<(Frame, Vec<Rectangle<i32, BufferCoords>>)>, Receiver<PendingImageCopyData>,
Duration, Duration,
)>, )>,
DrmDeviceFd, DrmDeviceFd,

View file

@ -13,7 +13,7 @@ use crate::{
wayland::{ wayland::{
handlers::{ handlers::{
compositor::recursive_frame_time_estimation, compositor::recursive_frame_time_estimation,
screencopy::{submit_buffer, FrameHolder, SessionData}, screencopy::{submit_buffer, FrameHolder, PendingImageCopyData, SessionData},
}, },
protocols::screencopy::{ protocols::screencopy::{
FailureReason, Frame as ScreencopyFrame, SessionRef as ScreencopySessionRef, FailureReason, Frame as ScreencopyFrame, SessionRef as ScreencopySessionRef,
@ -78,7 +78,7 @@ use smithay::{
}, },
wayland_server::protocol::wl_surface::WlSurface, wayland_server::protocol::wl_surface::WlSurface,
}, },
utils::{Buffer as BufferCoords, Clock, Monotonic, Physical, Point, Rectangle, Transform}, utils::{Clock, Monotonic, Physical, Point, Rectangle, Transform},
wayland::{ wayland::{
dmabuf::{get_dmabuf, DmabufFeedbackBuilder}, dmabuf::{get_dmabuf, DmabufFeedbackBuilder},
presentation::Refresh, presentation::Refresh,
@ -172,7 +172,7 @@ pub type GbmDrmOutput = DrmOutput<
GbmFramebufferExporter<DrmDeviceFd>, GbmFramebufferExporter<DrmDeviceFd>,
Option<( Option<(
OutputPresentationFeedback, OutputPresentationFeedback,
Receiver<(ScreencopyFrame, Vec<Rectangle<i32, BufferCoords>>)>, Receiver<PendingImageCopyData>,
Duration, Duration,
)>, )>,
DrmDeviceFd, DrmDeviceFd,
@ -819,7 +819,7 @@ impl SurfaceThreadState {
self.timings.presented(clock); self.timings.presented(clock);
while let Ok((frame, damage)) = frames.recv() { while let Ok(PendingImageCopyData { frame, damage, .. }) = frames.recv() {
frame.success(self.output.current_transform(), damage, clock); frame.success(self.output.current_transform(), damage, clock);
} }
} }
@ -1635,7 +1635,7 @@ fn send_screencopy_result<'a>(
renderer: &mut GlMultiRenderer<'a>, renderer: &mut GlMultiRenderer<'a>,
output: &Output, output: &Output,
pre_postprocess_data: &mut PrePostprocessData, pre_postprocess_data: &mut PrePostprocessData,
tx: &std::sync::mpsc::Sender<(ScreencopyFrame, Vec<Rectangle<i32, BufferCoords>>)>, tx: &std::sync::mpsc::Sender<PendingImageCopyData>,
frame_result: &RenderFrameResult<GbmBuffer, GbmFramebuffer, CosmicElement<GlMultiRenderer<'a>>>, frame_result: &RenderFrameResult<GbmBuffer, GbmFramebuffer, CosmicElement<GlMultiRenderer<'a>>>,
elements: &[CosmicElement<GlMultiRenderer>], elements: &[CosmicElement<GlMultiRenderer>],
(session, frame, res): ( (session, frame, res): (
@ -1807,7 +1807,7 @@ fn send_screencopy_result<'a>(
let transform = output.current_transform(); let transform = output.current_transform();
if let Some((frame, damage)) = submit_buffer( if let Some(data) = submit_buffer(
frame, frame,
renderer, renderer,
shm_buffer.then_some(fb.as_mut().unwrap()), shm_buffer.then_some(fb.as_mut().unwrap()),
@ -1816,9 +1816,10 @@ fn send_screencopy_result<'a>(
sync, sync,
)? { )? {
if frame_result.is_empty { if frame_result.is_empty {
frame.success(transform, damage, presentation_time); data.frame
.success(transform, data.damage, presentation_time);
} else { } else {
let _ = tx.send((frame, damage)); let _ = tx.send(data);
} }
} }

View file

@ -28,7 +28,7 @@ use crate::{
handlers::{ handlers::{
compositor::FRAME_TIME_FILTER, compositor::FRAME_TIME_FILTER,
data_device::get_dnd_icon, data_device::get_dnd_icon,
screencopy::{render_session, FrameHolder, SessionData}, screencopy::{render_session, FrameHolder, PendingImageCopyData, SessionData},
}, },
protocols::workspace::WorkspaceHandle, protocols::workspace::WorkspaceHandle,
}, },
@ -1332,7 +1332,11 @@ where
match result { match result {
Ok((res, mut elements)) => { Ok((res, mut elements)) => {
for (session, frame) in output.take_pending_frames() { for (session, frame) in output.take_pending_frames() {
if let Some((frame, damage)) = render_session::<_, _, GlesTexture>( if let Some(PendingImageCopyData { frame, damage, .. }) = render_session::<
_,
_,
GlesTexture,
>(
renderer, renderer,
&session.user_data().get::<SessionData>().unwrap(), &session.user_data().get::<SessionData>().unwrap(),
frame, frame,

View file

@ -54,6 +54,12 @@ use crate::{
use super::{super::data_device::get_dnd_icon, user_data::SessionHolder}; use super::{super::data_device::get_dnd_icon, user_data::SessionHolder};
pub struct PendingImageCopyData {
pub frame: Frame,
pub damage: Vec<smithay::utils::Rectangle<i32, BufferCoords>>,
pub sync: SyncPoint,
}
pub fn submit_buffer<R>( pub fn submit_buffer<R>(
frame: Frame, frame: Frame,
renderer: &mut R, renderer: &mut R,
@ -61,7 +67,7 @@ pub fn submit_buffer<R>(
transform: Transform, transform: Transform,
damage: Option<&[Rectangle<i32, Physical>]>, damage: Option<&[Rectangle<i32, Physical>]>,
sync: SyncPoint, sync: SyncPoint,
) -> Result<Option<(Frame, Vec<Rectangle<i32, BufferCoords>>)>, R::Error> ) -> Result<Option<PendingImageCopyData>, R::Error>
where where
R: ExportMem, R: ExportMem,
R::Error: FromGlesError, R::Error: FromGlesError,
@ -124,16 +130,17 @@ where
} }
} }
Ok(Some(( Ok(Some(PendingImageCopyData {
frame, frame,
damage damage: damage
.into_iter() .into_iter()
.map(|rect| { .map(|rect| {
let logical = rect.to_logical(1); let logical = rect.to_logical(1);
logical.to_buffer(1, transform, &logical.size) logical.to_buffer(1, transform, &logical.size)
}) })
.collect(), .collect(),
))) sync,
}))
} }
pub fn render_session<F, R, T>( pub fn render_session<F, R, T>(
@ -142,7 +149,7 @@ pub fn render_session<F, R, T>(
frame: Frame, frame: Frame,
transform: Transform, transform: Transform,
render_fn: F, render_fn: F,
) -> Result<Option<(Frame, Vec<Rectangle<i32, BufferCoords>>)>, DTError<R::Error>> ) -> Result<Option<PendingImageCopyData>, DTError<R::Error>>
where where
R: ExportMem + Offscreen<T>, R: ExportMem + Offscreen<T>,
R::Error: FromGlesError, R::Error: FromGlesError,
@ -430,7 +437,7 @@ pub fn render_workspace_to_buffer(
} }
}; };
if let Some((frame, damage)) = result { if let Some(PendingImageCopyData { frame, damage, .. }) = result {
frame.success(transform, damage, common.clock.now()) frame.success(transform, damage, common.clock.now())
} }
} }
@ -661,7 +668,7 @@ pub fn render_window_to_buffer(
}, },
}; };
if let Some((frame, damage)) = result { if let Some(PendingImageCopyData { frame, damage, .. }) = result {
frame.success(Transform::Normal, damage, common.clock.now()) frame.success(Transform::Normal, damage, common.clock.now())
} }
} }
@ -817,7 +824,7 @@ pub fn render_cursor_to_buffer(
} }
}; };
if let Some((frame, damage)) = result { if let Some(PendingImageCopyData { frame, damage, .. }) = result {
frame.success(Transform::Normal, damage, common.clock.now()) frame.success(Transform::Normal, damage, common.clock.now())
} }
} }