wayland_server: make frame callbacks, release buffers. logging
This commit is contained in:
@@ -4,7 +4,7 @@ use smithay::input::{Seat, SeatHandler, SeatState};
|
||||
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
|
||||
use smithay::reexports::wayland_server;
|
||||
use smithay::reexports::wayland_server::Resource;
|
||||
use smithay::reexports::wayland_server::protocol::{wl_buffer, wl_output, wl_seat, wl_surface};
|
||||
use smithay::reexports::wayland_server::protocol::{wl_buffer, wl_output, wl_seat};
|
||||
use smithay::wayland::buffer::BufferHandler;
|
||||
use smithay::wayland::dmabuf::{
|
||||
DmabufFeedback, DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier, get_dmabuf,
|
||||
@@ -21,9 +21,7 @@ use std::os::fd::OwnedFd;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use smithay::utils::Serial;
|
||||
use smithay::wayland::compositor::{
|
||||
self, BufferAssignment, SurfaceAttributes, TraversalAction, with_surface_tree_downward,
|
||||
};
|
||||
use smithay::wayland::compositor::{self, BufferAssignment, SurfaceAttributes};
|
||||
|
||||
use smithay::wayland::selection::SelectionHandler;
|
||||
use smithay::wayland::selection::data_device::{
|
||||
@@ -36,8 +34,8 @@ use wayland_server::Client;
|
||||
use wayland_server::backend::{ClientData, ClientId, DisconnectReason};
|
||||
use wayland_server::protocol::wl_surface::WlSurface;
|
||||
|
||||
use crate::backend::wayvr::SurfaceBufWithImage;
|
||||
use crate::backend::wayvr::image_importer::ImageImporter;
|
||||
use crate::backend::wayvr::{SurfaceBufWithImage, time};
|
||||
use crate::ipc::event_queue::SyncEventQueue;
|
||||
|
||||
use super::WayVRTask;
|
||||
@@ -83,66 +81,81 @@ impl compositor::CompositorHandler for Application {
|
||||
|
||||
match attrs.buffer.take() {
|
||||
Some(BufferAssignment::NewBuffer(buffer)) => {
|
||||
let current = SurfaceBufWithImage::get_from_surface(states);
|
||||
|
||||
if current.is_none_or(|c| c.buffer != buffer) {
|
||||
match buffer_type(&buffer) {
|
||||
Some(BufferType::Dma) => {
|
||||
let dmabuf = get_dmabuf(&buffer).unwrap(); // always Ok due to buffer_type
|
||||
if let Ok(image) =
|
||||
self.image_importer.get_or_import_dmabuf(dmabuf.clone())
|
||||
match buffer_type(&buffer) {
|
||||
Some(BufferType::Dma) => {
|
||||
let dmabuf = get_dmabuf(&buffer).unwrap(); // always Ok due to buffer_type
|
||||
if let Ok(image) = self
|
||||
.image_importer
|
||||
.get_or_import_dmabuf(dmabuf.clone())
|
||||
.inspect_err(|e| {
|
||||
log::warn!("wayland_server failed to import DMA-buf: {e:?}")
|
||||
})
|
||||
{
|
||||
let sbwi = SurfaceBufWithImage {
|
||||
image,
|
||||
transform: wl_transform_to_frame_transform(
|
||||
attrs.buffer_transform,
|
||||
),
|
||||
scale: attrs.buffer_scale,
|
||||
dmabuf: true,
|
||||
};
|
||||
sbwi.apply_to_surface(states);
|
||||
}
|
||||
}
|
||||
Some(BufferType::Shm) => {
|
||||
let _ = with_buffer_contents(&buffer, |data, size, buf| {
|
||||
if let Ok(image) = self
|
||||
.image_importer
|
||||
.import_shm(data, size, buf)
|
||||
.inspect_err(|e| {
|
||||
log::warn!("wayland_server failed to import SHM: {e:?}")
|
||||
})
|
||||
{
|
||||
let sbwi = SurfaceBufWithImage {
|
||||
image,
|
||||
buffer,
|
||||
transform: wl_transform_to_frame_transform(
|
||||
attrs.buffer_transform,
|
||||
),
|
||||
scale: attrs.buffer_scale,
|
||||
dmabuf: false,
|
||||
};
|
||||
sbwi.apply_to_surface(states);
|
||||
}
|
||||
}
|
||||
Some(BufferType::Shm) => {
|
||||
let _ = with_buffer_contents(&buffer, |data, size, buf| {
|
||||
if let Ok(image) =
|
||||
self.image_importer.import_shm(data, size, buf)
|
||||
{
|
||||
let sbwi = SurfaceBufWithImage {
|
||||
image,
|
||||
buffer: buffer.clone(),
|
||||
transform: wl_transform_to_frame_transform(
|
||||
attrs.buffer_transform,
|
||||
),
|
||||
scale: attrs.buffer_scale,
|
||||
};
|
||||
sbwi.apply_to_surface(states);
|
||||
}
|
||||
});
|
||||
}
|
||||
Some(BufferType::SinglePixel) => {
|
||||
let spb = get_single_pixel_buffer(&buffer).unwrap(); // always Ok
|
||||
if let Ok(image) = self.image_importer.import_spb(spb) {
|
||||
let sbwi = SurfaceBufWithImage {
|
||||
image,
|
||||
buffer,
|
||||
transform: wl_transform_to_frame_transform(
|
||||
// does this even matter
|
||||
attrs.buffer_transform,
|
||||
),
|
||||
scale: attrs.buffer_scale,
|
||||
};
|
||||
sbwi.apply_to_surface(states);
|
||||
}
|
||||
}
|
||||
Some(other) => log::warn!("Unsupported wl_buffer format: {other:?}"),
|
||||
None => { /* don't draw anything */ }
|
||||
});
|
||||
}
|
||||
Some(BufferType::SinglePixel) => {
|
||||
let spb = get_single_pixel_buffer(&buffer).unwrap(); // always Ok
|
||||
if let Ok(image) =
|
||||
self.image_importer.import_spb(spb).inspect_err(|e| {
|
||||
log::warn!("wayland_server failed to import SPB: {e:?}")
|
||||
})
|
||||
{
|
||||
let sbwi = SurfaceBufWithImage {
|
||||
image,
|
||||
transform: wl_transform_to_frame_transform(
|
||||
// does this even matter
|
||||
attrs.buffer_transform,
|
||||
),
|
||||
scale: attrs.buffer_scale,
|
||||
dmabuf: false,
|
||||
};
|
||||
sbwi.apply_to_surface(states);
|
||||
}
|
||||
}
|
||||
Some(other) => log::warn!("Unsupported wl_buffer format: {other:?}"),
|
||||
None => { /* don't draw anything */ }
|
||||
}
|
||||
buffer.release();
|
||||
}
|
||||
Some(BufferAssignment::Removed) => {}
|
||||
None => {}
|
||||
}
|
||||
|
||||
let t = time::get_millis() as u32;
|
||||
let callbacks = std::mem::take(&mut attrs.frame_callbacks);
|
||||
for cb in callbacks {
|
||||
cb.done(t);
|
||||
}
|
||||
});
|
||||
|
||||
self.redraw_requests.insert(surface.id());
|
||||
@@ -286,28 +299,6 @@ delegate_seat!(Application);
|
||||
delegate_data_device!(Application);
|
||||
delegate_output!(Application);
|
||||
|
||||
pub fn send_frames_surface_tree(surface: &wl_surface::WlSurface, time: u32) {
|
||||
with_surface_tree_downward(
|
||||
surface,
|
||||
(),
|
||||
|_, _, &()| TraversalAction::DoChildren(()),
|
||||
|_surf, states, &()| {
|
||||
// the surface may not have any user_data if it is a subsurface and has not
|
||||
// yet been committed
|
||||
for callback in states
|
||||
.cached_state
|
||||
.get::<SurfaceAttributes>()
|
||||
.current()
|
||||
.frame_callbacks
|
||||
.drain(..)
|
||||
{
|
||||
callback.done(time);
|
||||
}
|
||||
},
|
||||
|_, _, &()| true,
|
||||
);
|
||||
}
|
||||
|
||||
fn wl_transform_to_frame_transform(
|
||||
transform: wl_output::Transform,
|
||||
) -> wlx_capture::frame::Transform {
|
||||
|
||||
@@ -14,7 +14,7 @@ use smallvec::SmallVec;
|
||||
use smithay::{
|
||||
input::{SeatState, keyboard::XkbConfig},
|
||||
output::{Mode, Output},
|
||||
reexports::wayland_server::{self, backend::ClientId, protocol::wl_buffer},
|
||||
reexports::wayland_server::{self, backend::ClientId},
|
||||
wayland::{
|
||||
compositor::{self, SurfaceData, with_states},
|
||||
dmabuf::{DmabufFeedbackBuilder, DmabufState},
|
||||
@@ -26,8 +26,6 @@ use smithay::{
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
collections::{HashMap, HashSet},
|
||||
mem::MaybeUninit,
|
||||
rc::Rc,
|
||||
sync::Arc,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
@@ -112,7 +110,7 @@ pub struct Config {
|
||||
pub struct WayVRState {
|
||||
time_start: u64,
|
||||
pub manager: client::WayVRCompositor,
|
||||
pub wm: Rc<RefCell<window::WindowManager>>,
|
||||
pub wm: window::WindowManager,
|
||||
pub processes: process::ProcessVec,
|
||||
pub config: Config,
|
||||
pub tasks: SyncEventQueue<WayVRTask>,
|
||||
@@ -241,7 +239,7 @@ impl WayVR {
|
||||
time_start,
|
||||
manager: client::WayVRCompositor::new(state, display, seat_keyboard, seat_pointer)?,
|
||||
processes: ProcessVec::new(),
|
||||
wm: Rc::new(RefCell::new(window::WindowManager::new())),
|
||||
wm: window::WindowManager::new(),
|
||||
config,
|
||||
ticks: 0,
|
||||
tasks,
|
||||
@@ -307,11 +305,7 @@ impl WayVR {
|
||||
continue;
|
||||
};
|
||||
|
||||
let window_handle = self
|
||||
.state
|
||||
.wm
|
||||
.borrow_mut()
|
||||
.create_window(&toplevel, process_handle);
|
||||
let window_handle = self.state.wm.create_window(&toplevel, process_handle);
|
||||
|
||||
let title: Arc<str> = with_states(toplevel.wl_surface(), |states| {
|
||||
states
|
||||
@@ -353,8 +347,8 @@ impl WayVR {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut wm = self.state.wm.borrow_mut();
|
||||
let Some(window_handle) = wm.find_window_handle(&toplevel) else {
|
||||
let Some(window_handle) = self.state.wm.find_window_handle(&toplevel)
|
||||
else {
|
||||
log::warn!("DropToplevel: Couldn't find matching window handle");
|
||||
continue;
|
||||
};
|
||||
@@ -365,9 +359,7 @@ impl WayVR {
|
||||
)));
|
||||
}
|
||||
|
||||
wm.remove_window(window_handle);
|
||||
|
||||
drop(wm);
|
||||
self.state.wm.remove_window(window_handle);
|
||||
}
|
||||
}
|
||||
WayVRTask::ProcessTerminationRequest(process_handle) => {
|
||||
@@ -404,7 +396,7 @@ impl WayVRState {
|
||||
if self.mouse_freeze > Instant::now() {
|
||||
return;
|
||||
}
|
||||
if let Some(window) = self.wm.borrow_mut().windows.get_mut(&handle) {
|
||||
if let Some(window) = self.wm.windows.get_mut(&handle) {
|
||||
window.send_mouse_move(&mut self.manager, x, y);
|
||||
}
|
||||
}
|
||||
@@ -413,7 +405,7 @@ impl WayVRState {
|
||||
self.mouse_freeze =
|
||||
Instant::now() + Duration::from_millis(self.config.click_freeze_time_ms as _);
|
||||
|
||||
if let Some(window) = self.wm.borrow_mut().windows.get_mut(&handle) {
|
||||
if let Some(window) = self.wm.windows.get_mut(&handle) {
|
||||
window.send_mouse_down(&mut self.manager, index);
|
||||
}
|
||||
}
|
||||
@@ -563,10 +555,10 @@ struct SurfaceBufWithImageContainer {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SurfaceBufWithImage {
|
||||
buffer: wl_buffer::WlBuffer,
|
||||
pub image: Arc<ImageView>,
|
||||
pub transform: Transform,
|
||||
pub scale: i32,
|
||||
pub dmabuf: bool,
|
||||
}
|
||||
|
||||
impl SurfaceBufWithImage {
|
||||
@@ -575,7 +567,11 @@ impl SurfaceBufWithImage {
|
||||
if let Some(container) = surface_data.data_map.get::<SurfaceBufWithImageContainer>() {
|
||||
container.inner.replace(self);
|
||||
} else {
|
||||
surface_data.data_map.insert_if_missing(|| self);
|
||||
surface_data
|
||||
.data_map
|
||||
.insert_if_missing(|| SurfaceBufWithImageContainer {
|
||||
inner: RefCell::new(self),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -199,7 +199,6 @@ impl Connection {
|
||||
list: params
|
||||
.wayland_state
|
||||
.wm
|
||||
.borrow_mut()
|
||||
.windows
|
||||
.iter()
|
||||
.map(|(handle, win)| packet_server::WvrWindow {
|
||||
@@ -222,7 +221,6 @@ impl Connection {
|
||||
if let Some(window) = params
|
||||
.wayland_state
|
||||
.wm
|
||||
.borrow_mut()
|
||||
.windows
|
||||
.get_mut(&wayvr::window::WindowHandle::from_packet(handle))
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::{
|
||||
backend::{
|
||||
XrBackend,
|
||||
input::{self, HoverResult},
|
||||
wayvr::{self, SurfaceBufWithImage, WayVR, window::WindowManager},
|
||||
wayvr::{self, SurfaceBufWithImage, WayVR},
|
||||
},
|
||||
graphics::{ExtentExt, WGfxExtras},
|
||||
ipc::{event_queue::SyncEventQueue, signal::WayVRSignal},
|
||||
@@ -84,7 +84,6 @@ pub struct WayVRBackend {
|
||||
interaction_transform: Option<Affine2>,
|
||||
window: wayvr::window::WindowHandle,
|
||||
wayvr: Rc<RefCell<WayVRData>>,
|
||||
wm: Rc<RefCell<WindowManager>>,
|
||||
just_resumed: bool,
|
||||
meta: Option<FrameMeta>,
|
||||
stereo: Option<StereoMode>,
|
||||
@@ -98,12 +97,10 @@ impl WayVRBackend {
|
||||
wayvr: Rc<RefCell<WayVRData>>,
|
||||
window: wayvr::window::WindowHandle,
|
||||
) -> anyhow::Result<Self> {
|
||||
let wm = wayvr.borrow().data.state.wm.clone();
|
||||
Ok(Self {
|
||||
name,
|
||||
pipeline: None,
|
||||
wayvr,
|
||||
wm,
|
||||
window,
|
||||
mouse_transform: Affine2::IDENTITY,
|
||||
interaction_transform: None,
|
||||
@@ -134,8 +131,8 @@ impl OverlayBackend for WayVRBackend {
|
||||
}
|
||||
|
||||
fn should_render(&mut self, app: &mut AppState) -> anyhow::Result<ShouldRender> {
|
||||
let wm = self.wm.borrow();
|
||||
let Some(window) = wm.windows.get(&self.window) else {
|
||||
let wayvr = &self.wayvr.borrow().data;
|
||||
let Some(window) = wayvr.state.wm.windows.get(&self.window) else {
|
||||
log::debug!(
|
||||
"{:?}: WayVR overlay without matching window entry",
|
||||
self.name
|
||||
@@ -175,12 +172,19 @@ impl OverlayBackend for WayVRBackend {
|
||||
.as_ref()
|
||||
.is_none_or(|i| *i.image() != *surf.image.image())
|
||||
{
|
||||
log::trace!(
|
||||
"{}: new {} image",
|
||||
self.name,
|
||||
surf.dmabuf.then_some("DMA-buf").unwrap_or("SHM")
|
||||
);
|
||||
self.cur_image = Some(surf.image);
|
||||
Ok(ShouldRender::Should)
|
||||
} else {
|
||||
log::trace!("{}: no new image", self.name);
|
||||
Ok(ShouldRender::Can)
|
||||
}
|
||||
} else {
|
||||
log::trace!("{}: no buffer for wl_surface", self.name);
|
||||
Ok(ShouldRender::Unable)
|
||||
}
|
||||
})
|
||||
@@ -215,12 +219,13 @@ impl OverlayBackend for WayVRBackend {
|
||||
}
|
||||
|
||||
fn on_hover(&mut self, _app: &mut state::AppState, hit: &input::PointerHit) -> HoverResult {
|
||||
if let Some(window) = self.wm.borrow().windows.get(&self.window) {
|
||||
let wayvr = &mut self.wayvr.borrow_mut().data;
|
||||
if let Some((x, y)) = wayvr.state.wm.windows.get(&self.window).map(|window| {
|
||||
let pos = self.mouse_transform.transform_point2(hit.uv);
|
||||
let x = ((pos.x * (window.size_x as f32)) as u32).max(0);
|
||||
let y = ((pos.y * (window.size_y as f32)) as u32).max(0);
|
||||
|
||||
let wayvr = &mut self.wayvr.borrow_mut().data;
|
||||
(x, y)
|
||||
}) {
|
||||
wayvr.state.send_mouse_move(self.window, x, y);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user