Add documentation for the egl buffer features
This commit is contained in:
parent
efaadb8882
commit
aaa68b1cce
|
@ -27,7 +27,6 @@ use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
||||||
use smithay::backend::graphics::egl::wayland::{Format, EGLDisplay, EGLWaylandExtensions};
|
use smithay::backend::graphics::egl::wayland::{Format, EGLDisplay, EGLWaylandExtensions};
|
||||||
use smithay::wayland::compositor::{CompositorToken, SubsurfaceRole, TraversalAction};
|
use smithay::wayland::compositor::{CompositorToken, SubsurfaceRole, TraversalAction};
|
||||||
use smithay::wayland::compositor::roles::Role;
|
use smithay::wayland::compositor::roles::Role;
|
||||||
use smithay::wayland::shell::ShellState;
|
|
||||||
use smithay::wayland::shm::init_shm_global;
|
use smithay::wayland::shm::init_shm_global;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
|
@ -35,7 +34,6 @@ use std::os::unix::io::RawFd;
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use wayland_server::{StateToken};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Card(File);
|
pub struct Card(File);
|
||||||
|
@ -125,7 +123,7 @@ fn main() {
|
||||||
|
|
||||||
init_shm_global(&mut event_loop, vec![], log.clone());
|
init_shm_global(&mut event_loop, vec![], log.clone());
|
||||||
|
|
||||||
let (compositor_token, shell_state_token, window_map) = init_shell(&mut event_loop, log.clone(), egl_display.clone());
|
let (compositor_token, _shell_state_token, window_map) = init_shell(&mut event_loop, log.clone(), egl_display.clone());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a listening socket:
|
* Add a listening socket:
|
||||||
|
@ -141,7 +139,6 @@ fn main() {
|
||||||
&mut event_loop,
|
&mut event_loop,
|
||||||
device_token,
|
device_token,
|
||||||
DrmHandlerImpl {
|
DrmHandlerImpl {
|
||||||
shell_state_token,
|
|
||||||
compositor_token,
|
compositor_token,
|
||||||
window_map: window_map.clone(),
|
window_map: window_map.clone(),
|
||||||
drawer: renderer,
|
drawer: renderer,
|
||||||
|
@ -158,7 +155,6 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DrmHandlerImpl {
|
pub struct DrmHandlerImpl {
|
||||||
shell_state_token: StateToken<ShellState<SurfaceData, Roles, Rc<RefCell<Option<EGLDisplay>>>, ()>>,
|
|
||||||
compositor_token: CompositorToken<SurfaceData, Roles, Rc<RefCell<Option<EGLDisplay>>>>,
|
compositor_token: CompositorToken<SurfaceData, Roles, Rc<RefCell<Option<EGLDisplay>>>>,
|
||||||
window_map: Rc<RefCell<MyWindowMap>>,
|
window_map: Rc<RefCell<MyWindowMap>>,
|
||||||
drawer: GliumDrawer<DrmBackend<Card>>,
|
drawer: GliumDrawer<DrmBackend<Card>>,
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
use glium;
|
use glium;
|
||||||
use glium::{Frame, Surface, GlObject};
|
use glium::{Frame, Surface, GlObject};
|
||||||
use glium::backend::Facade;
|
|
||||||
use glium::index::PrimitiveType;
|
use glium::index::PrimitiveType;
|
||||||
use glium::texture::{MipmapsOption, UncompressedFloatFormat, Texture2d};
|
use glium::texture::{MipmapsOption, UncompressedFloatFormat, Texture2d};
|
||||||
use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
||||||
use smithay::backend::graphics::egl::error::Result as EGLResult;
|
use smithay::backend::graphics::egl::error::Result as EGLResult;
|
||||||
use smithay::backend::graphics::egl::wayland::{Format, EGLImages, EGLDisplay, EGLWaylandExtensions, BufferAccessError};
|
use smithay::backend::graphics::egl::wayland::{Format, EGLImages, EGLDisplay, EGLWaylandExtensions};
|
||||||
use smithay::backend::graphics::glium::GliumGraphicsBackend;
|
use smithay::backend::graphics::glium::GliumGraphicsBackend;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use wayland_server::Display;
|
use wayland_server::Display;
|
||||||
use wayland_server::protocol::wl_buffer::WlBuffer;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
|
|
|
@ -19,7 +19,6 @@ extern crate ctrlc;
|
||||||
|
|
||||||
mod helpers;
|
mod helpers;
|
||||||
|
|
||||||
use drm::Device as BasicDevice;
|
|
||||||
use drm::control::{Device as ControlDevice, ResourceInfo};
|
use drm::control::{Device as ControlDevice, ResourceInfo};
|
||||||
use drm::control::connector::{Info as ConnectorInfo, State as ConnectorState};
|
use drm::control::connector::{Info as ConnectorInfo, State as ConnectorState};
|
||||||
use drm::control::encoder::Info as EncoderInfo;
|
use drm::control::encoder::Info as EncoderInfo;
|
||||||
|
@ -45,7 +44,6 @@ use smithay::wayland::compositor::{CompositorToken, SubsurfaceRole, TraversalAct
|
||||||
use smithay::wayland::compositor::roles::Role;
|
use smithay::wayland::compositor::roles::Role;
|
||||||
use smithay::wayland::output::{Mode, Output, PhysicalProperties};
|
use smithay::wayland::output::{Mode, Output, PhysicalProperties};
|
||||||
use smithay::wayland::seat::{KeyboardHandle, PointerHandle, Seat};
|
use smithay::wayland::seat::{KeyboardHandle, PointerHandle, Seat};
|
||||||
use smithay::wayland::shell::ShellState;
|
|
||||||
use smithay::wayland::shm::init_shm_global;
|
use smithay::wayland::shm::init_shm_global;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -56,7 +54,6 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
|
||||||
use xkbcommon::xkb::keysyms as xkb;
|
use xkbcommon::xkb::keysyms as xkb;
|
||||||
use wayland_server::{Display, StateToken, StateProxy};
|
use wayland_server::{Display, StateToken, StateProxy};
|
||||||
use wayland_server::protocol::{wl_output, wl_pointer};
|
use wayland_server::protocol::{wl_output, wl_pointer};
|
||||||
|
@ -199,7 +196,7 @@ fn main() {
|
||||||
*/
|
*/
|
||||||
init_shm_global(&mut event_loop, vec![], log.clone());
|
init_shm_global(&mut event_loop, vec![], log.clone());
|
||||||
|
|
||||||
let (compositor_token, shell_state_token, window_map) = init_shell(&mut event_loop, log.clone(), active_egl_context.clone());
|
let (compositor_token, _shell_state_token, window_map) = init_shell(&mut event_loop, log.clone(), active_egl_context.clone());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize session on the current tty
|
* Initialize session on the current tty
|
||||||
|
@ -226,7 +223,6 @@ fn main() {
|
||||||
let bytes = include_bytes!("resources/cursor2.rgba");
|
let bytes = include_bytes!("resources/cursor2.rgba");
|
||||||
let udev_token
|
let udev_token
|
||||||
= UdevBackend::new(&mut event_loop, &context, session.clone(), UdevHandlerImpl {
|
= UdevBackend::new(&mut event_loop, &context, session.clone(), UdevHandlerImpl {
|
||||||
shell_state_token,
|
|
||||||
compositor_token,
|
compositor_token,
|
||||||
active_egl_context,
|
active_egl_context,
|
||||||
backends: HashMap::new(),
|
backends: HashMap::new(),
|
||||||
|
@ -307,9 +303,12 @@ fn main() {
|
||||||
let udev_event_source = udev_backend_bind(&mut event_loop, udev_token).unwrap();
|
let udev_event_source = udev_backend_bind(&mut event_loop, udev_token).unwrap();
|
||||||
|
|
||||||
while running.load(Ordering::SeqCst) {
|
while running.load(Ordering::SeqCst) {
|
||||||
event_loop.dispatch(Some(16));
|
if let Err(_) = event_loop.dispatch(Some(16)) {
|
||||||
display.flush_clients();
|
running.store(false, Ordering::SeqCst);
|
||||||
window_map.borrow_mut().refresh();
|
} else {
|
||||||
|
display.flush_clients();
|
||||||
|
window_map.borrow_mut().refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Bye Bye");
|
println!("Bye Bye");
|
||||||
|
@ -326,7 +325,6 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UdevHandlerImpl {
|
struct UdevHandlerImpl {
|
||||||
shell_state_token: StateToken<ShellState<SurfaceData, Roles, Rc<RefCell<Option<EGLDisplay>>>, ()>>,
|
|
||||||
compositor_token: CompositorToken<SurfaceData, Roles, Rc<RefCell<Option<EGLDisplay>>>>,
|
compositor_token: CompositorToken<SurfaceData, Roles, Rc<RefCell<Option<EGLDisplay>>>>,
|
||||||
active_egl_context: Rc<RefCell<Option<EGLDisplay>>>,
|
active_egl_context: Rc<RefCell<Option<EGLDisplay>>>,
|
||||||
backends: HashMap<u64, Rc<RefCell<HashMap<crtc::Handle, GliumDrawer<DrmBackend<SessionFdDrmDevice>>>>>>,
|
backends: HashMap<u64, Rc<RefCell<HashMap<crtc::Handle, GliumDrawer<DrmBackend<SessionFdDrmDevice>>>>>>,
|
||||||
|
@ -399,7 +397,6 @@ impl UdevHandler<DrmHandlerImpl> for UdevHandlerImpl {
|
||||||
self.backends.insert(device.device_id(), backends.clone());
|
self.backends.insert(device.device_id(), backends.clone());
|
||||||
|
|
||||||
Some(DrmHandlerImpl {
|
Some(DrmHandlerImpl {
|
||||||
shell_state_token: self.shell_state_token.clone(),
|
|
||||||
compositor_token: self.compositor_token.clone(),
|
compositor_token: self.compositor_token.clone(),
|
||||||
backends,
|
backends,
|
||||||
window_map: self.window_map.clone(),
|
window_map: self.window_map.clone(),
|
||||||
|
@ -434,7 +431,6 @@ impl UdevHandler<DrmHandlerImpl> for UdevHandlerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DrmHandlerImpl {
|
pub struct DrmHandlerImpl {
|
||||||
shell_state_token: StateToken<ShellState<SurfaceData, Roles, Rc<RefCell<Option<EGLDisplay>>>, ()>>,
|
|
||||||
compositor_token: CompositorToken<SurfaceData, Roles, Rc<RefCell<Option<EGLDisplay>>>>,
|
compositor_token: CompositorToken<SurfaceData, Roles, Rc<RefCell<Option<EGLDisplay>>>>,
|
||||||
backends: Rc<RefCell<HashMap<crtc::Handle, GliumDrawer<DrmBackend<SessionFdDrmDevice>>>>>,
|
backends: Rc<RefCell<HashMap<crtc::Handle, GliumDrawer<DrmBackend<SessionFdDrmDevice>>>>>,
|
||||||
window_map: Rc<RefCell<MyWindowMap>>,
|
window_map: Rc<RefCell<MyWindowMap>>,
|
||||||
|
|
|
@ -14,6 +14,7 @@ use std::cell::Cell;
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use wayland_server::Display;
|
use wayland_server::Display;
|
||||||
|
|
||||||
|
/// Backend based on a `DrmDevice` and a given crtc
|
||||||
pub struct DrmBackend<A: Device + 'static> {
|
pub struct DrmBackend<A: Device + 'static> {
|
||||||
backend: Rc<DrmBackendInternal<A>>,
|
backend: Rc<DrmBackendInternal<A>>,
|
||||||
surface: EGLSurface<GbmSurface<framebuffer::Info>>,
|
surface: EGLSurface<GbmSurface<framebuffer::Info>>,
|
||||||
|
@ -21,7 +22,6 @@ pub struct DrmBackend<A: Device + 'static> {
|
||||||
connectors: Vec<connector::Handle>,
|
connectors: Vec<connector::Handle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Backend based on a `DrmDevice` and a given crtc
|
|
||||||
pub(crate) struct DrmBackendInternal<A: Device + 'static> {
|
pub(crate) struct DrmBackendInternal<A: Device + 'static> {
|
||||||
context: Rc<EGLContext<Gbm<framebuffer::Info>, GbmDevice<A>>>,
|
context: Rc<EGLContext<Gbm<framebuffer::Info>, GbmDevice<A>>>,
|
||||||
cursor: Cell<BufferObject<()>>,
|
cursor: Cell<BufferObject<()>>,
|
||||||
|
|
|
@ -400,7 +400,9 @@ impl<A: ControlDevice + 'static> DrmDevice<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait for types representing open devices
|
||||||
pub trait DevPath {
|
pub trait DevPath {
|
||||||
|
/// Returns the path of the open device if possible
|
||||||
fn dev_path(&self) -> Option<PathBuf>;
|
fn dev_path(&self) -> Option<PathBuf>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,7 +558,7 @@ where
|
||||||
#[cfg(feature = "backend_session")]
|
#[cfg(feature = "backend_session")]
|
||||||
impl<A: ControlDevice + 'static> SessionObserver for StateToken<DrmDevice<A>> {
|
impl<A: ControlDevice + 'static> SessionObserver for StateToken<DrmDevice<A>> {
|
||||||
fn pause<'a>(&mut self, state: &mut StateProxy<'a>) {
|
fn pause<'a>(&mut self, state: &mut StateProxy<'a>) {
|
||||||
let device: &mut DrmDevice<A> = state.get_mut(self);
|
let device = state.get_mut(self);
|
||||||
device.active = false;
|
device.active = false;
|
||||||
if let Err(err) = device.drop_master() {
|
if let Err(err) = device.drop_master() {
|
||||||
error!(
|
error!(
|
||||||
|
@ -567,7 +569,7 @@ impl<A: ControlDevice + 'static> SessionObserver for StateToken<DrmDevice<A>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn activate<'a>(&mut self, state: &mut StateProxy<'a>) {
|
fn activate<'a>(&mut self, state: &mut StateProxy<'a>) {
|
||||||
let mut device = state.get_mut(self);
|
let device = state.get_mut(self);
|
||||||
device.active = true;
|
device.active = true;
|
||||||
if let Err(err) = device.set_master() {
|
if let Err(err) = device.set_master() {
|
||||||
crit!(
|
crit!(
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! EGL context related structs
|
||||||
|
|
||||||
use super::{ffi, EGLSurface, PixelFormat};
|
use super::{ffi, EGLSurface, PixelFormat};
|
||||||
use super::error::*;
|
use super::error::*;
|
||||||
use super::native;
|
use super::native;
|
||||||
|
@ -47,6 +49,7 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> DerefMut for EGLContext<B,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
||||||
|
/// Create a new `EGLContext` from a given `NativeDisplay`
|
||||||
pub fn new<L>(
|
pub fn new<L>(
|
||||||
native: N,
|
native: N,
|
||||||
attributes: GlAttributes,
|
attributes: GlAttributes,
|
||||||
|
@ -146,16 +149,16 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
||||||
Err(_) => ptr::null(),
|
Err(_) => ptr::null(),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let procAddress = constrain(|sym| {
|
let proc_address = constrain(|sym| {
|
||||||
let addr = CString::new(sym).unwrap();
|
let addr = CString::new(sym).unwrap();
|
||||||
let addr = addr.as_ptr();
|
let addr = addr.as_ptr();
|
||||||
ffi::egl::GetProcAddress(addr) as *const _
|
ffi::egl::GetProcAddress(addr) as *const _
|
||||||
});
|
});
|
||||||
ffi::egl::load_with(&procAddress);
|
ffi::egl::load_with(&proc_address);
|
||||||
ffi::egl::BindWaylandDisplayWL::load_with(&procAddress);
|
ffi::egl::BindWaylandDisplayWL::load_with(&proc_address);
|
||||||
ffi::egl::UnbindWaylandDisplayWL::load_with(&procAddress);
|
ffi::egl::UnbindWaylandDisplayWL::load_with(&proc_address);
|
||||||
ffi::egl::QueryWaylandBufferWL::load_with(&procAddress);
|
ffi::egl::QueryWaylandBufferWL::load_with(&proc_address);
|
||||||
ffi::gl::load_with(&procAddress);
|
ffi::gl::load_with(&proc_address);
|
||||||
});
|
});
|
||||||
|
|
||||||
// the first step is to query the list of extensions without any display, if supported
|
// the first step is to query the list of extensions without any display, if supported
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! EGL error types
|
||||||
|
|
||||||
error_chain! {
|
error_chain! {
|
||||||
errors {
|
errors {
|
||||||
#[doc = "The requested OpenGL version is not supported"]
|
#[doc = "The requested OpenGL version is not supported"]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//! Common traits and types for egl context creation and rendering
|
//! Common traits and types for egl rendering
|
||||||
|
|
||||||
/// Large parts of this module are taken from
|
/// Large parts of this module are taken from
|
||||||
/// https://github.com/tomaka/glutin/tree/044e651edf67a2029eecc650dd42546af1501414/src/api/egl/
|
/// https://github.com/tomaka/glutin/tree/044e651edf67a2029eecc650dd42546af1501414/src/api/egl/
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! Type safe native types for safe context/surface creation
|
||||||
|
|
||||||
use super::ffi;
|
use super::ffi;
|
||||||
use super::error::*;
|
use super::error::*;
|
||||||
|
|
||||||
|
@ -18,9 +20,17 @@ use winit::os::unix::WindowExt;
|
||||||
#[cfg(feature = "backend_winit")]
|
#[cfg(feature = "backend_winit")]
|
||||||
use wayland_client::egl as wegl;
|
use wayland_client::egl as wegl;
|
||||||
|
|
||||||
|
/// Trait for typed backend variants (X11/Wayland/GBM)
|
||||||
pub trait Backend {
|
pub trait Backend {
|
||||||
|
/// Surface type created by this backend
|
||||||
type Surface: NativeSurface;
|
type Surface: NativeSurface;
|
||||||
|
|
||||||
|
/// Return an `EGLDisplay` based on this backend
|
||||||
|
///
|
||||||
|
/// # Unsafety
|
||||||
|
///
|
||||||
|
/// The returned `EGLDisplay` needs to be a valid ptr for egl,
|
||||||
|
/// but there is no way to test that.
|
||||||
unsafe fn get_display<F: Fn(&str) -> bool>(
|
unsafe fn get_display<F: Fn(&str) -> bool>(
|
||||||
display: ffi::NativeDisplayType,
|
display: ffi::NativeDisplayType,
|
||||||
has_dp_extension: F,
|
has_dp_extension: F,
|
||||||
|
@ -29,6 +39,7 @@ pub trait Backend {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "backend_winit")]
|
#[cfg(feature = "backend_winit")]
|
||||||
|
/// Wayland backend type
|
||||||
pub enum Wayland {}
|
pub enum Wayland {}
|
||||||
#[cfg(feature = "backend_winit")]
|
#[cfg(feature = "backend_winit")]
|
||||||
impl Backend for Wayland {
|
impl Backend for Wayland {
|
||||||
|
@ -65,8 +76,10 @@ impl Backend for Wayland {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "backend_winit")]
|
#[cfg(feature = "backend_winit")]
|
||||||
|
/// Typed Xlib window for the `X11` backend
|
||||||
pub struct XlibWindow(u64);
|
pub struct XlibWindow(u64);
|
||||||
#[cfg(feature = "backend_winit")]
|
#[cfg(feature = "backend_winit")]
|
||||||
|
/// X11 backend type
|
||||||
pub enum X11 {}
|
pub enum X11 {}
|
||||||
#[cfg(feature = "backend_winit")]
|
#[cfg(feature = "backend_winit")]
|
||||||
impl Backend for X11 {
|
impl Backend for X11 {
|
||||||
|
@ -94,6 +107,7 @@ impl Backend for X11 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(feature = "backend_drm")]
|
#[cfg(feature = "backend_drm")]
|
||||||
|
/// Gbm backend type
|
||||||
pub struct Gbm<T: 'static> {
|
pub struct Gbm<T: 'static> {
|
||||||
_userdata: PhantomData<T>,
|
_userdata: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
@ -134,7 +148,9 @@ impl<T: 'static> Backend for Gbm<T> {
|
||||||
///
|
///
|
||||||
/// The returned `NativeDisplayType` must be valid for egl and there is no way to test that.
|
/// The returned `NativeDisplayType` must be valid for egl and there is no way to test that.
|
||||||
pub unsafe trait NativeDisplay<B: Backend> {
|
pub unsafe trait NativeDisplay<B: Backend> {
|
||||||
|
/// Arguments used to surface creation.
|
||||||
type Arguments;
|
type Arguments;
|
||||||
|
/// Error type thrown by the surface creation in case of failure.
|
||||||
type Error: ::std::error::Error + Send + 'static;
|
type Error: ::std::error::Error + Send + 'static;
|
||||||
/// Because one typ might implement multiple `Backend` this function must be called to check
|
/// Because one typ might implement multiple `Backend` this function must be called to check
|
||||||
/// if the expected `Backend` is used at runtime.
|
/// if the expected `Backend` is used at runtime.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! EGL surface related structs
|
||||||
|
|
||||||
use super::{EGLContext, SwapBuffersError};
|
use super::{EGLContext, SwapBuffersError};
|
||||||
use super::error::*;
|
use super::error::*;
|
||||||
use super::ffi;
|
use super::ffi;
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
//! Wayland specific EGL functionality - EGL based WlBuffers.
|
||||||
|
//!
|
||||||
|
//! The types of this module can be used to initialize hardware acceleration rendering
|
||||||
|
//! based on EGL for clients as it may enabled usage of `EGLImage` based `WlBuffer`s.
|
||||||
|
//!
|
||||||
|
//! To use it bind any backend implementing the `EGLWaylandExtensions` trait, that shall do the
|
||||||
|
//! rendering (so pick a fast one), to the `wayland_server::Display` of your compositor.
|
||||||
|
//! Note only one backend may be bould to any `Display` at any time.
|
||||||
|
//!
|
||||||
|
//! You may then use the resulting `EGLDisplay` to recieve `EGLImages` of an egl-based `WlBuffer`
|
||||||
|
//! for rendering.
|
||||||
|
|
||||||
use backend::graphics::egl::{EGLContext, EglExtensionNotSupportedError, ffi, native};
|
use backend::graphics::egl::{EGLContext, EglExtensionNotSupportedError, ffi, native};
|
||||||
use backend::graphics::egl::error::*;
|
use backend::graphics::egl::error::*;
|
||||||
use backend::graphics::egl::ffi::egl::types::EGLImage;
|
use backend::graphics::egl::ffi::egl::types::EGLImage;
|
||||||
|
@ -113,17 +125,26 @@ impl ::std::error::Error for TextureCreationError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Texture format types
|
||||||
#[repr(i32)]
|
#[repr(i32)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
pub enum Format {
|
pub enum Format {
|
||||||
|
/// RGB format
|
||||||
RGB = ffi::egl::TEXTURE_RGB as i32,
|
RGB = ffi::egl::TEXTURE_RGB as i32,
|
||||||
|
/// RGB + alpha channel format
|
||||||
RGBA = ffi::egl::TEXTURE_RGBA as i32,
|
RGBA = ffi::egl::TEXTURE_RGBA as i32,
|
||||||
|
/// External format
|
||||||
External = ffi::egl::TEXTURE_EXTERNAL_WL,
|
External = ffi::egl::TEXTURE_EXTERNAL_WL,
|
||||||
|
/// 2-plane Y and UV format
|
||||||
Y_UV = ffi::egl::TEXTURE_Y_UV_WL,
|
Y_UV = ffi::egl::TEXTURE_Y_UV_WL,
|
||||||
|
/// 3-plane Y, U and V format
|
||||||
Y_U_V = ffi::egl::TEXTURE_Y_U_V_WL,
|
Y_U_V = ffi::egl::TEXTURE_Y_U_V_WL,
|
||||||
|
/// 2-plane Y and XUXV format
|
||||||
Y_XUXV = ffi::egl::TEXTURE_Y_XUXV_WL,
|
Y_XUXV = ffi::egl::TEXTURE_Y_XUXV_WL,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format {
|
impl Format {
|
||||||
|
/// Amount of planes this format uses
|
||||||
pub fn num_planes(&self) -> usize {
|
pub fn num_planes(&self) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
Format::RGB | Format::RGBA | Format::External => 1,
|
Format::RGB | Format::RGBA | Format::External => 1,
|
||||||
|
@ -133,21 +154,34 @@ impl Format {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Images of the egl-based `WlBuffer`.
|
||||||
pub struct EGLImages {
|
pub struct EGLImages {
|
||||||
display: Weak<ffi::egl::types::EGLDisplay>,
|
display: Weak<ffi::egl::types::EGLDisplay>,
|
||||||
|
/// Width in pixels
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
|
/// Height in pixels
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
|
/// If the y-axis is inverted or not
|
||||||
pub y_inverted: bool,
|
pub y_inverted: bool,
|
||||||
|
/// Format of these images
|
||||||
pub format: Format,
|
pub format: Format,
|
||||||
images: Vec<EGLImage>,
|
images: Vec<EGLImage>,
|
||||||
buffer: WlBuffer,
|
buffer: WlBuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EGLImages {
|
impl EGLImages {
|
||||||
|
/// Amount of planes of these `EGLImages`
|
||||||
pub fn num_planes(&self) -> usize {
|
pub fn num_planes(&self) -> usize {
|
||||||
self.format.num_planes()
|
self.format.num_planes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Bind plane to an OpenGL texture id
|
||||||
|
///
|
||||||
|
/// This does only temporarily modify the OpenGL state any changes are reverted before returning.
|
||||||
|
///
|
||||||
|
/// # Unsafety
|
||||||
|
///
|
||||||
|
/// The given `tex_id` needs to be a valid GL texture otherwise undefined behavior might occur.
|
||||||
pub unsafe fn bind_to_texture(&self, plane: usize, tex_id: c_uint) -> ::std::result::Result<(), TextureCreationError> {
|
pub unsafe fn bind_to_texture(&self, plane: usize, tex_id: c_uint) -> ::std::result::Result<(), TextureCreationError> {
|
||||||
if self.display.upgrade().is_some() {
|
if self.display.upgrade().is_some() {
|
||||||
let mut old_tex_id: i32 = 0;
|
let mut old_tex_id: i32 = 0;
|
||||||
|
@ -177,6 +211,8 @@ impl Drop for EGLImages {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait any backend type may implement that allows binding a `wayland_server::Display`
|
||||||
|
/// to create an `EGLDisplay` for egl-based `WlBuffer`s.
|
||||||
pub trait EGLWaylandExtensions {
|
pub trait EGLWaylandExtensions {
|
||||||
/// Binds this EGL context to the given Wayland display.
|
/// Binds this EGL context to the given Wayland display.
|
||||||
///
|
///
|
||||||
|
@ -194,6 +230,9 @@ pub trait EGLWaylandExtensions {
|
||||||
fn bind_wl_display(&self, display: &Display) -> Result<EGLDisplay>;
|
fn bind_wl_display(&self, display: &Display) -> Result<EGLDisplay>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Type to recieve `EGLImages` for egl-based `WlBuffer`s.
|
||||||
|
///
|
||||||
|
/// Can be created by using `EGLWaylandExtensions::bind_wl_display`.
|
||||||
pub struct EGLDisplay(Weak<ffi::egl::types::EGLDisplay>, *mut wl_display);
|
pub struct EGLDisplay(Weak<ffi::egl::types::EGLDisplay>, *mut wl_display);
|
||||||
|
|
||||||
impl EGLDisplay {
|
impl EGLDisplay {
|
||||||
|
@ -201,6 +240,11 @@ impl EGLDisplay {
|
||||||
EGLDisplay(Rc::downgrade(&context.display), display)
|
EGLDisplay(Rc::downgrade(&context.display), display)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Try to recieve `EGLImages` from a given `WlBuffer`.
|
||||||
|
///
|
||||||
|
/// In case the buffer is not managed by egl (but e.g. the wayland::shm module)
|
||||||
|
/// a `BufferAccessError::NotManaged(WlBuffer)` is returned with the original buffer
|
||||||
|
/// to render it another way.
|
||||||
pub fn egl_buffer_contents(&self, buffer: WlBuffer) -> ::std::result::Result<EGLImages, BufferAccessError> {
|
pub fn egl_buffer_contents(&self, buffer: WlBuffer) -> ::std::result::Result<EGLImages, BufferAccessError> {
|
||||||
if let Some(display) = self.0.upgrade() {
|
if let Some(display) = self.0.upgrade() {
|
||||||
let mut format: i32 = 0;
|
let mut format: i32 = 0;
|
||||||
|
|
|
@ -25,6 +25,7 @@ use udev::{Context, Enumerator, Event, EventType, MonitorBuilder, MonitorSocket,
|
||||||
use wayland_server::{EventLoopHandle, StateProxy, StateToken};
|
use wayland_server::{EventLoopHandle, StateProxy, StateToken};
|
||||||
use wayland_server::sources::{FdEventSource, FdEventSourceImpl, FdInterest};
|
use wayland_server::sources::{FdEventSource, FdEventSourceImpl, FdInterest};
|
||||||
|
|
||||||
|
/// Udev's `DrmDevice` type based on the underlying session
|
||||||
pub struct SessionFdDrmDevice(RawFd);
|
pub struct SessionFdDrmDevice(RawFd);
|
||||||
|
|
||||||
impl AsRawFd for SessionFdDrmDevice {
|
impl AsRawFd for SessionFdDrmDevice {
|
||||||
|
|
Loading…
Reference in New Issue