From aa3ee245d1ddeed4a198c9cb4386c730404b1012 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 17 Nov 2022 12:25:41 +0100 Subject: [PATCH] screencopy: Fix format and copy code --- src/state.rs | 7 +++++- src/wayland/handlers/screencopy.rs | 36 ++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/state.rs b/src/state.rs index 075aec61..16a4e159 100644 --- a/src/state.rs +++ b/src/state.rs @@ -26,6 +26,7 @@ use smithay::{ calloop::{LoopHandle, LoopSignal}, wayland_server::{ backend::{ClientData, ClientId, DisconnectReason}, + protocol::wl_shm, Display, DisplayHandle, }, }, @@ -233,7 +234,11 @@ impl State { vec![CursorMode::Embedded, CursorMode::Hidden], |_| true, ); // TODO: privileged - let shm_state = ShmState::new::(dh, vec![], None); + let shm_state = ShmState::new::( + dh, + vec![wl_shm::Format::Xbgr8888, wl_shm::Format::Abgr8888], + None, + ); let seat_state = SeatState::::new(); let viewporter_state = ViewporterState::new::(dh, None); let wl_drm_state = WlDrmState; diff --git a/src/wayland/handlers/screencopy.rs b/src/wayland/handlers/screencopy.rs index a3180f84..540be69c 100644 --- a/src/wayland/handlers/screencopy.rs +++ b/src/wayland/handlers/screencopy.rs @@ -180,12 +180,12 @@ impl ScreencopyHandler for State { let mut formats = vec![ BufferInfo::Shm { - format: ShmFormat::Argb8888, + format: ShmFormat::Abgr8888, size, stride: size.w as u32 * 4, }, BufferInfo::Shm { - format: ShmFormat::Xrgb8888, + format: ShmFormat::Xbgr8888, size, stride: size.w as u32 * 4, }, @@ -279,7 +279,7 @@ impl ScreencopyHandler for State { if let Some(BufferType::Shm) = buffer_type(¶ms.buffer) { if with_buffer_contents(¶ms.buffer, |_, info| { - info.format != ShmFormat::Argb8888 && info.format != ShmFormat::Xrgb8888 + info.format != ShmFormat::Abgr8888 && info.format != ShmFormat::Xbgr8888 }) .unwrap() { @@ -418,12 +418,12 @@ fn formats_for_output( let mut formats = vec![ BufferInfo::Shm { - format: ShmFormat::Argb8888, + format: ShmFormat::Abgr8888, size: mode, stride: mode.w as u32 * 4, }, BufferInfo::Shm { - format: ShmFormat::Xrgb8888, + format: ShmFormat::Xbgr8888, size: mode, stride: mode.w as u32 * 4, }, @@ -500,11 +500,33 @@ where { if matches!(buffer_type(buffer), Some(BufferType::Shm)) { let buffer_size = buffer_dimensions(buffer).unwrap(); - with_buffer_contents_mut(buffer, |data, _info| { + with_buffer_contents_mut(buffer, |slice, data| { + let offset = data.offset as i32; + let width = data.width as i32; + let height = data.height as i32; + let stride = data.stride as i32; + + // number of bytes per pixel + // TODO: compute from data.format + let pixelsize = 4i32; + + // ensure consistency, the SHM handler of smithay should ensure this + assert!((offset + (height - 1) * stride + width * pixelsize) as usize <= slice.len()); + let mapping = renderer.copy_framebuffer(Rectangle::from_loc_and_size((0, 0), buffer_size))?; let gl_data = renderer.map_texture(&mapping)?; - data.copy_from_slice(gl_data); + assert!((width * height * pixelsize) as usize <= gl_data.len()); + + for i in 0..height { + unsafe { + std::ptr::copy_nonoverlapping::( + gl_data.as_ptr().offset((width * pixelsize * i) as isize), + slice.as_mut_ptr().offset((offset + stride * i) as isize), + (width * pixelsize) as usize, + ); + } + } Ok(()) }) .unwrap()?;