Add seperate GL module

- Move parts of glium & egl module into own module
- Add raw GL loader as an alternative
This commit is contained in:
Victor Brekenfeld 2018-11-21 09:21:12 +01:00
parent c9e67cdfef
commit ac0dc42e9e
4 changed files with 89 additions and 20 deletions

View File

@ -0,0 +1,76 @@
use nix::libc::c_void;
use super::SwapBuffersError;
#[cfg_attr(feature = "cargo-clippy", allow(clippy))]
#[allow(missing_docs)]
pub(crate) mod ffi {
include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs"));
}
pub use self::ffi::Gles2;
/// Describes the pixel format of the main framebuffer
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct PixelFormat {
/// is the format hardware accelerated
pub hardware_accelerated: bool,
/// number of bits used for colors
pub color_bits: u8,
/// number of bits used for alpha channel
pub alpha_bits: u8,
/// number of bits used for depth channel
pub depth_bits: u8,
/// number of bits used for stencil buffer
pub stencil_bits: u8,
/// is stereoscopy enabled
pub stereoscopy: bool,
/// is double buffering enabled
pub double_buffer: bool,
/// number of samples used for multisampling if enabled
pub multisampling: Option<u16>,
/// is srgb enabled
pub srgb: bool,
}
/// Trait that describes objects that have an OpenGL context
/// and can be used to render upon
pub trait GLGraphicsBackend {
/// Swaps buffers at the end of a frame.
fn swap_buffers(&self) -> Result<(), SwapBuffersError>;
/// Returns the address of an OpenGL function.
///
/// Supposes that the context has been made current before this function is called.
unsafe fn get_proc_address(&self, symbol: &str) -> *const c_void;
/// Returns the dimensions of the window, or screen, etc in points.
///
/// That are the scaled pixels of the underlying graphics backend.
/// For nested compositors this will respect the scaling of the root compositor.
/// For drawing directly onto hardware this unit will be equal to actual pixels.
fn get_framebuffer_dimensions(&self) -> (u32, u32);
/// Returns true if the OpenGL context is the current one in the thread.
fn is_current(&self) -> bool;
/// Makes the OpenGL context the current context in the current thread.
///
/// # Unsafety
///
/// This function is marked unsafe, because the context cannot be made current
/// on multiple threads.
unsafe fn make_current(&self) -> Result<(), SwapBuffersError>;
/// Returns the pixel format of the main framebuffer of the context.
fn get_pixel_format(&self) -> PixelFormat;
}
/// Loads a Raw GLES Interface for a given `GLGraphicsBackend`
///
/// This remains valid as long as the underlying `GLGraphicsBackend` is alive
/// and may only be used in combination with the backend. Using this with any
/// other gl context may cause undefined behavior.
pub fn load_raw_gl<B: GLGraphicsBackend>(backend: &B) -> Gles2 {
Gles2::load_with(|s| unsafe { backend.get_proc_address(s) as *const _ })
}

View File

@ -1,9 +1,8 @@
//! Glium compatibility module //! Glium compatibility module
use backend::graphics::egl::{ use backend::graphics::{
error::Result as EGLResult, gl::GLGraphicsBackend,
wayland::{EGLDisplay, EGLWaylandExtensions}, SwapBuffersError,
EGLGraphicsBackend, SwapBuffersError,
}; };
use glium::{ use glium::{
backend::{Backend, Context, Facade}, backend::{Backend, Context, Facade},
@ -15,7 +14,6 @@ use std::{
os::raw::c_void, os::raw::c_void,
rc::Rc, rc::Rc,
}; };
use wayland_server::Display;
impl From<SwapBuffersError> for GliumSwapBuffersError { impl From<SwapBuffersError> for GliumSwapBuffersError {
fn from(error: SwapBuffersError) -> Self { fn from(error: SwapBuffersError) -> Self {
@ -28,14 +26,14 @@ impl From<SwapBuffersError> for GliumSwapBuffersError {
} }
/// Wrapper to expose `Glium` compatibility /// Wrapper to expose `Glium` compatibility
pub struct GliumGraphicsBackend<T: EGLGraphicsBackend> { pub struct GliumGraphicsBackend<T: GLGraphicsBackend> {
context: Rc<Context>, context: Rc<Context>,
backend: Rc<InternalBackend<T>>, backend: Rc<InternalBackend<T>>,
} }
struct InternalBackend<T: EGLGraphicsBackend>(RefCell<T>); struct InternalBackend<T: GLGraphicsBackend>(RefCell<T>);
impl<T: EGLGraphicsBackend + 'static> GliumGraphicsBackend<T> { impl<T: GLGraphicsBackend + 'static> GliumGraphicsBackend<T> {
fn new(backend: T) -> GliumGraphicsBackend<T> { fn new(backend: T) -> GliumGraphicsBackend<T> {
let internal = Rc::new(InternalBackend(RefCell::new(backend))); let internal = Rc::new(InternalBackend(RefCell::new(backend)));
@ -79,27 +77,19 @@ impl<T: EGLGraphicsBackend + 'static> GliumGraphicsBackend<T> {
} }
} }
impl<T: EGLGraphicsBackend> Facade for GliumGraphicsBackend<T> { impl<T: GLGraphicsBackend> Facade for GliumGraphicsBackend<T> {
fn get_context(&self) -> &Rc<Context> { fn get_context(&self) -> &Rc<Context> {
&self.context &self.context
} }
} }
impl<T: EGLGraphicsBackend + 'static> From<T> for GliumGraphicsBackend<T> { impl<T: GLGraphicsBackend + 'static> From<T> for GliumGraphicsBackend<T> {
fn from(backend: T) -> Self { fn from(backend: T) -> Self {
GliumGraphicsBackend::new(backend) GliumGraphicsBackend::new(backend)
} }
} }
impl<T: EGLGraphicsBackend + EGLWaylandExtensions + 'static> EGLWaylandExtensions unsafe impl<T: GLGraphicsBackend> Backend for InternalBackend<T> {
for GliumGraphicsBackend<T>
{
fn bind_wl_display(&self, display: &Display) -> EGLResult<EGLDisplay> {
(*self.backend).0.borrow().bind_wl_display(display)
}
}
unsafe impl<T: EGLGraphicsBackend> Backend for InternalBackend<T> {
fn swap_buffers(&self) -> Result<(), GliumSwapBuffersError> { fn swap_buffers(&self) -> Result<(), GliumSwapBuffersError> {
self.0.borrow().swap_buffers().map_err(Into::into) self.0.borrow().swap_buffers().map_err(Into::into)
} }

View File

@ -35,7 +35,8 @@ pub trait GraphicsBackend {
) -> Result<(), Self::Error>; ) -> Result<(), Self::Error>;
} }
pub mod egl; #[cfg(feature = "renderer_gl")]
pub mod gl;
#[cfg(feature = "renderer_glium")] #[cfg(feature = "renderer_glium")]
pub mod glium; pub mod glium;
pub mod software; pub mod software;

View File

@ -19,6 +19,8 @@ pub mod input;
#[cfg(feature = "backend_drm")] #[cfg(feature = "backend_drm")]
pub mod drm; pub mod drm;
#[cfg(feature = "backend_egl")]
pub mod egl;
#[cfg(feature = "backend_libinput")] #[cfg(feature = "backend_libinput")]
pub mod libinput; pub mod libinput;
#[cfg(feature = "backend_session")] #[cfg(feature = "backend_session")]