smithay/anvil/src/shm_load.rs

52 lines
1.9 KiB
Rust
Raw Normal View History

use std::borrow::Cow;
2018-10-02 21:37:24 +00:00
use smithay::{wayland::shm::BufferData, wayland_server::protocol::wl_shm::Format};
2018-05-13 12:35:27 +00:00
use glium::texture::{ClientFormat, RawImage2d};
2018-05-13 12:35:27 +00:00
2018-06-27 12:04:29 +00:00
pub fn load_shm_buffer(data: BufferData, pool: &[u8]) -> Result<(RawImage2d<u8>, usize), Format> {
2018-05-13 12:35:27 +00:00
let offset = data.offset as usize;
let width = data.width as usize;
let height = data.height as usize;
let stride = data.stride as usize;
// number of bytes per pixel
// TODO: compute from data.format
let pixelsize = 4;
// ensure consistency, the SHM handler of smithay should ensure this
assert!(offset + (height - 1) * stride + width * pixelsize <= pool.len());
let slice: Cow<[u8]> = if stride == width * pixelsize {
// the buffer is cleanly continuous, use as-is
Cow::Borrowed(&pool[offset..(offset + height * width * pixelsize)])
} else {
// the buffer is discontinuous or lines overlap
// we need to make a copy as unfortunately glium does not
// expose the OpenGL APIs we would need to load this buffer :/
let mut data = Vec::with_capacity(height * width * pixelsize);
for i in 0..height {
data.extend(&pool[(offset + i * stride)..(offset + i * stride + width * pixelsize)]);
2018-05-13 12:35:27 +00:00
}
Cow::Owned(data)
};
2018-05-13 12:35:27 +00:00
// sharders format need to be reversed to account for endianness
let (client_format, fragment) = match data.format {
Format::Argb8888 => (ClientFormat::U8U8U8U8, ::shaders::BUFFER_BGRA),
Format::Xrgb8888 => (ClientFormat::U8U8U8U8, ::shaders::BUFFER_BGRX),
Format::Rgba8888 => (ClientFormat::U8U8U8U8, ::shaders::BUFFER_ABGR),
Format::Rgbx8888 => (ClientFormat::U8U8U8U8, ::shaders::BUFFER_XBGR),
_ => return Err(data.format),
};
Ok((
RawImage2d {
data: slice,
width: width as u32,
height: height as u32,
format: client_format,
},
fragment,
))
2018-05-13 12:35:27 +00:00
}