anvil: fix shm buffer loading
This commit is contained in:
parent
664327660e
commit
a9ce9a4664
|
@ -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;
|
||||||
}
|
}
|
||||||
",
|
",
|
||||||
|
|
|
@ -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")]
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue