diff --git a/Cargo.toml b/Cargo.toml index 51fe2cd..48f7d33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,17 +12,20 @@ exclude = [".travis.yml", ".rustfmt.toml"] [dependencies] gbm-sys = { version = "0.1", path = "./gbm-sys" } -libc = "0.2" -bitflags = "1.0.0" -wayland-server = { version = "0.12", optional = true } -drm = { version = "0.3", optional = true } +libc = "0.2.66" +bitflags = "1.2.1" +wayland-client = { version = "0.23", optional = true } +drm = { version = "0.3.4", optional = true } +glutin_interface = { version = "0.1.0", path = "../glutin_interface", optional = true } +winit_types = { version = "0.1.0", path = "../winit_types", optional = true } [dev-dependencies] -drm = "0.3.0" +drm = "0.3.4" [features] -default = ["import-wayland", "import-egl", "drm-support"] -import-wayland = ["wayland-server"] +default = ["import-wayland", "import-egl", "drm-support", "glutin-support"] +glutin-support = ["glutin_interface", "winit_types"] +import-wayland = ["wayland-client"] import-egl = [] drm-support = ["drm"] gen = ["gbm-sys/gen"] diff --git a/gbm-sys/build.rs b/gbm-sys/build.rs index fc48594..39de612 100644 --- a/gbm-sys/build.rs +++ b/gbm-sys/build.rs @@ -10,8 +10,7 @@ use std::path::Path; fn main() {} #[cfg(feature = "gen")] -fn main() -{ +fn main() { // Setup bindings builder let generated = bindgen::builder() .header("include/gbm.h") diff --git a/gbm-sys/src/lib.rs b/gbm-sys/src/lib.rs index 8d44d77..a3a69aa 100644 --- a/gbm-sys/src/lib.rs +++ b/gbm-sys/src/lib.rs @@ -3,95 +3,93 @@ extern crate libc; macro_rules! __gbm_fourcc_code { - ($a:expr, $b:expr, $c:expr, $d:expr) => ( + ($a:expr, $b:expr, $c:expr, $d:expr) => { ($a as u32) | (($b as u32) << 8) | (($c as u32) << 16) | (($d as u32) << 24) - ) + }; } -/* color index */ -pub const GBM_FORMAT_C8 :u32 = __gbm_fourcc_code!('C', '8', ' ', ' '); /* [7:0] C */ +// color index +pub const GBM_FORMAT_C8: u32 = __gbm_fourcc_code!('C', '8', ' ', ' '); // [7:0] C -/* 8 bpp Red */ -pub const GBM_FORMAT_R8 :u32 = __gbm_fourcc_code!('R', '8', ' ', ' '); /* [7:0] R */ +// 8 bpp Red +pub const GBM_FORMAT_R8: u32 = __gbm_fourcc_code!('R', '8', ' ', ' '); // [7:0] R -/* 16 bpp RG */ -pub const GBM_FORMAT_GR88 :u32 = __gbm_fourcc_code!('G', 'R', '8', '8'); /* [15:0] G:R 8:8 little endian */ +// 16 bpp RG +pub const GBM_FORMAT_GR88: u32 = __gbm_fourcc_code!('G', 'R', '8', '8'); // [15:0] G:R 8:8 little endian -/* 8 bpp RGB */ -pub const GBM_FORMAT_RGB332 :u32 = __gbm_fourcc_code!('R', 'G', 'B', '8'); /* [7:0] R:G:B 3:3:2 */ -pub const GBM_FORMAT_BGR233 :u32 = __gbm_fourcc_code!('B', 'G', 'R', '8'); /* [7:0] B:G:R 2:3:3 */ +// 8 bpp RGB +pub const GBM_FORMAT_RGB332: u32 = __gbm_fourcc_code!('R', 'G', 'B', '8'); // [7:0] R:G:B 3:3:2 +pub const GBM_FORMAT_BGR233: u32 = __gbm_fourcc_code!('B', 'G', 'R', '8'); // [7:0] B:G:R 2:3:3 -/* 16 bpp RGB */ -pub const GBM_FORMAT_XRGB4444 :u32 = __gbm_fourcc_code!('X', 'R', '1', '2'); /* [15:0] x:R:G:B 4:4:4:4 little endian */ -pub const GBM_FORMAT_XBGR4444 :u32 = __gbm_fourcc_code!('X', 'B', '1', '2'); /* [15:0] x:B:G:R 4:4:4:4 little endian */ -pub const GBM_FORMAT_RGBX4444 :u32 = __gbm_fourcc_code!('R', 'X', '1', '2'); /* [15:0] R:G:B:x 4:4:4:4 little endian */ -pub const GBM_FORMAT_BGRX4444 :u32 = __gbm_fourcc_code!('B', 'X', '1', '2'); /* [15:0] B:G:R:x 4:4:4:4 little endian */ +// 16 bpp RGB +pub const GBM_FORMAT_XRGB4444: u32 = __gbm_fourcc_code!('X', 'R', '1', '2'); // [15:0] x:R:G:B 4:4:4:4 little endian +pub const GBM_FORMAT_XBGR4444: u32 = __gbm_fourcc_code!('X', 'B', '1', '2'); // [15:0] x:B:G:R 4:4:4:4 little endian +pub const GBM_FORMAT_RGBX4444: u32 = __gbm_fourcc_code!('R', 'X', '1', '2'); // [15:0] R:G:B:x 4:4:4:4 little endian +pub const GBM_FORMAT_BGRX4444: u32 = __gbm_fourcc_code!('B', 'X', '1', '2'); // [15:0] B:G:R:x 4:4:4:4 little endian -pub const GBM_FORMAT_ARGB4444 :u32 = __gbm_fourcc_code!('A', 'R', '1', '2'); /* [15:0] A:R:G:B 4:4:4:4 little endian */ -pub const GBM_FORMAT_ABGR4444 :u32 = __gbm_fourcc_code!('A', 'B', '1', '2'); /* [15:0] A:B:G:R 4:4:4:4 little endian */ -pub const GBM_FORMAT_RGBA4444 :u32 = __gbm_fourcc_code!('R', 'A', '1', '2'); /* [15:0] R:G:B:A 4:4:4:4 little endian */ -pub const GBM_FORMAT_BGRA4444 :u32 = __gbm_fourcc_code!('B', 'A', '1', '2'); /* [15:0] B:G:R:A 4:4:4:4 little endian */ +pub const GBM_FORMAT_ARGB4444: u32 = __gbm_fourcc_code!('A', 'R', '1', '2'); // [15:0] A:R:G:B 4:4:4:4 little endian +pub const GBM_FORMAT_ABGR4444: u32 = __gbm_fourcc_code!('A', 'B', '1', '2'); // [15:0] A:B:G:R 4:4:4:4 little endian +pub const GBM_FORMAT_RGBA4444: u32 = __gbm_fourcc_code!('R', 'A', '1', '2'); // [15:0] R:G:B:A 4:4:4:4 little endian +pub const GBM_FORMAT_BGRA4444: u32 = __gbm_fourcc_code!('B', 'A', '1', '2'); // [15:0] B:G:R:A 4:4:4:4 little endian -pub const GBM_FORMAT_XRGB1555 :u32 = __gbm_fourcc_code!('X', 'R', '1', '5'); /* [15:0] x:R:G:B 1:5:5:5 little endian */ -pub const GBM_FORMAT_XBGR1555 :u32 = __gbm_fourcc_code!('X', 'B', '1', '5'); /* [15:0] x:B:G:R 1:5:5:5 little endian */ -pub const GBM_FORMAT_RGBX5551 :u32 = __gbm_fourcc_code!('R', 'X', '1', '5'); /* [15:0] R:G:B:x 5:5:5:1 little endian */ -pub const GBM_FORMAT_BGRX5551 :u32 = __gbm_fourcc_code!('B', 'X', '1', '5'); /* [15:0] B:G:R:x 5:5:5:1 little endian */ +pub const GBM_FORMAT_XRGB1555: u32 = __gbm_fourcc_code!('X', 'R', '1', '5'); // [15:0] x:R:G:B 1:5:5:5 little endian +pub const GBM_FORMAT_XBGR1555: u32 = __gbm_fourcc_code!('X', 'B', '1', '5'); // [15:0] x:B:G:R 1:5:5:5 little endian +pub const GBM_FORMAT_RGBX5551: u32 = __gbm_fourcc_code!('R', 'X', '1', '5'); // [15:0] R:G:B:x 5:5:5:1 little endian +pub const GBM_FORMAT_BGRX5551: u32 = __gbm_fourcc_code!('B', 'X', '1', '5'); // [15:0] B:G:R:x 5:5:5:1 little endian -pub const GBM_FORMAT_ARGB1555 :u32 = __gbm_fourcc_code!('A', 'R', '1', '5'); /* [15:0] A:R:G:B 1:5:5:5 little endian */ -pub const GBM_FORMAT_ABGR1555 :u32 = __gbm_fourcc_code!('A', 'B', '1', '5'); /* [15:0] A:B:G:R 1:5:5:5 little endian */ -pub const GBM_FORMAT_RGBA5551 :u32 = __gbm_fourcc_code!('R', 'A', '1', '5'); /* [15:0] R:G:B:A 5:5:5:1 little endian */ -pub const GBM_FORMAT_BGRA5551 :u32 = __gbm_fourcc_code!('B', 'A', '1', '5'); /* [15:0] B:G:R:A 5:5:5:1 little endian */ +pub const GBM_FORMAT_ARGB1555: u32 = __gbm_fourcc_code!('A', 'R', '1', '5'); // [15:0] A:R:G:B 1:5:5:5 little endian +pub const GBM_FORMAT_ABGR1555: u32 = __gbm_fourcc_code!('A', 'B', '1', '5'); // [15:0] A:B:G:R 1:5:5:5 little endian +pub const GBM_FORMAT_RGBA5551: u32 = __gbm_fourcc_code!('R', 'A', '1', '5'); // [15:0] R:G:B:A 5:5:5:1 little endian +pub const GBM_FORMAT_BGRA5551: u32 = __gbm_fourcc_code!('B', 'A', '1', '5'); // [15:0] B:G:R:A 5:5:5:1 little endian -pub const GBM_FORMAT_RGB565 :u32 = __gbm_fourcc_code!('R', 'G', '1', '6'); /* [15:0] R:G:B 5:6:5 little endian */ -pub const GBM_FORMAT_BGR565 :u32 = __gbm_fourcc_code!('B', 'G', '1', '6'); /* [15:0] B:G:R 5:6:5 little endian */ +pub const GBM_FORMAT_RGB565: u32 = __gbm_fourcc_code!('R', 'G', '1', '6'); // [15:0] R:G:B 5:6:5 little endian +pub const GBM_FORMAT_BGR565: u32 = __gbm_fourcc_code!('B', 'G', '1', '6'); // [15:0] B:G:R 5:6:5 little endian -/* 24 bpp RGB */ -pub const GBM_FORMAT_RGB888 :u32 = __gbm_fourcc_code!('R', 'G', '2', '4'); /* [23:0] R:G:B little endian */ -pub const GBM_FORMAT_BGR888 :u32 = __gbm_fourcc_code!('B', 'G', '2', '4'); /* [23:0] B:G:R little endian */ +// 24 bpp RGB +pub const GBM_FORMAT_RGB888: u32 = __gbm_fourcc_code!('R', 'G', '2', '4'); // [23:0] R:G:B little endian +pub const GBM_FORMAT_BGR888: u32 = __gbm_fourcc_code!('B', 'G', '2', '4'); // [23:0] B:G:R little endian -/* 32 bpp RGB */ -pub const GBM_FORMAT_XRGB8888 :u32 = __gbm_fourcc_code!('X', 'R', '2', '4'); /* [31:0] x:R:G:B 8:8:8:8 little endian */ -pub const GBM_FORMAT_XBGR8888 :u32 = __gbm_fourcc_code!('X', 'B', '2', '4'); /* [31:0] x:B:G:R 8:8:8:8 little endian */ -pub const GBM_FORMAT_RGBX8888 :u32 = __gbm_fourcc_code!('R', 'X', '2', '4'); /* [31:0] R:G:B:x 8:8:8:8 little endian */ -pub const GBM_FORMAT_BGRX8888 :u32 = __gbm_fourcc_code!('B', 'X', '2', '4'); /* [31:0] B:G:R:x 8:8:8:8 little endian */ +// 32 bpp RGB +pub const GBM_FORMAT_XRGB8888: u32 = __gbm_fourcc_code!('X', 'R', '2', '4'); // [31:0] x:R:G:B 8:8:8:8 little endian +pub const GBM_FORMAT_XBGR8888: u32 = __gbm_fourcc_code!('X', 'B', '2', '4'); // [31:0] x:B:G:R 8:8:8:8 little endian +pub const GBM_FORMAT_RGBX8888: u32 = __gbm_fourcc_code!('R', 'X', '2', '4'); // [31:0] R:G:B:x 8:8:8:8 little endian +pub const GBM_FORMAT_BGRX8888: u32 = __gbm_fourcc_code!('B', 'X', '2', '4'); // [31:0] B:G:R:x 8:8:8:8 little endian -pub const GBM_FORMAT_ARGB8888 :u32 = __gbm_fourcc_code!('A', 'R', '2', '4'); /* [31:0] A:R:G:B 8:8:8:8 little endian */ -pub const GBM_FORMAT_ABGR8888 :u32 = __gbm_fourcc_code!('A', 'B', '2', '4'); /* [31:0] A:B:G:R 8:8:8:8 little endian */ -pub const GBM_FORMAT_RGBA8888 :u32 = __gbm_fourcc_code!('R', 'A', '2', '4'); /* [31:0] R:G:B:A 8:8:8:8 little endian */ -pub const GBM_FORMAT_BGRA8888 :u32 = __gbm_fourcc_code!('B', 'A', '2', '4'); /* [31:0] B:G:R:A 8:8:8:8 little endian */ +pub const GBM_FORMAT_ARGB8888: u32 = __gbm_fourcc_code!('A', 'R', '2', '4'); // [31:0] A:R:G:B 8:8:8:8 little endian +pub const GBM_FORMAT_ABGR8888: u32 = __gbm_fourcc_code!('A', 'B', '2', '4'); // [31:0] A:B:G:R 8:8:8:8 little endian +pub const GBM_FORMAT_RGBA8888: u32 = __gbm_fourcc_code!('R', 'A', '2', '4'); // [31:0] R:G:B:A 8:8:8:8 little endian +pub const GBM_FORMAT_BGRA8888: u32 = __gbm_fourcc_code!('B', 'A', '2', '4'); // [31:0] B:G:R:A 8:8:8:8 little endian -pub const GBM_FORMAT_XRGB2101010 :u32 = __gbm_fourcc_code!('X', 'R', '3', '0'); /* [31:0] x:R:G:B 2:10:10:10 little endian */ -pub const GBM_FORMAT_XBGR2101010 :u32 = __gbm_fourcc_code!('X', 'B', '3', '0'); /* [31:0] x:B:G:R 2:10:10:10 little endian */ -pub const GBM_FORMAT_RGBX1010102 :u32 = __gbm_fourcc_code!('R', 'X', '3', '0'); /* [31:0] R:G:B:x 10:10:10:2 little endian */ -pub const GBM_FORMAT_BGRX1010102 :u32 = __gbm_fourcc_code!('B', 'X', '3', '0'); /* [31:0] B:G:R:x 10:10:10:2 little endian */ +pub const GBM_FORMAT_XRGB2101010: u32 = __gbm_fourcc_code!('X', 'R', '3', '0'); // [31:0] x:R:G:B 2:10:10:10 little endian +pub const GBM_FORMAT_XBGR2101010: u32 = __gbm_fourcc_code!('X', 'B', '3', '0'); // [31:0] x:B:G:R 2:10:10:10 little endian +pub const GBM_FORMAT_RGBX1010102: u32 = __gbm_fourcc_code!('R', 'X', '3', '0'); // [31:0] R:G:B:x 10:10:10:2 little endian +pub const GBM_FORMAT_BGRX1010102: u32 = __gbm_fourcc_code!('B', 'X', '3', '0'); // [31:0] B:G:R:x 10:10:10:2 little endian -pub const GBM_FORMAT_ARGB2101010 :u32 = __gbm_fourcc_code!('A', 'R', '3', '0'); /* [31:0] A:R:G:B 2:10:10:10 little endian */ -pub const GBM_FORMAT_ABGR2101010 :u32 = __gbm_fourcc_code!('A', 'B', '3', '0'); /* [31:0] A:B:G:R 2:10:10:10 little endian */ -pub const GBM_FORMAT_RGBA1010102 :u32 = __gbm_fourcc_code!('R', 'A', '3', '0'); /* [31:0] R:G:B:A 10:10:10:2 little endian */ -pub const GBM_FORMAT_BGRA1010102 :u32 = __gbm_fourcc_code!('B', 'A', '3', '0'); /* [31:0] B:G:R:A 10:10:10:2 little endian */ +pub const GBM_FORMAT_ARGB2101010: u32 = __gbm_fourcc_code!('A', 'R', '3', '0'); // [31:0] A:R:G:B 2:10:10:10 little endian +pub const GBM_FORMAT_ABGR2101010: u32 = __gbm_fourcc_code!('A', 'B', '3', '0'); // [31:0] A:B:G:R 2:10:10:10 little endian +pub const GBM_FORMAT_RGBA1010102: u32 = __gbm_fourcc_code!('R', 'A', '3', '0'); // [31:0] R:G:B:A 10:10:10:2 little endian +pub const GBM_FORMAT_BGRA1010102: u32 = __gbm_fourcc_code!('B', 'A', '3', '0'); // [31:0] B:G:R:A 10:10:10:2 little endian -/* packed YCbCr */ -pub const GBM_FORMAT_YUYV :u32 = __gbm_fourcc_code!('Y', 'U', 'Y', 'V'); /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */ -pub const GBM_FORMAT_YVYU :u32 = __gbm_fourcc_code!('Y', 'V', 'Y', 'U'); /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */ -pub const GBM_FORMAT_UYVY :u32 = __gbm_fourcc_code!('U', 'Y', 'V', 'Y'); /* [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */ -pub const GBM_FORMAT_VYUY :u32 = __gbm_fourcc_code!('V', 'Y', 'U', 'Y'); /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */ +// packed YCbCr +pub const GBM_FORMAT_YUYV: u32 = __gbm_fourcc_code!('Y', 'U', 'Y', 'V'); // [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian +pub const GBM_FORMAT_YVYU: u32 = __gbm_fourcc_code!('Y', 'V', 'Y', 'U'); // [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian +pub const GBM_FORMAT_UYVY: u32 = __gbm_fourcc_code!('U', 'Y', 'V', 'Y'); // [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian +pub const GBM_FORMAT_VYUY: u32 = __gbm_fourcc_code!('V', 'Y', 'U', 'Y'); // [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian -pub const GBM_FORMAT_AYUV :u32 = __gbm_fourcc_code!('A', 'Y', 'U', 'V'); /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */ +pub const GBM_FORMAT_AYUV: u32 = __gbm_fourcc_code!('A', 'Y', 'U', 'V'); // [31:0] A:Y:Cb:Cr 8:8:8:8 little endian #[repr(C)] pub enum GBM_BO_IMPORT { WL_BUFFER = 0x5501, EGL_IMAGE = 0x5502, - FD = 0x5503, + FD = 0x5503, } #[cfg(feature = "gen")] include!(concat!(env!("OUT_DIR"), "/gen.rs")); -#[cfg(all(not(feature = "gen"), - target_os="linux", - target_arch="x86_64"))] +#[cfg(all(not(feature = "gen"), target_os = "linux", target_arch = "x86_64"))] include!(concat!("platforms/linux/x86_64/gen.rs")); #[link(name = "gbm")] -extern {} +extern "C" {} diff --git a/src/buffer_object.rs b/src/buffer_object.rs index 0c1d912..9c17958 100644 --- a/src/buffer_object.rs +++ b/src/buffer_object.rs @@ -9,8 +9,8 @@ use std::io::{Error as IoError, Result as IoResult}; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use std::os::unix::io::{AsRawFd, RawFd}; -use std::rc::Weak; use std::ptr; +use std::rc::Weak; use std::slice; /// A gbm buffer object @@ -104,27 +104,27 @@ impl<'a, T: 'static> MappedBufferObject<'a, T> { impl<'a, T: 'static> Deref for MappedBufferObject<'a, T> { type Target = BufferObject; fn deref(&self) -> &BufferObject { - match &self.bo { - &BORef::Ref(bo) => bo, - &BORef::Mut(ref bo) => bo, + match self.bo { + BORef::Ref(bo) => bo, + BORef::Mut(ref bo) => bo, } } } impl<'a, T: 'static> DerefMut for MappedBufferObject<'a, T> { fn deref_mut(&mut self) -> &mut BufferObject { - match &mut self.bo { - &mut BORef::Ref(_) => unreachable!(), - &mut BORef::Mut(ref mut bo) => bo, + match self.bo { + BORef::Ref(_) => unreachable!(), + BORef::Mut(ref mut bo) => bo, } } } impl<'a, T: 'static> Drop for MappedBufferObject<'a, T> { fn drop(&mut self) { - let ffi = match &self.bo { - &BORef::Ref(bo) => bo.ffi, - &BORef::Mut(ref bo) => bo.ffi, + let ffi = match self.bo { + BORef::Ref(bo) => bo.ffi, + BORef::Mut(ref bo) => bo.ffi, }; unsafe { ::ffi::gbm_bo_unmap(ffi, self.addr) } } @@ -169,7 +169,7 @@ impl BufferObject { pub fn format(&self) -> Result { if self._device.upgrade().is_some() { Ok(Format::from_ffi(unsafe { ::ffi::gbm_bo_get_format(self.ffi) }) - .expect("libgbm returned invalid buffer format")) + .expect("libgbm returned invalid buffer format")) } else { Err(DeviceDestroyedError) } @@ -190,16 +190,26 @@ impl BufferObject { /// Map a region of a gbm buffer object for cpu access /// /// This function maps a region of a gbm bo for cpu read access. - pub fn map<'a, D, F, S>(&'a self, device: &Device, x: u32, y: u32, width: u32, height: u32, f: F) -> Result, WrongDeviceError> - where - D: AsRawFd + 'static, - F: FnOnce(&MappedBufferObject<'a, T>) -> S, + pub fn map<'a, D, F, S>( + &'a self, + device: &Device, + x: u32, + y: u32, + width: u32, + height: u32, + f: F, + ) -> Result, WrongDeviceError> + where + D: AsRawFd + 'static, + F: FnOnce(&MappedBufferObject<'a, T>) -> S, { if let Some(_device) = self._device.upgrade() { - if *_device != device.as_raw_mut() { // not matching + if *_device != device.as_raw_mut() { + // not matching return Err(WrongDeviceError); } - } else { // not matching + } else { + // not matching return Err(WrongDeviceError); } @@ -249,15 +259,17 @@ impl BufferObject { height: u32, f: F, ) -> Result, WrongDeviceError> - where - D: AsRawFd + 'static, - F: FnOnce(&mut MappedBufferObject<'a, T>) -> S, + where + D: AsRawFd + 'static, + F: FnOnce(&mut MappedBufferObject<'a, T>) -> S, { if let Some(_device) = self._device.upgrade() { - if *_device != device.as_raw_mut() { // not matching + if *_device != device.as_raw_mut() { + // not matching return Err(WrongDeviceError); } - } else { // not matching + } else { + // not matching return Err(WrongDeviceError); } @@ -394,7 +406,10 @@ impl BufferObject { } } - pub(crate) unsafe fn new(ffi: *mut ::ffi::gbm_bo, device: Weak<*mut ::ffi::gbm_device>) -> BufferObject { + pub(crate) unsafe fn new( + ffi: *mut ::ffi::gbm_bo, + device: Weak<*mut ::ffi::gbm_device>, + ) -> BufferObject { BufferObject { ffi, _device: device, @@ -426,7 +441,10 @@ impl Drop for BufferObject { #[cfg(feature = "drm-support")] impl DrmBuffer for BufferObject { fn size(&self) -> (u32, u32) { - (self.width().expect("GbmDevice does not exist anymore"), self.height().expect("GbmDevice does not exist anymore")) + ( + self.width().expect("GbmDevice does not exist anymore"), + self.height().expect("GbmDevice does not exist anymore"), + ) } fn format(&self) -> DrmPixelFormat { @@ -438,7 +456,15 @@ impl DrmBuffer for BufferObject { } fn handle(&self) -> DrmId { - unsafe { DrmId::from_raw(*self.handle().expect("GbmDevice does not exist anymore").u32.as_ref()) } + unsafe { + DrmId::from_raw( + *self + .handle() + .expect("GbmDevice does not exist anymore") + .u32 + .as_ref(), + ) + } } } @@ -448,15 +474,11 @@ pub struct WrongDeviceError; impl fmt::Display for WrongDeviceError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use std::error::Error; - write!(f, "{}", self.description()) + write!( + f, + "The gbm specified is not the one this buffer object belongs to" + ) } } -impl error::Error for WrongDeviceError { - fn description(&self) -> &str { - "The gbm specified is not the one this buffer object belongs to" - } - - fn cause(&self) -> Option<&error::Error> { None } -} +impl error::Error for WrongDeviceError {} diff --git a/src/device.rs b/src/device.rs index d230a82..a9002db 100644 --- a/src/device.rs +++ b/src/device.rs @@ -5,25 +5,38 @@ use libc::c_void; use std::error; use std::ffi::CStr; use std::fmt; -use std::rc::Rc; use std::io::{Error as IoError, Result as IoResult}; -use std::os::unix::io::{AsRawFd, RawFd}; use std::ops::{Deref, DerefMut}; +use std::os::unix::io::{AsRawFd, RawFd}; +use std::rc::Rc; -#[cfg(feature = "import-wayland")] -use wayland_server::Resource; +#[cfg(feature = "glutin-support")] +use glutin_interface::{ + GbmWindowParts, NativeDisplay, NativeWindowSource, RawDisplay, Seal, WaylandWindowParts, X11WindowParts, +}; +#[cfg(feature = "glutin-support")] +use std::marker::PhantomData; +#[cfg(feature = "glutin-support")] +use std::sync::Arc; +#[cfg(feature = "glutin-support")] +use winit_types::platform::OsError; +#[cfg(feature = "glutin-support")] +use winit_types::{ + dpi::PhysicalSize, + error::{Error, ErrorType}, +}; #[cfg(feature = "import-wayland")] -use wayland_server::protocol::wl_buffer::WlBuffer; +use wayland_client::{protocol::wl_buffer::WlBuffer, Proxy}; #[cfg(feature = "import-egl")] /// An EGLImage handle pub type EGLImage = *mut c_void; -#[cfg(feature = "drm-support")] -use drm::Device as DrmDevice; #[cfg(feature = "drm-support")] use drm::control::Device as DrmControlDevice; +#[cfg(feature = "drm-support")] +use drm::Device as DrmDevice; /// Type wrapping a foreign file destructor pub struct FdWrapper(RawFd); @@ -76,7 +89,6 @@ impl Device { /// /// The lifetime of the resulting device depends on the ownership of the file descriptor. /// Closing the file descriptor before dropping the Device will lead to undefined behavior. - /// pub unsafe fn new_from_fd(fd: RawFd) -> IoResult> { let ptr = ::ffi::gbm_create_device(fd); if ptr.is_null() { @@ -102,7 +114,7 @@ impl Device { Err(IoError::last_os_error()) } else { Ok(Device { - fd: fd, + fd, ffi: Rc::new(ptr), }) } @@ -119,13 +131,7 @@ impl Device { /// Test if a format is supported for a given set of usage flags pub fn is_format_supported(&self, format: Format, usage: BufferObjectFlags) -> bool { - unsafe { - ::ffi::gbm_device_is_format_supported( - *self.ffi, - format.as_ffi(), - usage.bits(), - ) != 0 - } + unsafe { ::ffi::gbm_device_is_format_supported(*self.ffi, format.as_ffi(), usage.bits()) != 0 } } /// Allocate a new surface object @@ -136,15 +142,8 @@ impl Device { format: Format, usage: BufferObjectFlags, ) -> IoResult> { - let ptr = unsafe { - ::ffi::gbm_surface_create( - *self.ffi, - width, - height, - format.as_ffi(), - usage.bits(), - ) - }; + let ptr = + unsafe { ::ffi::gbm_surface_create(*self.ffi, width, height, format.as_ffi(), usage.bits()) }; if ptr.is_null() { Err(IoError::last_os_error()) } else { @@ -160,15 +159,7 @@ impl Device { format: Format, usage: BufferObjectFlags, ) -> IoResult> { - let ptr = unsafe { - ::ffi::gbm_bo_create( - *self.ffi, - width, - height, - format.as_ffi(), - usage.bits(), - ) - }; + let ptr = unsafe { ::ffi::gbm_bo_create(*self.ffi, width, height, format.as_ffi(), usage.bits()) }; if ptr.is_null() { Err(IoError::last_os_error()) } else { @@ -187,14 +178,14 @@ impl Device { #[cfg(feature = "import-wayland")] pub fn import_buffer_object_from_wayland( &self, - buffer: &WlBuffer, + buffer: &Proxy, usage: BufferObjectFlags, ) -> IoResult> { let ptr = unsafe { ::ffi::gbm_bo_import( *self.ffi, ::ffi::GBM_BO_IMPORT::WL_BUFFER as u32, - buffer.ptr() as *mut _, + buffer.c_ptr() as *mut _, usage.bits(), ) }; @@ -224,13 +215,12 @@ impl Device { buffer: EGLImage, usage: BufferObjectFlags, ) -> IoResult> { - let ptr = - ::ffi::gbm_bo_import( - *self.ffi, - ::ffi::GBM_BO_IMPORT::EGL_IMAGE as u32, - buffer, - usage.bits(), - ); + let ptr = ::ffi::gbm_bo_import( + *self.ffi, + ::ffi::GBM_BO_IMPORT::EGL_IMAGE as u32, + buffer, + usage.bits(), + ); if ptr.is_null() { Err(IoError::last_os_error()) } else { @@ -257,9 +247,9 @@ impl Device { ) -> IoResult> { let mut fd_data = ::ffi::gbm_import_fd_data { fd: buffer, - width: width, - height: height, - stride: stride, + width, + height, + stride, format: format.as_ffi(), }; @@ -285,6 +275,66 @@ impl DrmDevice for Device {} #[cfg(feature = "drm-support")] impl DrmControlDevice for Device {} +#[cfg(feature = "glutin-support")] +/// This is a horrid wrapper around [`Device`] that lets us implement Glutin's +/// `NativeWindowSource` on `Device` while allowing [`Surface`] to be generic +/// over `TS`. +/// +/// [`Device`]: crate::Device +/// [`Surface`]: crate::Surface +pub struct DeviceGlutinWrapper<'a, TD: AsRawFd + 'static, TS: 'static>(&'a Device, PhantomData); + +#[cfg(feature = "glutin-support")] +impl<'a, TD: AsRawFd + 'static, TS: 'static> From<&'a Device> for DeviceGlutinWrapper<'a, TD, TS> { + fn from(d: &Device) -> DeviceGlutinWrapper { + DeviceGlutinWrapper(d, PhantomData) + } +} + +#[cfg(feature = "glutin-support")] +impl<'a, TD: AsRawFd + 'static, TS: 'static> NativeWindowSource for DeviceGlutinWrapper<'a, TD, TS> { + type Window = Surface; + type WindowBuilder = (PhysicalSize, BufferObjectFlags); + + fn build_wayland( + &self, + _wb: Self::WindowBuilder, + _wwp: WaylandWindowParts, + ) -> Result { + unimplemented!("GBM does not provide Wayland support") + } + + fn build_x11(&self, _wb: Self::WindowBuilder, _xwp: X11WindowParts) -> Result { + unimplemented!("GBM does not provide X11 support") + } + + fn build_gbm(&self, wb: Self::WindowBuilder, gbmwp: GbmWindowParts) -> Result { + if !wb.1.contains(BufferObjectFlags::RENDERING) { + return Err(make_error!(ErrorType::BadApiUsage( + "BufferObjectFlags::RENDERING was not present.".to_string() + ))); + } + self.0 + .create_surface( + wb.0.width, + wb.0.height, + Format::from_ffi(gbmwp.color_format).unwrap(), + wb.1, + ) + .map_err(|err| make_oserror!(OsError::IoError(Arc::new(err)))) + } +} + +#[cfg(feature = "glutin-support")] +impl NativeDisplay for Device { + fn raw_display(&self) -> RawDisplay { + RawDisplay::Gbm { + gbm_device: Some(*self.ffi as *mut _), + _non_exhaustive_do_not_use: Seal, + } + } +} + impl Drop for Device { fn drop(&mut self) { unsafe { ::ffi::gbm_device_destroy(*self.ffi) }; @@ -297,15 +347,8 @@ pub struct DeviceDestroyedError; impl fmt::Display for DeviceDestroyedError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use std::error::Error; - write!(f, "{}", self.description()) + write!(f, "The underlying gbm device was already destroyed") } } -impl error::Error for DeviceDestroyedError { - fn description(&self) -> &str { - "The underlying gbm device was already destroyed" - } - - fn cause(&self) -> Option<&error::Error> { None } -} +impl error::Error for DeviceDestroyedError {} diff --git a/src/lib.rs b/src/lib.rs index aae3b92..4af42a9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -89,16 +89,23 @@ extern crate gbm_sys as ffi; extern crate libc; #[cfg(feature = "import-wayland")] -extern crate wayland_server; +extern crate wayland_client; #[cfg(feature = "drm-support")] extern crate drm; +#[cfg(feature = "glutin-support")] +extern crate glutin_interface; + +#[cfg(feature = "glutin-support")] +#[macro_use] +extern crate winit_types; + #[macro_use] extern crate bitflags; -mod device; mod buffer_object; +mod device; mod surface; pub use self::buffer_object::*; @@ -180,9 +187,9 @@ pub enum Format { impl Format { #[doc(hidden)] - pub fn as_ffi(&self) -> u32 { + pub fn as_ffi(self) -> u32 { use Format::*; - match *self { + match self { C8 => ::ffi::GBM_FORMAT_C8, R8 => ::ffi::GBM_FORMAT_R8, GR88 => ::ffi::GBM_FORMAT_GR88, diff --git a/src/surface.rs b/src/surface.rs index 79cb90b..59384fd 100644 --- a/src/surface.rs +++ b/src/surface.rs @@ -1,10 +1,10 @@ -use {AsRaw, BufferObject, DeviceDestroyedError}; -use std::error::{self, Error}; +use std::error; use std::fmt; use std::marker::PhantomData; use std::mem; use std::ops::{Deref, DerefMut}; use std::rc::{Rc, Weak}; +use {AsRaw, BufferObject, DeviceDestroyedError}; /// A gbm rendering surface pub struct Surface { @@ -13,6 +13,31 @@ pub struct Surface { _bo_userdata: PhantomData, } +#[cfg(feature = "glutin-support")] +use glutin_interface::{NativeWindow, RawWindow, Seal}; + +#[cfg(feature = "glutin-support")] +use winit_types::dpi::PhysicalSize; + +#[cfg(feature = "glutin-support")] +impl NativeWindow for Surface { + fn raw_window(&self) -> RawWindow { + RawWindow::Gbm { + gbm_surface: *self.ffi as *mut _, + _non_exhaustive_do_not_use: Seal, + } + } + + fn size(&self) -> PhysicalSize { + // Glutin doesn't need this for this platform, so whatever + unimplemented!() + } + + fn scale_factor(&self) -> f64 { + 1.0 + } +} + /// Handle to a front buffer of a surface pub struct SurfaceBufferHandle(Weak<*mut ::ffi::gbm_surface>, Option>); @@ -56,20 +81,17 @@ pub enum FrontBufferError { impl fmt::Display for FrontBufferError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.description()) + let err = match *self { + FrontBufferError::NoFreeBuffers => "No free buffers remaining".to_string(), + FrontBufferError::Unknown => "Unknown error".to_string(), + FrontBufferError::Destroyed(ref err) => err.to_string(), + }; + write!(f, "{}", err) } } impl error::Error for FrontBufferError { - fn description(&self) -> &str { - match *self { - FrontBufferError::NoFreeBuffers => "No free buffers remaining", - FrontBufferError::Unknown => "Unknown error", - FrontBufferError::Destroyed(ref err) => err.description(), - } - } - - fn cause(&self) -> Option<&error::Error> { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { match *self { FrontBufferError::Destroyed(ref err) => Some(err), _ => None, @@ -122,7 +144,10 @@ impl Surface { } } - pub(crate) unsafe fn new(ffi: *mut ::ffi::gbm_surface, device: Weak<*mut ::ffi::gbm_device>) -> Surface { + pub(crate) unsafe fn new( + ffi: *mut ::ffi::gbm_surface, + device: Weak<*mut ::ffi::gbm_device>, + ) -> Surface { Surface { ffi: Rc::new(ffi), _device: device,