The glory of error-chain

This commit is contained in:
Drakulix 2017-09-18 16:58:20 +02:00
parent a04bfcdd11
commit fa6742fb5f
7 changed files with 380 additions and 421 deletions

View File

@ -22,6 +22,7 @@ clippy = { version = "*", optional = true }
rental = "0.4.11"
wayland-protocols = { version = "0.10.1", features = ["unstable_protocols", "server"] }
image = "0.15.0"
error-chain = "0.11.0"
[build-dependencies]
gl_generator = "0.5"

View File

@ -1,5 +1,5 @@
use super::{CrtcError, DrmError, ModeError};
use super::devices;
use super::error::*;
use backend::graphics::GraphicsBackend;
use backend::graphics::egl::{EGLGraphicsBackend, EGLSurface, PixelFormat, SwapBuffersError};
use drm::buffer::Buffer;
@ -94,7 +94,7 @@ pub(crate) struct DrmBackendInternal {
impl DrmBackendInternal {
pub(crate) fn new<I, L>(context: Rc<devices::Context>, crtc: crtc::Handle, mode: Mode, connectors: I,
own_id: usize, logger: L)
-> Result<DrmBackendInternal, DrmError>
-> Result<DrmBackendInternal>
where
I: Into<Vec<connector::Handle>>,
L: Into<Option<::slog::Logger>>,
@ -107,11 +107,12 @@ impl DrmBackendInternal {
// check the connectors, if they suite the mode
for connector in connectors.iter() {
if !connector::Info::load_from_device(context.head().head(), *connector)?
if !connector::Info::load_from_device(context.head().head(), *connector)
.chain_err(|| ErrorKind::DrmDev(format!("{:?}", context.head().head())))?
.modes()
.contains(&mode)
{
return Err(DrmError::Mode(ModeError::ModeNotSuitable));
bail!(ErrorKind::ModeNotSuitable(mode))
}
}
@ -122,23 +123,31 @@ impl DrmBackendInternal {
Ok(GbmTypes {
cursor: {
// Create an unused cursor buffer (we don't want an Option here)
context.devices.gbm.create_buffer_object(
1,
1,
GbmFormat::ARGB8888,
&[BufferObjectFlags::Cursor, BufferObjectFlags::Write],
)?
context
.devices
.gbm
.create_buffer_object(
1,
1,
GbmFormat::ARGB8888,
&[BufferObjectFlags::Cursor, BufferObjectFlags::Write],
)
.chain_err(|| ErrorKind::GbmInitFailed)?
},
surface: Surface::try_new(
{
debug!(log, "Creating GbmSurface");
// create a gbm surface
Box::new(context.devices.gbm.create_surface(
w as u32,
h as u32,
GbmFormat::XRGB8888,
&[BufferObjectFlags::Scanout, BufferObjectFlags::Rendering],
)?)
Box::new(context
.devices
.gbm
.create_surface(
w as u32,
h as u32,
GbmFormat::XRGB8888,
&[BufferObjectFlags::Scanout, BufferObjectFlags::Rendering],
)
.chain_err(|| ErrorKind::GbmInitFailed)?)
},
|surface| {
// create an egl surface from the gbm one
@ -147,15 +156,24 @@ impl DrmBackendInternal {
// make it active for the first `crtc::set`
// (which is needed before the first page_flip)
unsafe { egl_surface.make_current()? };
egl_surface.swap_buffers()?;
unsafe {
egl_surface
.make_current()
.chain_err(|| ErrorKind::FailedToSwap)?
};
egl_surface
.swap_buffers()
.chain_err(|| ErrorKind::FailedToSwap)?;
// init the first screen
// (must be done before calling page_flip for the first time)
let mut front_bo = surface.lock_front_buffer()?;
let mut front_bo = surface
.lock_front_buffer()
.chain_err(|| ErrorKind::FailedToSwap)?;
debug!(log, "FrontBuffer color format: {:?}", front_bo.format());
// we need a framebuffer per front buffer
let fb = framebuffer::create(context.devices.drm, &*front_bo)?;
let fb = framebuffer::create(context.devices.drm, &*front_bo)
.chain_err(|| ErrorKind::DrmDev(format!("{:?}", context.devices.drm)))?;
debug!(log, "Initialize screen");
crtc::set(
@ -165,6 +183,8 @@ impl DrmBackendInternal {
&connectors,
(0, 0),
Some(mode),
).chain_err(
|| ErrorKind::DrmDev(format!("{:?}", context.devices.drm)),
)?;
front_bo.set_userdata(fb);
@ -176,7 +196,7 @@ impl DrmBackendInternal {
},
})
},
).map_err(DrmError::from)?,
).map_err(Error::from)?,
})
})?,
crtc,
@ -216,10 +236,15 @@ impl DrmBackend {
/// # Errors
///
/// Errors if the new connector does not support the currently set `Mode`
pub fn add_connector(&mut self, connector: connector::Handle) -> Result<(), DrmError> {
pub fn add_connector(&mut self, connector: connector::Handle) -> Result<()> {
let info =
connector::Info::load_from_device(self.0.borrow().graphics.head().head().head(), connector)
.map_err(|err| ModeError::FailedToLoad(err))?;
.chain_err(|| {
ErrorKind::DrmDev(format!(
"{:?}",
self.0.borrow().graphics.head().head().head()
))
})?;
// check if the connector can handle the current mode
let mut internal = self.0.borrow_mut();
@ -229,16 +254,21 @@ impl DrmBackend {
.iter()
.map(|encoder| {
encoder::Info::load_from_device(self.0.borrow().graphics.head().head().head(), *encoder)
.map_err(DrmError::from)
.chain_err(|| {
ErrorKind::DrmDev(format!(
"{:?}",
self.0.borrow().graphics.head().head().head()
))
})
})
.collect::<Result<Vec<encoder::Info>, DrmError>>()?;
.collect::<Result<Vec<encoder::Info>>>()?;
// and if any encoder supports the selected crtc
if !encoders
.iter()
.any(|encoder| encoder.supports_crtc(self.0.borrow().crtc))
{
return Err(DrmError::Crtc(CrtcError::NoSuitableEncoder));
bail!(ErrorKind::NoSuitableEncoder(info, self.0.borrow().crtc));
}
info!(
@ -249,7 +279,7 @@ impl DrmBackend {
internal.connectors.push(connector);
Ok(())
} else {
Err(DrmError::Mode(ModeError::ModeNotSuitable))
bail!(ErrorKind::ModeNotSuitable(self.0.borrow().mode))
}
}
@ -270,7 +300,7 @@ impl DrmBackend {
info.connector_type()
);
} else {
info!(self.0.borrow().logger, "Removeing unknown connector");
info!(self.0.borrow().logger, "Removing unknown connector");
}
self.0.borrow_mut().connectors.retain(|x| *x != connector);
@ -283,14 +313,20 @@ impl DrmBackend {
/// This will fail if not all set connectors support the new `Mode`.
/// Several internal resources will need to be recreated to fit the new `Mode`.
/// Other errors might occur.
pub fn use_mode(&mut self, mode: Mode) -> Result<(), DrmError> {
pub fn use_mode(&mut self, mode: Mode) -> Result<()> {
// check the connectors
for connector in self.0.borrow().connectors.iter() {
if !connector::Info::load_from_device(self.0.borrow().graphics.head().head().head(), *connector)?
if !connector::Info::load_from_device(self.0.borrow().graphics.head().head().head(), *connector)
.chain_err(|| {
ErrorKind::DrmDev(format!(
"{:?}",
self.0.borrow().graphics.head().head().head()
))
})?
.modes()
.contains(&mode)
{
return Err(DrmError::Mode(ModeError::ModeNotSuitable));
bail!(ErrorKind::ModeNotSuitable(mode));
}
}
@ -303,61 +339,76 @@ impl DrmBackend {
let (w, h) = mode.size();
internal
.graphics
.rent_all_mut(|graphics| -> Result<(), DrmError> {
// Recreate the surface and the related resources to match the new
// resolution.
debug!(logger, "Reinitializing surface for new mode: {}:{}", w, h);
graphics.gbm.surface = Surface::try_new(
{
// create a new gbm surface
debug!(logger, "Creating GbmSurface");
Box::new(graphics.context.devices.gbm.create_surface(
internal.graphics.rent_all_mut(|graphics| -> Result<()> {
// Recreate the surface and the related resources to match the new
// resolution.
debug!(logger, "Reinitializing surface for new mode: {}:{}", w, h);
graphics.gbm.surface = Surface::try_new(
{
// create a new gbm surface
debug!(logger, "Creating GbmSurface");
Box::new(graphics
.context
.devices
.gbm
.create_surface(
w as u32,
h as u32,
GbmFormat::XRGB8888,
&[BufferObjectFlags::Scanout, BufferObjectFlags::Rendering],
)?)
},
|surface| {
// create an egl surface from the gbm one
debug!(logger, "Creating EGLSurface");
let egl_surface = graphics.context.egl.create_surface(&surface)?;
)
.chain_err(|| ErrorKind::GbmInitFailed)?)
},
|surface| {
// create an egl surface from the gbm one
debug!(logger, "Creating EGLSurface");
let egl_surface = graphics.context.egl.create_surface(&surface)?;
// make it active for the first `crtc::set`
// (which is needed before the first page_flip)
unsafe { egl_surface.make_current()? };
egl_surface.swap_buffers()?;
// make it active for the first `crtc::set`
// (which is needed before the first page_flip)
unsafe {
egl_surface
.make_current()
.chain_err(|| ErrorKind::FailedToSwap)?
};
egl_surface
.swap_buffers()
.chain_err(|| ErrorKind::FailedToSwap)?;
let mut front_bo = surface.lock_front_buffer()?;
debug!(logger, "FrontBuffer color format: {:?}", front_bo.format());
// we need a framebuffer per front_buffer
let fb = framebuffer::create(graphics.context.devices.drm, &*front_bo)?;
let mut front_bo = surface
.lock_front_buffer()
.chain_err(|| ErrorKind::FailedToSwap)?;
debug!(logger, "FrontBuffer color format: {:?}", front_bo.format());
// we need a framebuffer per front_buffer
let fb = framebuffer::create(graphics.context.devices.drm, &*front_bo).chain_err(|| {
ErrorKind::DrmDev(format!("{:?}", graphics.context.devices.drm))
})?;
debug!(logger, "Initialize screen");
crtc::set(
graphics.context.devices.drm,
crtc,
fb.handle(),
&connectors,
(0, 0),
Some(mode),
)?;
front_bo.set_userdata(fb);
debug!(logger, "Initialize screen");
crtc::set(
graphics.context.devices.drm,
crtc,
fb.handle(),
&connectors,
(0, 0),
Some(mode),
).chain_err(|| {
ErrorKind::DrmDev(format!("{:?}", graphics.context.devices.drm))
})?;
front_bo.set_userdata(fb);
Ok(EGL {
surface: egl_surface,
buffers: GbmBuffers {
front_buffer: Cell::new(front_bo),
next_buffer: Cell::new(None),
},
})
},
)?;
Ok(EGL {
surface: egl_surface,
buffers: GbmBuffers {
front_buffer: Cell::new(front_bo),
next_buffer: Cell::new(None),
},
})
},
)?;
Ok(())
})?;
Ok(())
})?;
info!(logger, "Setting new mode: {:?}", mode.name());
internal.mode = mode;
@ -375,34 +426,46 @@ impl DrmBackend {
impl GraphicsBackend for DrmBackend {
type CursorFormat = ImageBuffer<Rgba<u8>, Vec<u8>>;
type Error = DrmError;
type Error = Error;
fn set_cursor_position(&self, x: u32, y: u32) -> Result<(), DrmError> {
fn set_cursor_position(&self, x: u32, y: u32) -> Result<()> {
trace!(self.0.borrow().logger, "Move the cursor to {},{}", x, y);
crtc::move_cursor(
self.0.borrow().graphics.head().head().head(),
self.0.borrow().crtc,
(x as i32, y as i32),
).map_err(DrmError::from)
).chain_err(|| {
ErrorKind::DrmDev(format!(
"{:?}",
self.0.borrow().graphics.head().head().head()
))
})
}
fn set_cursor_representation(&self, buffer: ImageBuffer<Rgba<u8>, Vec<u8>>, hotspot: (u32, u32))
-> Result<(), DrmError> {
-> Result<()> {
let (w, h) = buffer.dimensions();
debug!(self.0.borrow().logger, "Importing cursor");
/// import the cursor into a buffer we can render
self.0
.borrow_mut()
.graphics
.rent_all_mut(|graphics| -> Result<(), DrmError> {
.rent_all_mut(|graphics| -> Result<()> {
graphics.gbm.cursor = {
let mut cursor = graphics.context.devices.gbm.create_buffer_object(
w,
h,
GbmFormat::ARGB8888,
&[BufferObjectFlags::Cursor, BufferObjectFlags::Write],
)?;
cursor.write(&*buffer.into_raw())?;
let mut cursor = graphics
.context
.devices
.gbm
.create_buffer_object(
w,
h,
GbmFormat::ARGB8888,
&[BufferObjectFlags::Cursor, BufferObjectFlags::Write],
)
.chain_err(|| ErrorKind::GbmInitFailed)?;
cursor
.write(&*buffer.into_raw())
.chain_err(|| ErrorKind::GbmInitFailed)?;
cursor
};
Ok(())
@ -429,7 +492,12 @@ impl GraphicsBackend for DrmBackend {
.graphics
.rent(|gbm| Buffer::handle(&gbm.cursor)),
(w, h),
).map_err(DrmError::from)
).chain_err(|| {
ErrorKind::DrmDev(format!(
"{:?}",
self.0.borrow().graphics.head().head().head()
))
})
} else {
Ok(())
}
@ -437,7 +505,7 @@ impl GraphicsBackend for DrmBackend {
}
impl EGLGraphicsBackend for DrmBackend {
fn swap_buffers(&self) -> Result<(), SwapBuffersError> {
fn swap_buffers(&self) -> ::std::result::Result<(), SwapBuffersError> {
self.0.borrow().graphics.rent_all(|graphics| {
// We cannot call lock_front_buffer anymore without releasing the previous buffer, which will happen when the page flip is done
if graphics.gbm.surface.rent(|egl| {
@ -503,7 +571,7 @@ impl EGLGraphicsBackend for DrmBackend {
.rent(|context| context.is_current())
}
unsafe fn make_current(&self) -> Result<(), SwapBuffersError> {
unsafe fn make_current(&self) -> ::std::result::Result<(), SwapBuffersError> {
self.0
.borrow()
.graphics

View File

@ -1,110 +1,52 @@
use backend::graphics::egl::{CreationError, SwapBuffersError};
use drm::result::Error as DrmError;
use gbm::FrontBufferError;
//!
//! Errors thrown by the `DrmDevice` and `DrmBackend`
//!
use backend::graphics::egl;
use drm::control::{connector, crtc, Mode};
use rental::TryNewError;
use std::error::{self, Error as ErrorTrait};
use std::fmt;
use std::io::Error as IoError;
error_chain! {
errors {
#[doc = "The `DrmDevice` encountered an access error"]
DrmDev(dev: String) {
description("The drm device encountered an access error"),
display("The drm device ({:?}) encountered an access error", dev),
}
/// Error summing up error types related to all underlying libraries
/// involved in creating the a `DrmDevice`/`DrmBackend`
#[derive(Debug)]
pub enum Error {
/// The `DrmDevice` has encountered an error on an ioctl
Drm(DrmError),
/// The `EGLContext` could not be created
EGLCreation(CreationError),
/// Swapping Buffers via EGL was not possible
EGLSwap(SwapBuffersError),
/// Locking the front buffer of the underlying `GbmSurface` failed
Gbm(FrontBufferError),
/// A generic IO-Error happened accessing the underlying devices
Io(IoError),
/// Selected an invalid Mode
Mode(ModeError),
/// Error related to the selected crtc
Crtc(CrtcError),
}
#[doc = "Creation of gbm resource failed"]
GbmInitFailed {
description("Creation of gbm resource failed"),
display("Creation of gbm resource failed"),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"DrmBackend error: {}",
match self {
&Error::Drm(ref x) => x as &error::Error,
&Error::EGLCreation(ref x) => x as &error::Error,
&Error::EGLSwap(ref x) => x as &error::Error,
&Error::Gbm(ref x) => x as &error::Error,
&Error::Io(ref x) => x as &error::Error,
&Error::Mode(ref x) => x as &error::Error,
&Error::Crtc(ref x) => x as &error::Error,
}
)
}
}
#[doc = "Swapping front buffers failed"]
FailedToSwap {
description("Swapping front buffers failed"),
display("Swapping front buffers failed"),
}
impl error::Error for Error {
fn description(&self) -> &str {
"DrmBackend error"
}
#[doc = "mode is not compatible with all given connectors"]
ModeNotSuitable(mode: Mode) {
description("Mode is not compatible with all given connectors"),
display("Mode ({:?}) is not compatible with all given connectors", mode),
}
fn cause(&self) -> Option<&error::Error> {
match self {
&Error::Drm(ref x) => Some(x as &error::Error),
&Error::EGLCreation(ref x) => Some(x as &error::Error),
&Error::EGLSwap(ref x) => Some(x as &error::Error),
&Error::Gbm(ref x) => Some(x as &error::Error),
&Error::Io(ref x) => Some(x as &error::Error),
&Error::Mode(ref x) => Some(x as &error::Error),
&Error::Crtc(ref x) => Some(x as &error::Error),
#[doc = "The given crtc is already in use by another backend"]
CrtcAlreadyInUse(crtc: crtc::Handle) {
description("The given crtc is already in use by another backend"),
display("The given crtc ({:?}) is already in use by another backend", crtc),
}
#[doc = "No encoder was found for a given connector on the set crtc"]
NoSuitableEncoder(connector: connector::Info, crtc: crtc::Handle) {
description("No encoder found for given connector on set crtc"),
display("No encoder found for the given connector '{:?}' on the set crtc ({:?})", connector.connector_type(), crtc),
}
}
}
impl From<DrmError> for Error {
fn from(err: DrmError) -> Error {
Error::Drm(err)
}
}
impl From<CreationError> for Error {
fn from(err: CreationError) -> Error {
Error::EGLCreation(err)
}
}
impl From<SwapBuffersError> for Error {
fn from(err: SwapBuffersError) -> Error {
Error::EGLSwap(err)
}
}
impl From<FrontBufferError> for Error {
fn from(err: FrontBufferError) -> Error {
Error::Gbm(err)
}
}
impl From<IoError> for Error {
fn from(err: IoError) -> Error {
Error::Io(err)
}
}
impl From<ModeError> for Error {
fn from(err: ModeError) -> Error {
match err {
err @ ModeError::ModeNotSuitable => Error::Mode(err),
ModeError::FailedToLoad(err) => Error::Drm(err),
}
}
}
impl From<CrtcError> for Error {
fn from(err: CrtcError) -> Error {
Error::Crtc(err)
links {
EGL(egl::Error, egl::ErrorKind) #[doc = "EGL error"];
}
}
@ -113,72 +55,3 @@ impl<H> From<TryNewError<Error, H>> for Error {
err.0
}
}
/// Error when trying to select an invalid mode
#[derive(Debug)]
pub enum ModeError {
/// `Mode` is not compatible with all given connectors
ModeNotSuitable,
/// Failed to load `Mode` information
FailedToLoad(DrmError),
}
impl fmt::Display for ModeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())?;
if let Some(cause) = self.cause() {
write!(f, "\tCause: {}", cause)?;
}
Ok(())
}
}
impl error::Error for ModeError {
fn description(&self) -> &str {
match self {
&ModeError::ModeNotSuitable => "Mode does not match all attached connectors",
&ModeError::FailedToLoad(_) => "Failed to load mode information from device",
}
}
fn cause(&self) -> Option<&error::Error> {
match self {
&ModeError::FailedToLoad(ref err) => Some(err as &error::Error),
_ => None,
}
}
}
/// Errors related to the selected crtc
#[derive(Debug)]
pub enum CrtcError {
/// Selected crtc is already in use by another `DrmBackend`
AlreadyInUse,
/// For the selected crtc no encoder exists that supports all connectors
NoSuitableEncoder,
}
impl fmt::Display for CrtcError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())?;
if let Some(cause) = self.cause() {
write!(f, "\tCause: {}", cause)?;
}
Ok(())
}
}
impl error::Error for CrtcError {
fn description(&self) -> &str {
match self {
&CrtcError::AlreadyInUse => "Crtc is already in use by another DrmBackend",
&CrtcError::NoSuitableEncoder => "Crtc has no supported encoder that can drive all connectors",
}
}
fn cause(&self) -> Option<&error::Error> {
match self {
_ => None,
}
}
}

View File

@ -205,11 +205,11 @@ use wayland_server::EventLoopHandle;
use wayland_server::sources::{FdEventSourceHandler, FdInterest};
mod backend;
mod error;
pub mod error;
pub use self::backend::{DrmBackend, Id};
use self::backend::DrmBackendInternal;
pub use self::error::{CrtcError, Error as DrmError, ModeError};
use self::error::*;
/// Internal struct as required by the drm crate
#[derive(Debug)]
@ -275,7 +275,7 @@ impl<H: DrmHandler + 'static> DrmDevice<H> {
/// # Safety
/// The file descriptor might not be valid and needs to be owned by smithay,
/// make sure not to share it. Otherwise undefined behavior might occur.
pub unsafe fn new_from_fd<L>(fd: RawFd, logger: L) -> Result<Self, DrmError>
pub unsafe fn new_from_fd<L>(fd: RawFd, logger: L) -> Result<Self>
where
L: Into<Option<::slog::Logger>>,
{
@ -299,8 +299,7 @@ impl<H: DrmHandler + 'static> DrmDevice<H> {
/// # Safety
/// The file descriptor might not be valid and needs to be owned by smithay,
/// make sure not to share it. Otherwise undefined behavior might occur.
pub unsafe fn new_from_fd_with_gl_attr<L>(fd: RawFd, attributes: GlAttributes, logger: L)
-> Result<Self, DrmError>
pub unsafe fn new_from_fd_with_gl_attr<L>(fd: RawFd, attributes: GlAttributes, logger: L) -> Result<Self>
where
L: Into<Option<::slog::Logger>>,
{
@ -311,7 +310,7 @@ impl<H: DrmHandler + 'static> DrmDevice<H> {
///
/// Returns an error if the file is no valid drm node or context creation was not
/// successful.
pub fn new_from_file<L>(file: File, logger: L) -> Result<Self, DrmError>
pub fn new_from_file<L>(file: File, logger: L) -> Result<Self>
where
L: Into<Option<::slog::Logger>>,
{
@ -331,15 +330,14 @@ impl<H: DrmHandler + 'static> DrmDevice<H> {
///
/// Returns an error if the file is no valid drm node or context creation was not
/// successful.
pub fn new_from_file_with_gl_attr<L>(file: File, attributes: GlAttributes, logger: L)
-> Result<Self, DrmError>
pub fn new_from_file_with_gl_attr<L>(file: File, attributes: GlAttributes, logger: L) -> Result<Self>
where
L: Into<Option<::slog::Logger>>,
{
DrmDevice::new(DrmDev::new_from_file(file), attributes, logger)
}
fn new<L>(drm: DrmDev, attributes: GlAttributes, logger: L) -> Result<Self, DrmError>
fn new<L>(drm: DrmDev, attributes: GlAttributes, logger: L) -> Result<Self>
where
L: Into<Option<::slog::Logger>>,
{
@ -365,7 +363,7 @@ impl<H: DrmHandler + 'static> DrmDevice<H> {
context: Rc::new(Context::try_new(
Box::new(Devices::try_new(Box::new(drm), |drm| {
debug!(log, "Creating gbm device");
GbmDevice::new_from_drm::<DrmDevice<H>>(drm).map_err(DrmError::from)
GbmDevice::new_from_drm::<DrmDevice<H>>(drm).chain_err(|| ErrorKind::GbmInitFailed)
})?),
|devices| {
debug!(log, "Creating egl context from gbm device");
@ -379,7 +377,7 @@ impl<H: DrmHandler + 'static> DrmDevice<H> {
..Default::default()
},
log.clone(),
).map_err(DrmError::from)
).map_err(Error::from)
},
)?),
backends: Vec::new(),
@ -393,15 +391,14 @@ impl<H: DrmHandler + 'static> DrmDevice<H> {
///
/// Errors if initialization fails or the mode is not available on all given
/// connectors.
pub fn create_backend<I>(&mut self, crtc: crtc::Handle, mode: Mode, connectors: I)
-> Result<DrmBackend, DrmError>
pub fn create_backend<I>(&mut self, crtc: crtc::Handle, mode: Mode, connectors: I) -> Result<DrmBackend>
where
I: Into<Vec<connector::Handle>>,
{
for backend in self.backends.iter() {
if let Some(backend) = backend.upgrade() {
if backend.borrow().is_crtc(crtc) {
return Err(DrmError::Crtc(CrtcError::AlreadyInUse));
bail!(ErrorKind::CrtcAlreadyInUse(crtc))
}
}
}
@ -411,21 +408,25 @@ impl<H: DrmHandler + 'static> DrmDevice<H> {
// check if we have an encoder for every connector
for connector in connectors.iter() {
let con_info = connector::Info::load_from_device(self.context.head().head(), *connector)?;
let con_info = connector::Info::load_from_device(self.context.head().head(), *connector)
.chain_err(|| {
ErrorKind::DrmDev(format!("{:?}", self.context.head().head()))
})?;
// then check for every connector which encoders it does support
let encoders = con_info
.encoders()
.iter()
.map(|encoder| {
encoder::Info::load_from_device(self.context.head().head(), *encoder)
.map_err(DrmError::from)
encoder::Info::load_from_device(self.context.head().head(), *encoder).chain_err(|| {
ErrorKind::DrmDev(format!("{:?}", self.context.head().head()))
})
})
.collect::<Result<Vec<encoder::Info>, DrmError>>()?;
.collect::<Result<Vec<encoder::Info>>>()?;
// and if any encoder supports the selected crtc
if !encoders.iter().any(|encoder| encoder.supports_crtc(crtc)) {
return Err(DrmError::Crtc(CrtcError::NoSuitableEncoder));
bail!(ErrorKind::NoSuitableEncoder(con_info, crtc))
}
}

View File

@ -10,11 +10,11 @@ use super::GraphicsBackend;
use gbm::{AsRaw, Device as GbmDevice, Surface as GbmSurface};
use libloading::Library;
use nix::{c_int, c_void};
use rental::TryNewError;
use slog;
use std::error::{self, Error};
use std::error;
use std::ffi::{CStr, CString};
use std::fmt;
use std::io;
use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, DerefMut};
@ -74,7 +74,7 @@ pub enum NativeSurfacePtr {
}
/// Enumerates all supported backends
#[derive(Clone, Copy, PartialEq)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum NativeType {
/// X11 window & surface
X11,
@ -82,66 +82,77 @@ pub enum NativeType {
Wayland,
/// Gbm surface
Gbm,
/// Unknown
Unknown,
}
/// Error that can happen while creating an `EGLContext` or `EGLSurface`
#[derive(Debug)]
pub enum CreationError {
/// I/O error from the underlying system
IoError(io::Error),
/// Operating System error
OsError(String),
/// The requested OpenGl version is not supported by the graphics system
OpenGlVersionNotSupported,
/// There is no pixel format available that fulfills all requirements
NoAvailablePixelFormat,
/// Surface creation from an unsupport combination
///
/// E.g creating a surface from an X11 window on a context created from a wayland display
NonMatchingSurfaceType,
/// Context creation is not supported on this system
NotSupported,
}
error_chain! {
errors {
#[doc = "The requested OpenGL version is not supported"]
OpenGlVersionNotSupported(version: (u8, u8)) {
description("The requested OpenGL version is not supported."),
display("The requested OpenGL version {:?} is not supported.", version),
}
impl From<io::Error> for CreationError {
fn from(err: io::Error) -> Self {
CreationError::IoError(err)
#[doc = "The EGL implementation does not support creating OpenGL ES contexts"]
OpenGlesNotSupported {
description("The EGL implementation does not support creating OpenGL ES contexts")
}
#[doc = "No available pixel format matched the criteria"]
NoAvailablePixelFormat {
description("No available pixel format matched the criteria.")
}
#[doc = "Surface type does not match the context type"]
NonMatchingSurfaceType(context: NativeType, surface: NativeType) {
description("Surface type does not match the context type."),
display("Surface type '{:?}' does not match the context type '{:?}'.", surface, context),
}
#[doc = "Context creation is not supported on the current window system"]
NotSupported {
description("Context creation is not supported on the current window system.")
}
#[doc = "Loading libEGL failed"]
LoadingEGLFailed {
description("Loading libEGL failed"),
}
#[doc = "EGL was unable to optain a valid EGL Display"]
DisplayNotSupported {
description("EGL was unable to optain a valid EGL Display")
}
#[doc = "eglInitialize returned an error"]
InitFailed {
description("Failed to initialize EGL")
}
#[doc = "Failed to configure the EGL context"]
ConfigFailed {
description("Failed to configure the EGL context")
}
#[doc = "Context creation failed as one or more requirements could not be met. Try removing some gl attributes or pixel format requirements"]
CreationFailed {
description("Context creation failed as one or more requirements could not be met. Try removing some gl attributes or pixel format requirements")
}
#[doc = "eglCreateWindowSurface failed"]
SurfaceCreationFailed {
description("Failed to create a new EGLSurface")
}
#[doc = "The reason of failure could not be determined"]
Unknown(err_no: u32)
}
}
impl fmt::Display for CreationError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str(self.description())?;
if let Some(err) = error::Error::cause(self) {
write!(formatter, ": {}", err)?;
}
Ok(())
}
}
impl error::Error for CreationError {
fn description(&self) -> &str {
match *self {
CreationError::IoError(ref err) => err.description(),
CreationError::OsError(ref text) => text,
CreationError::OpenGlVersionNotSupported => {
"The requested OpenGL version is not \
supported."
}
CreationError::NoAvailablePixelFormat => {
"Couldn't find any pixel format that matches \
the criterias."
}
CreationError::NonMatchingSurfaceType => "Surface type does not match the context type.",
CreationError::NotSupported => "Context creation is not supported on the current window system",
}
}
fn cause(&self) -> Option<&error::Error> {
match *self {
CreationError::IoError(ref err) => Some(err),
_ => None,
}
impl<H> From<TryNewError<Error, H>> for Error {
fn from(err: TryNewError<Error, H>) -> Error {
err.0
}
}
@ -155,20 +166,22 @@ pub unsafe trait NativeSurface {
type Keep: 'static;
/// Return a surface for the given type if possible
fn surface(&self, backend: NativeType) -> Result<(NativeSurfacePtr, Self::Keep), CreationError>;
fn surface(&self, backend: NativeType) -> Result<(NativeSurfacePtr, Self::Keep)>;
}
#[cfg(feature = "backend_winit")]
unsafe impl NativeSurface for WinitWindow {
type Keep = Option<wegl::WlEglSurface>;
fn surface(&self, backend_type: NativeType)
-> Result<(NativeSurfacePtr, Option<wegl::WlEglSurface>), CreationError> {
fn surface(&self, backend_type: NativeType) -> Result<(NativeSurfacePtr, Option<wegl::WlEglSurface>)> {
match backend_type {
NativeType::X11 => if let Some(window) = self.get_xlib_window() {
Ok((NativeSurfacePtr::X11(window), None))
} else {
return Err(CreationError::NonMatchingSurfaceType);
bail!(ErrorKind::NonMatchingSurfaceType(
NativeType::Wayland,
NativeType::X11
));
},
NativeType::Wayland => if let Some(surface) = self.get_wayland_surface() {
let (w, h) = self.get_inner_size().unwrap();
@ -179,9 +192,12 @@ unsafe impl NativeSurface for WinitWindow {
Some(egl_surface),
))
} else {
return Err(CreationError::NonMatchingSurfaceType);
bail!(ErrorKind::NonMatchingSurfaceType(
NativeType::X11,
NativeType::Wayland
));
},
_ => Err(CreationError::NonMatchingSurfaceType),
x => bail!(ErrorKind::NonMatchingSurfaceType(NativeType::Unknown, x)),
}
}
}
@ -190,18 +206,18 @@ unsafe impl NativeSurface for WinitWindow {
unsafe impl<'a, T: 'static> NativeSurface for GbmSurface<'a, T> {
type Keep = ();
fn surface(&self, backend: NativeType) -> Result<(NativeSurfacePtr, Self::Keep), CreationError> {
fn surface(&self, backend: NativeType) -> Result<(NativeSurfacePtr, Self::Keep)> {
match backend {
NativeType::Gbm => Ok((NativeSurfacePtr::Gbm(self.as_raw() as *const _), ())),
_ => Err(CreationError::NonMatchingSurfaceType),
x => bail!(ErrorKind::NonMatchingSurfaceType(NativeType::Gbm, x)),
}
}
}
unsafe impl NativeSurface for () {
type Keep = ();
fn surface(&self, _backend: NativeType) -> Result<(NativeSurfacePtr, ()), CreationError> {
Err(CreationError::NotSupported)
fn surface(&self, _backend: NativeType) -> Result<(NativeSurfacePtr, ())> {
bail!(ErrorKind::NotSupported)
}
}
@ -225,7 +241,7 @@ impl<'a> EGLContext<'a, ()> {
#[cfg(feature = "backend_winit")]
pub fn new_from_winit<L>(window: &'a WinitWindow, attributes: GlAttributes,
reqs: PixelFormatRequirements, logger: L)
-> Result<EGLContext<'a, WinitWindow>, CreationError>
-> Result<EGLContext<'a, WinitWindow>>
where
L: Into<Option<::slog::Logger>>,
{
@ -242,7 +258,7 @@ impl<'a> EGLContext<'a, ()> {
NativeDisplayPtr::Wayland(display)
} else {
error!(log, "Window is backed by an unsupported graphics framework");
return Err(CreationError::NotSupported);
bail!(ErrorKind::NotSupported)
},
attributes,
reqs,
@ -255,7 +271,7 @@ impl<'a> EGLContext<'a, ()> {
#[cfg(feature = "backend_drm")]
pub fn new_from_gbm<L, U: 'static>(gbm: &'a GbmDevice<'a>, attributes: GlAttributes,
reqs: PixelFormatRequirements, logger: L)
-> Result<EGLContext<'a, GbmSurface<'a, U>>, CreationError>
-> Result<EGLContext<'a, GbmSurface<'a, U>>>
where
L: Into<Option<::slog::Logger>>,
{
@ -275,7 +291,7 @@ impl<'a> EGLContext<'a, ()> {
impl<'a, T: NativeSurface> EGLContext<'a, T> {
unsafe fn new(native: NativeDisplayPtr, mut attributes: GlAttributes, reqs: PixelFormatRequirements,
log: ::slog::Logger)
-> Result<EGLContext<'a, T>, CreationError>
-> Result<EGLContext<'a, T>>
where
T: NativeSurface,
{
@ -297,12 +313,12 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
}
}
}
Some((1, _)) => {
Some((1, x)) => {
error!(
log,
"OpenGLES 1.* is not supported by the EGL renderer backend"
);
return Err(CreationError::OpenGlVersionNotSupported);
bail!(ErrorKind::OpenGlVersionNotSupported((1, x)));
}
Some(version) => {
error!(
@ -310,12 +326,12 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
"OpenGLES {:?} is unknown and not supported by the EGL renderer backend",
version
);
return Err(CreationError::OpenGlVersionNotSupported);
bail!(ErrorKind::OpenGlVersionNotSupported(version));
}
};
trace!(log, "Loading libEGL");
let lib = Library::new("libEGL.so.1")?;
let lib = Library::new("libEGL.so.1").chain_err(|| ErrorKind::LoadingEGLFailed)?;
let egl = ffi::egl::Egl::load_with(|sym| {
let name = CString::new(sym).unwrap();
let symbol = lib.get::<*mut c_void>(name.as_bytes());
@ -418,6 +434,7 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
if display == ffi::egl::NO_DISPLAY {
error!(log, "EGL Display is not valid");
bail!(ErrorKind::DisplayNotSupported);
}
let egl_version = {
@ -425,7 +442,7 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
let mut minor: ffi::egl::types::EGLint = mem::uninitialized();
if egl.Initialize(display, &mut major, &mut minor) == 0 {
return Err(CreationError::OsError(String::from("eglInitialize failed")));
bail!(ErrorKind::InitFailed);
}
info!(log, "EGL Initialized");
@ -451,7 +468,7 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
log,
"OpenGLES not supported by the underlying EGL implementation"
);
return Err(CreationError::OpenGlVersionNotSupported);
bail!(ErrorKind::OpenGlesNotSupported);
}
let descriptor = {
@ -477,7 +494,7 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
log,
"OpenglES 3.* is not supported on EGL Versions lower then 1.3"
);
return Err(CreationError::NoAvailablePixelFormat);
bail!(ErrorKind::NoAvailablePixelFormat);
}
trace!(log, "Setting RENDERABLE_TYPE to OPENGL_ES3");
out.push(ffi::egl::RENDERABLE_TYPE as c_int);
@ -492,7 +509,7 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
log,
"OpenglES 2.* is not supported on EGL Versions lower then 1.3"
);
return Err(CreationError::NoAvailablePixelFormat);
bail!(ErrorKind::NoAvailablePixelFormat);
}
trace!(log, "Setting RENDERABLE_TYPE to OPENGL_ES2");
out.push(ffi::egl::RENDERABLE_TYPE as c_int);
@ -561,7 +578,7 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
if reqs.stereoscopy {
error!(log, "Stereoscopy is currently unsupported (sorry!)");
return Err(CreationError::NoAvailablePixelFormat);
bail!(ErrorKind::NoAvailablePixelFormat);
}
out.push(ffi::egl::NONE as c_int);
@ -579,13 +596,11 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
&mut num_configs,
) == 0
{
return Err(CreationError::OsError(
String::from("eglChooseConfig failed"),
));
bail!(ErrorKind::ConfigFailed);
}
if num_configs == 0 {
error!(log, "No matching color format found");
return Err(CreationError::NoAvailablePixelFormat);
bail!(ErrorKind::NoAvailablePixelFormat);
}
// analyzing each config
@ -596,7 +611,7 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
let res = $egl.GetConfigAttrib($display, $config,
$attr as ffi::egl::types::EGLint, &mut value);
if res == 0 {
return Err(CreationError::OsError(String::from("eglGetConfigAttrib failed")));
bail!(ErrorKind::ConfigFailed);
}
value
}
@ -654,14 +669,8 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
if context.is_null() {
match egl.GetError() as u32 {
ffi::egl::BAD_ATTRIBUTE => {
error!(
log,
"Context creation failed as one or more requirements could not be met. Try removing some gl attributes or pixel format requirements"
);
return Err(CreationError::OpenGlVersionNotSupported);
}
e => panic!("eglCreateContext failed: 0x{:x}", e),
ffi::egl::BAD_ATTRIBUTE => bail!(ErrorKind::CreationFailed),
err_no => bail!(ErrorKind::Unknown(err_no)),
}
}
debug!(log, "EGL context successfully created");
@ -709,7 +718,7 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
}
/// Creates a surface bound to the given egl context for rendering
pub fn create_surface<'b>(&'a self, native: &'b T) -> Result<EGLSurface<'a, 'b, T>, CreationError> {
pub fn create_surface<'b>(&'a self, native: &'b T) -> Result<EGLSurface<'a, 'b, T>> {
trace!(self.logger, "Creating EGL window surface...");
let (surface, keep) = native.surface(self.backend_type)?;
@ -728,9 +737,7 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
};
if egl_surface.is_null() {
return Err(CreationError::OsError(
String::from("eglCreateWindowSurface failed"),
));
bail!(ErrorKind::SurfaceCreationFailed);
}
debug!(self.logger, "EGL surface successfully created");
@ -801,7 +808,7 @@ impl<'a, 'b, T: NativeSurface> DerefMut for EGLSurface<'a, 'b, T> {
impl<'context, 'surface, T: NativeSurface> EGLSurface<'context, 'surface, T> {
/// Swaps buffers at the end of a frame.
pub fn swap_buffers(&self) -> Result<(), SwapBuffersError> {
pub fn swap_buffers(&self) -> ::std::result::Result<(), SwapBuffersError> {
let ret = unsafe {
self.context
.egl
@ -824,7 +831,7 @@ impl<'context, 'surface, T: NativeSurface> EGLSurface<'context, 'surface, T> {
///
/// This function is marked unsafe, because the context cannot be made current
/// on multiple threads.
pub unsafe fn make_current(&self) -> Result<(), SwapBuffersError> {
pub unsafe fn make_current(&self) -> ::std::result::Result<(), SwapBuffersError> {
let ret = self.context.egl.MakeCurrent(
self.context.display as *const _,
self.surface as *const _,
@ -879,7 +886,8 @@ pub enum SwapBuffersError {
}
impl fmt::Display for SwapBuffersError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> {
use std::error::Error;
write!(formatter, "{}", self.description())
}
}
@ -983,7 +991,7 @@ pub struct PixelFormat {
/// and can be used to render upon
pub trait EGLGraphicsBackend: GraphicsBackend {
/// Swaps buffers at the end of a frame.
fn swap_buffers(&self) -> Result<(), SwapBuffersError>;
fn swap_buffers(&self) -> ::std::result::Result<(), SwapBuffersError>;
/// Returns the address of an OpenGL function.
///
@ -1006,7 +1014,7 @@ pub trait EGLGraphicsBackend: GraphicsBackend {
///
/// This function is marked unsafe, because the context cannot be made current
/// on multiple threads.
unsafe fn make_current(&self) -> Result<(), SwapBuffersError>;
unsafe fn make_current(&self) -> ::std::result::Result<(), SwapBuffersError>;
/// Returns the pixel format of the main framebuffer of the context.
fn get_pixel_format(&self) -> PixelFormat;

View File

@ -2,21 +2,20 @@
use backend::{SeatInternal, TouchSlotInternal};
use backend::graphics::GraphicsBackend;
use backend::graphics::egl::{CreationError, EGLContext, EGLGraphicsBackend, GlAttributes, PixelFormat,
use backend::graphics::egl::{self, EGLContext, EGLGraphicsBackend, GlAttributes, PixelFormat,
PixelFormatRequirements, SwapBuffersError};
use backend::input::{Axis, AxisSource, Event as BackendEvent, InputBackend, InputHandler, KeyState,
KeyboardKeyEvent, MouseButton, MouseButtonState, PointerAxisEvent, PointerButtonEvent,
PointerMotionAbsoluteEvent, Seat, SeatCapabilities, TouchCancelEvent, TouchDownEvent,
TouchMotionEvent, TouchSlot, TouchUpEvent, UnusedEvent};
use nix::c_void;
use rental::TryNewError;
use std::cmp;
use std::error::Error;
use std::error;
use std::fmt;
use std::rc::Rc;
use winit::{CreationError as WinitCreationError, ElementState, Event, EventsLoop, KeyboardInput,
MouseButton as WinitMouseButton, MouseCursor, MouseScrollDelta, Touch, TouchPhase,
WindowBuilder, WindowEvent};
use winit::{ElementState, Event, EventsLoop, KeyboardInput, MouseButton as WinitMouseButton, MouseCursor,
MouseScrollDelta, Touch, TouchPhase, WindowBuilder, WindowEvent};
rental! {
mod rental {
@ -40,6 +39,24 @@ rental! {
use self::rental::{Window, EGL};
error_chain! {
errors {
#[doc = "Failed to initialize a window"]
InitFailed {
description("Failed to initialize a window")
}
}
links {
EGL(egl::Error, egl::ErrorKind) #[doc = "EGL error"];
}
}
impl<H> From<TryNewError<Error, H>> for Error {
fn from(err: TryNewError<Error, H>) -> Error {
err.0
}
}
/// Window with an active EGL Context created by `winit`. Implements the
/// `EGLGraphicsBackend` graphics backend trait
pub struct WinitGraphicsBackend {
@ -64,7 +81,7 @@ pub struct WinitInputBackend {
/// Create a new `WinitGraphicsBackend`, which implements the `EGLGraphicsBackend`
/// graphics backend trait and a corresponding `WinitInputBackend`, which implements
/// the `InputBackend` trait
pub fn init<L>(logger: L) -> Result<(WinitGraphicsBackend, WinitInputBackend), CreationError>
pub fn init<L>(logger: L) -> Result<(WinitGraphicsBackend, WinitInputBackend)>
where
L: Into<Option<::slog::Logger>>,
{
@ -81,7 +98,7 @@ where
/// graphics backend trait, from a given `WindowBuilder` struct and a corresponding
/// `WinitInputBackend`, which implements the `InputBackend` trait
pub fn init_from_builder<L>(builder: WindowBuilder, logger: L)
-> Result<(WinitGraphicsBackend, WinitInputBackend), CreationError>
-> Result<(WinitGraphicsBackend, WinitInputBackend)>
where
L: Into<Option<::slog::Logger>>,
{
@ -101,9 +118,8 @@ where
/// graphics backend trait, from a given `WindowBuilder` struct, as well as given
/// `GlAttributes` for further customization of the rendering pipeline and a
/// corresponding `WinitInputBackend`, which implements the `InputBackend` trait.
pub fn init_from_builder_with_gl_attr<L>(
builder: WindowBuilder, attributes: GlAttributes, logger: L)
-> Result<(WinitGraphicsBackend, WinitInputBackend), CreationError>
pub fn init_from_builder_with_gl_attr<L>(builder: WindowBuilder, attributes: GlAttributes, logger: L)
-> Result<(WinitGraphicsBackend, WinitInputBackend)>
where
L: Into<Option<::slog::Logger>>,
{
@ -111,11 +127,13 @@ where
info!(log, "Initializing a winit backend");
let events_loop = EventsLoop::new();
let winit_window = builder.build(&events_loop)?;
let winit_window = builder
.build(&events_loop)
.chain_err(|| ErrorKind::InitFailed)?;
debug!(log, "Window created");
let window = match Window::try_new(Box::new(winit_window), |window| {
match EGL::try_new(
let window = Rc::new(Window::try_new(Box::new(winit_window), |window| {
EGL::try_new(
Box::new(match EGLContext::new_from_winit(
&*window,
attributes,
@ -128,20 +146,12 @@ where
log.clone(),
) {
Ok(context) => context,
Err(err) => {
error!(log, "EGLContext creation failed:\n {}", err);
return Err(err);
}
Err(err) => bail!(err),
}),
|context| context.create_surface(window),
) {
Ok(x) => Ok(x),
Err(::rental::TryNewError(err, _)) => return Err(err),
}
}) {
Ok(x) => Rc::new(x),
Err(::rental::TryNewError(err, _)) => return Err(err),
};
).map_err(egl::Error::from)
.map_err(Error::from)
})?);
Ok((
WinitGraphicsBackend {
@ -172,12 +182,13 @@ impl GraphicsBackend for WinitGraphicsBackend {
type CursorFormat = MouseCursor;
type Error = ();
fn set_cursor_position(&self, x: u32, y: u32) -> Result<(), ()> {
fn set_cursor_position(&self, x: u32, y: u32) -> ::std::result::Result<(), ()> {
debug!(self.logger, "Setting cursor position to {:?}", (x, y));
self.window.head().set_cursor_position(x as i32, y as i32)
}
fn set_cursor_representation(&self, cursor: Self::CursorFormat, _hotspot: (u32, u32)) -> Result<(), ()> {
fn set_cursor_representation(&self, cursor: Self::CursorFormat, _hotspot: (u32, u32))
-> ::std::result::Result<(), ()> {
// Cannot log this one, as `CursorFormat` is not `Debug` and should not be
debug!(self.logger, "Changing cursor representation");
self.window.head().set_cursor(cursor);
@ -186,7 +197,7 @@ impl GraphicsBackend for WinitGraphicsBackend {
}
impl EGLGraphicsBackend for WinitGraphicsBackend {
fn swap_buffers(&self) -> Result<(), SwapBuffersError> {
fn swap_buffers(&self) -> ::std::result::Result<(), SwapBuffersError> {
trace!(self.logger, "Swapping buffers");
self.window
.rent(|egl| egl.rent(|surface| surface.swap_buffers()))
@ -208,7 +219,7 @@ impl EGLGraphicsBackend for WinitGraphicsBackend {
self.window.rent(|egl| egl.head().is_current())
}
unsafe fn make_current(&self) -> Result<(), SwapBuffersError> {
unsafe fn make_current(&self) -> ::std::result::Result<(), SwapBuffersError> {
debug!(self.logger, "Setting EGL context to be the current context");
self.window
.rent(|egl| egl.rent(|surface| surface.make_current()))
@ -228,7 +239,7 @@ pub enum WinitInputError {
WindowClosed,
}
impl Error for WinitInputError {
impl error::Error for WinitInputError {
fn description(&self) -> &str {
match *self {
WinitInputError::WindowClosed => "Glutin Window was closed",
@ -238,6 +249,7 @@ impl Error for WinitInputError {
impl fmt::Display for WinitInputError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use std::error::Error;
write!(f, "{}", self.description())
}
}
@ -576,7 +588,7 @@ impl InputBackend for WinitInputBackend {
///
/// The linked `WinitGraphicsBackend` will error with a lost Context and should
/// not be used anymore as well.
fn dispatch_new_events(&mut self) -> Result<(), WinitInputError> {
fn dispatch_new_events(&mut self) -> ::std::result::Result<(), WinitInputError> {
let mut closed = false;
{
@ -831,12 +843,3 @@ impl From<ElementState> for MouseButtonState {
}
}
}
impl From<WinitCreationError> for CreationError {
fn from(error: WinitCreationError) -> Self {
match error {
WinitCreationError::OsError(x) => CreationError::OsError(x),
WinitCreationError::NotSupported => CreationError::NotSupported,
}
}
}

View File

@ -6,6 +6,8 @@
#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
// `error_chain!` can recurse deeply
#![recursion_limit = "1024"]
extern crate image;
extern crate nix;
@ -36,6 +38,9 @@ extern crate glium;
extern crate slog;
extern crate slog_stdlog;
#[macro_use]
extern crate error_chain;
pub mod backend;
pub mod compositor;
pub mod shm;