anvil: fix shm buffer loading

This commit is contained in:
Victor Berger 2018-05-13 14:35:27 +02:00
parent 664327660e
commit a9ce9a4664
4 changed files with 89 additions and 37 deletions

View File

@ -89,9 +89,9 @@ impl<T: Into<GliumGraphicsBackend<T>> + EGLGraphicsBackend + 'static> From<T> fo
varying lowp vec2 v_tex_coords; varying lowp vec2 v_tex_coords;
void main() { void main() {
lowp vec4 color = texture2D(tex, v_tex_coords); lowp vec4 color = texture2D(tex, v_tex_coords);
gl_FragColor.r = color.z; gl_FragColor.r = color.x;
gl_FragColor.g = color.y; gl_FragColor.g = color.y;
gl_FragColor.b = color.x; gl_FragColor.b = color.z;
gl_FragColor.a = color.w; gl_FragColor.a = color.w;
} }
", ",

View File

@ -13,15 +13,16 @@ use slog::Drain;
use smithay::wayland_server::Display; use smithay::wayland_server::Display;
mod glium_drawer; mod glium_drawer;
mod input_handler;
#[cfg(feature = "tty_launch")]
mod raw_drm;
mod shell; mod shell;
mod shm_load;
#[cfg(feature = "udev")] #[cfg(feature = "udev")]
mod udev; mod udev;
mod window_map; mod window_map;
#[cfg(feature = "winit")] #[cfg(feature = "winit")]
mod winit; mod winit;
mod input_handler;
#[cfg(feature = "tty_launch")]
mod raw_drm;
static POSSIBLE_BACKENDS: &'static [&'static str] = &[ static POSSIBLE_BACKENDS: &'static [&'static str] = &[
#[cfg(feature = "winit")] #[cfg(feature = "winit")]

View File

@ -39,11 +39,12 @@ pub fn init_shell(
) { ) {
// Create the compositor // Create the compositor
let c_egl_display = egl_display.clone(); let c_egl_display = egl_display.clone();
let log2 = log.clone();
let (compositor_token, _, _) = compositor_init( let (compositor_token, _, _) = compositor_init(
display, display,
looptoken.clone(), looptoken.clone(),
move |request, (surface, ctoken)| match request { move |request, (surface, ctoken)| match request {
SurfaceEvent::Commit => surface_commit(&surface, ctoken, &*c_egl_display), SurfaceEvent::Commit => surface_commit(&surface, ctoken, &*c_egl_display, &log2),
SurfaceEvent::Frame { callback } => callback SurfaceEvent::Frame { callback } => callback
.implement(|e, _| match e {}, None::<fn(_, _)>) .implement(|e, _| match e {}, None::<fn(_, _)>)
.send(wl_callback::Event::Done { callback_data: 0 }), .send(wl_callback::Event::Done { callback_data: 0 }),
@ -140,6 +141,7 @@ fn surface_commit(
surface: &Resource<wl_surface::WlSurface>, surface: &Resource<wl_surface::WlSurface>,
token: CompositorToken<SurfaceData, Roles>, token: CompositorToken<SurfaceData, Roles>,
display: &RefCell<Option<EGLDisplay>>, display: &RefCell<Option<EGLDisplay>>,
log: &::slog::Logger,
) { ) {
// we retrieve the contents of the associated buffer and copy it // we retrieve the contents of the associated buffer and copy it
token.with_surface_data(surface, |attributes| { token.with_surface_data(surface, |attributes| {
@ -167,17 +169,8 @@ fn surface_commit(
} }
Err(BufferAccessError::NotManaged(buffer)) => { Err(BufferAccessError::NotManaged(buffer)) => {
shm_buffer_contents(&buffer, |slice, data| { shm_buffer_contents(&buffer, |slice, data| {
let offset = data.offset as usize;
let stride = data.stride as usize;
let width = data.width as usize;
let height = data.height as usize;
let mut new_vec = Vec::with_capacity(width * height * 4);
for i in 0..height {
new_vec
.extend(&slice[(offset + i * stride)..(offset + i * stride + width * 4)]);
}
attributes.user_data.texture = None; attributes.user_data.texture = None;
attributes.user_data.buffer = Some(Buffer::Shm { data: new_vec, size: (data.width as u32, data.height as u32) }); attributes.user_data.buffer = Some(::shm_load::load_shm_buffer(data, slice, log));
}).expect("Got EGL buffer with no set EGLDisplay. You need to unbind your EGLContexts before dropping them!"); }).expect("Got EGL buffer with no set EGLDisplay. You need to unbind your EGLContexts before dropping them!");
buffer.send(wl_buffer::Event::Release); buffer.send(wl_buffer::Event::Release);
} }

58
anvil/src/shm_load.rs Normal file
View File

@ -0,0 +1,58 @@
use shell::Buffer;
use smithay::wayland::shm::BufferData;
use smithay::wayland_server::protocol::wl_shm::Format;
pub fn load_shm_buffer(data: BufferData, pool: &[u8], log: &::slog::Logger) -> Buffer {
// ensure consistency, the SHM handler of smithay should ensure this
debug_assert!(((data.offset + data.stride * data.height) as usize) <= pool.len());
let mut out = Vec::with_capacity((data.width * data.height * 4) as usize);
let offset = data.offset as usize;
let width = data.width as usize;
let height = data.height as usize;
let stride = data.stride as usize;
match data.format {
Format::Argb8888 => {
// TODO: this is so slooooow
for j in 0..height {
for i in 0..width {
// value must be read as native endianness
let val: u32 =
unsafe { *(&pool[offset + j * stride + i * 4] as *const u8 as *const u32) };
out.push(((val & 0x00FF0000) >> 16) as u8); //r
out.push(((val & 0x0000FF00) >> 8) as u8); //g
out.push(((val & 0x000000FF) >> 0) as u8); //b
out.push(((val & 0xFF000000) >> 24) as u8); //a
}
}
}
Format::Xrgb8888 => {
// TODO: this is so slooooow
for j in 0..height {
for i in 0..width {
// value must be read as native endianness
let val: u32 =
unsafe { *(&pool[offset + j * stride + i * 4] as *const u8 as *const u32) };
out.push(((val & 0x00FF0000) >> 16) as u8); //r
out.push(((val & 0x0000FF00) >> 8) as u8); //g
out.push(((val & 0x000000FF) >> 0) as u8); //b
out.push(255); // a
}
}
}
_ => {
error!(log, "Unsupported buffer format"; "format" => format!("{:?}", data.format));
// fill in with black
for _ in 0..(data.height * data.width) {
out.extend(&[0, 0, 0, 255])
}
}
}
Buffer::Shm {
data: out,
size: (data.width as u32, data.height as u32),
}
}