Skip to content

Commit

Permalink
Merge pull request #116 from Smithay/refactor/backend
Browse files Browse the repository at this point in the history
Refactor drm backend (v3)
  • Loading branch information
Drakulix committed Dec 9, 2018
2 parents 96a57fc + a3acd48 commit 60bb5e8
Show file tree
Hide file tree
Showing 59 changed files with 3,406 additions and 2,513 deletions.
6 changes: 5 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,15 @@ env:
# test individual features
- FEATURES="backend_winit"
- FEATURES="backend_drm"
- FEATURES="backend_drm_legacy"
- FEATURES="backend_drm_gbm"
- FEATURES="backend_drm_egl"
- FEATURES="backend_egl"
- FEATURES="backend_libinput"
- FEATURES="backend_udev"
- FEATURES="backend_session"
- FEATURES="backend_session_udev"
- FEATURES="backend_session_logind"
- FEATURES="renderer_gl"
- FEATURES="renderer_glium"
- FEATURES="xwayland"
# test default features
Expand Down
34 changes: 21 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ repository = "https://github.com/Smithay/smithay"
members = [ "anvil" ]

[dependencies]
wayland-server = "0.21.1"
wayland-sys = "0.21.1"
wayland-server = "0.21.6"
wayland-commons = "0.21.1"
wayland-sys = { version = "0.21.6", optional = true }
nix = "0.11"
xkbcommon = "0.2.1"
tempfile = "2.1.5"
Expand All @@ -21,29 +21,37 @@ slog-stdlog = "3.0.2"
libloading = "0.4.0"
wayland-client = { version = "0.21.1", features = ["egl"], optional = true }
winit = { version = "0.18.0", optional = true }
drm = { version = "^0.3.1", optional = true }
gbm = { version = "^0.4.0", optional = true, default-features = false, features = ["drm-support"] }
drm = { version = "^0.3.4", optional = true }
gbm = { version = "^0.5.0", optional = true, default-features = false, features = ["drm-support"] }
glium = { version = "0.19.0", optional = true, default-features = false }
input = { version = "0.4.0", optional = true }
input = { version = "0.4.1", optional = true }
udev = { version = "0.2.0", optional = true }
dbus = { version = "0.6.1", optional = true }
systemd = { version = "^0.2.0", optional = true }
wayland-protocols = { version = "0.21.1", features = ["unstable_protocols", "native_server"] }
wayland-protocols = { version = "0.21.3", features = ["unstable_protocols", "server"] }
image = "0.17.0"
error-chain = "0.11.0"
lazy_static = "1.0.0"

[dev-dependencies]
slog-term = "2.3"

[build-dependencies]
gl_generator = "0.9"
gl_generator = { version = "0.9", optional = true }

[features]
default = ["backend_winit", "backend_drm", "backend_libinput", "backend_udev", "renderer_glium", "xwayland"]
backend_winit = ["winit", "wayland-server/dlopen", "wayland-client/dlopen"]
backend_drm = ["drm", "gbm"]
default = ["backend_winit", "backend_drm_legacy", "backend_drm_gbm", "backend_drm_egl", "backend_libinput", "backend_udev", "backend_session", "renderer_glium", "xwayland"]
backend_winit = ["winit", "wayland-server/dlopen", "wayland-client/dlopen", "backend_egl", "renderer_gl", "native_lib"]
backend_drm = ["drm"]
backend_drm_legacy = ["backend_drm"]
backend_drm_gbm = ["backend_drm", "gbm"]
backend_drm_egl = ["backend_drm", "backend_egl"]
backend_egl = ["gl_generator"]
backend_libinput = ["input"]
backend_session = []
backend_session_udev = ["udev", "backend_session"]
backend_udev = ["udev"]
backend_session_logind = ["dbus", "systemd", "backend_session"]
backend_udev = ["udev", "backend_drm", "backend_session_udev"]
renderer_glium = ["glium"]
renderer_gl = ["gl_generator"]
renderer_glium = ["renderer_gl", "glium"]
native_lib = ["wayland-sys", "wayland-server/native_lib", "wayland-protocols/native_server"]
xwayland = []
6 changes: 3 additions & 3 deletions anvil/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ features = [ "renderer_glium" ]
gl_generator = "0.9"

[features]
default = [ "winit", "tty_launch", "udev" ]
default = [ "winit", "egl", "udev" ]
egl = [ "smithay/native_lib" ]
winit = [ "smithay/backend_winit" ]
tty_launch = [ "smithay/backend_libinput", "smithay/backend_drm" ]
udev = [ "tty_launch", "smithay/backend_udev" ]
udev = [ "smithay/backend_libinput", "smithay/backend_drm_legacy", "smithay/backend_drm_gbm", "smithay/backend_drm_egl", "smithay/backend_udev", "smithay/backend_session" ]
logind = [ "smithay/backend_session_logind" ]
139 changes: 96 additions & 43 deletions anvil/src/glium_drawer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,18 @@ use glium::{
};
use slog::Logger;

#[cfg(feature = "egl")]
use smithay::backend::egl::EGLDisplay;
use smithay::{
backend::graphics::{
egl::{
error::Result as EGLResult,
wayland::{BufferAccessError, EGLDisplay, EGLImages, EGLWaylandExtensions, Format},
EGLGraphicsBackend,
},
glium::GliumGraphicsBackend,
backend::{
egl::{BufferAccessError, EGLImages, Format},
graphics::{gl::GLGraphicsBackend, glium::GliumGraphicsBackend},
},
wayland::{
compositor::{roles::Role, SubsurfaceRole, TraversalAction},
shm::with_buffer_contents as shm_buffer_contents,
},
wayland_server::{protocol::wl_buffer, Display, Resource},
wayland_server::{protocol::wl_buffer, Resource},
};

use shaders;
Expand All @@ -38,22 +36,24 @@ struct Vertex {

implement_vertex!(Vertex, position, tex_coords);

pub struct GliumDrawer<F: EGLGraphicsBackend + 'static> {
pub struct GliumDrawer<F: GLGraphicsBackend + 'static> {
display: GliumGraphicsBackend<F>,
vertex_buffer: glium::VertexBuffer<Vertex>,
index_buffer: glium::IndexBuffer<u16>,
programs: [glium::Program; shaders::FRAGMENT_COUNT],
#[cfg(feature = "egl")]
egl_display: Rc<RefCell<Option<EGLDisplay>>>,
log: Logger,
}

impl<F: EGLGraphicsBackend + 'static> GliumDrawer<F> {
impl<F: GLGraphicsBackend + 'static> GliumDrawer<F> {
pub fn borrow(&self) -> Ref<F> {
self.display.borrow()
}
}

impl<T: Into<GliumGraphicsBackend<T>> + EGLGraphicsBackend + 'static> GliumDrawer<T> {
impl<T: Into<GliumGraphicsBackend<T>> + GLGraphicsBackend + 'static> GliumDrawer<T> {
#[cfg(feature = "egl")]
pub fn init(backend: T, egl_display: Rc<RefCell<Option<EGLDisplay>>>, log: Logger) -> GliumDrawer<T> {
let display = backend.into();

Expand All @@ -78,7 +78,8 @@ impl<T: Into<GliumGraphicsBackend<T>> + EGLGraphicsBackend + 'static> GliumDrawe
tex_coords: [1.0, 0.0],
},
],
).unwrap();
)
.unwrap();

// building the index buffer
let index_buffer =
Expand All @@ -95,9 +96,53 @@ impl<T: Into<GliumGraphicsBackend<T>> + EGLGraphicsBackend + 'static> GliumDrawe
log,
}
}

#[cfg(not(feature = "egl"))]
pub fn init(backend: T, log: Logger) -> GliumDrawer<T> {
let display = backend.into();

// building the vertex buffer, which contains all the vertices that we will draw
let vertex_buffer = glium::VertexBuffer::new(
&display,
&[
Vertex {
position: [0.0, 0.0],
tex_coords: [0.0, 0.0],
},
Vertex {
position: [0.0, 1.0],
tex_coords: [0.0, 1.0],
},
Vertex {
position: [1.0, 1.0],
tex_coords: [1.0, 1.0],
},
Vertex {
position: [1.0, 0.0],
tex_coords: [1.0, 0.0],
},
],
)
.unwrap();

// building the index buffer
let index_buffer =
glium::IndexBuffer::new(&display, PrimitiveType::TriangleStrip, &[1 as u16, 2, 0, 3]).unwrap();

let programs = opengl_programs!(&display);

GliumDrawer {
display,
vertex_buffer,
index_buffer,
programs,
log,
}
}
}

impl<F: EGLGraphicsBackend + 'static> GliumDrawer<F> {
impl<F: GLGraphicsBackend + 'static> GliumDrawer<F> {
#[cfg(feature = "egl")]
pub fn texture_from_buffer(&self, buffer: Resource<wl_buffer::WlBuffer>) -> Result<TextureMetadata, ()> {
// try to retrieve the egl contents of this buffer
let images = if let Some(display) = &self.egl_display.borrow().as_ref() {
Expand All @@ -122,7 +167,8 @@ impl<F: EGLGraphicsBackend + 'static> GliumDrawer<F> {
MipmapsOption::NoMipmap,
images.width,
images.height,
).unwrap();
)
.unwrap();
unsafe {
images
.bind_to_texture(0, opengl_texture.get_id())
Expand All @@ -138,26 +184,7 @@ impl<F: EGLGraphicsBackend + 'static> GliumDrawer<F> {
}
Err(BufferAccessError::NotManaged(buffer)) => {
// this is not an EGL buffer, try SHM
match shm_buffer_contents(&buffer, |slice, data| {
::shm_load::load_shm_buffer(data, slice)
.map(|(image, kind)| (Texture2d::new(&self.display, image).unwrap(), kind, data))
}) {
Ok(Ok((texture, kind, data))) => Ok(TextureMetadata {
texture,
fragment: kind,
y_inverted: false,
dimensions: (data.width as u32, data.height as u32),
images: None,
}),
Ok(Err(format)) => {
warn!(self.log, "Unsupported SHM buffer format"; "format" => format!("{:?}", format));
Err(())
}
Err(err) => {
warn!(self.log, "Unable to load buffer contents"; "err" => format!("{:?}", err));
Err(())
}
}
self.texture_from_shm_buffer(buffer)
}
Err(err) => {
error!(self.log, "EGL error"; "err" => format!("{:?}", err));
Expand All @@ -166,6 +193,35 @@ impl<F: EGLGraphicsBackend + 'static> GliumDrawer<F> {
}
}

#[cfg(not(feature = "egl"))]
pub fn texture_from_buffer(&self, buffer: Resource<wl_buffer::WlBuffer>) -> Result<TextureMetadata, ()> {
self.texture_from_shm_buffer(buffer)
}

fn texture_from_shm_buffer(&self, buffer: Resource<wl_buffer::WlBuffer>) -> Result<TextureMetadata, ()> {
match shm_buffer_contents(&buffer, |slice, data| {
::shm_load::load_shm_buffer(data, slice)
.map(|(image, kind)| (Texture2d::new(&self.display, image).unwrap(), kind, data))
}) {
Ok(Ok((texture, kind, data))) => Ok(TextureMetadata {
texture,
fragment: kind,
y_inverted: false,
dimensions: (data.width as u32, data.height as u32),
#[cfg(feature = "egl")]
images: None,
}),
Ok(Err(format)) => {
warn!(self.log, "Unsupported SHM buffer format"; "format" => format!("{:?}", format));
Err(())
}
Err(err) => {
warn!(self.log, "Unable to load buffer contents"; "err" => format!("{:?}", err));
Err(())
}
}
}

pub fn render_texture(
&self,
target: &mut glium::Frame,
Expand Down Expand Up @@ -208,7 +264,8 @@ impl<F: EGLGraphicsBackend + 'static> GliumDrawer<F> {
blend: blending,
..Default::default()
},
).unwrap();
)
.unwrap();
}

#[inline]
Expand All @@ -217,21 +274,16 @@ impl<F: EGLGraphicsBackend + 'static> GliumDrawer<F> {
}
}

impl<G: EGLWaylandExtensions + EGLGraphicsBackend + 'static> EGLWaylandExtensions for GliumDrawer<G> {
fn bind_wl_display(&self, display: &Display) -> EGLResult<EGLDisplay> {
self.display.bind_wl_display(display)
}
}

pub struct TextureMetadata {
pub texture: Texture2d,
pub fragment: usize,
pub y_inverted: bool,
pub dimensions: (u32, u32),
#[cfg(feature = "egl")]
images: Option<EGLImages>,
}

impl<F: EGLGraphicsBackend + 'static> GliumDrawer<F> {
impl<F: GLGraphicsBackend + 'static> GliumDrawer<F> {
pub fn draw_windows(&self, window_map: &MyWindowMap, compositor_token: MyCompositorToken, log: &Logger) {
let mut frame = self.draw();
frame.clear(None, Some((0.8, 0.8, 0.9, 1.0)), false, Some(1.0), None);
Expand Down Expand Up @@ -290,7 +342,8 @@ impl<F: EGLGraphicsBackend + 'static> GliumDrawer<F> {
TraversalAction::SkipChildren
}
},
).unwrap();
)
.unwrap();
}
});
}
Expand Down
16 changes: 9 additions & 7 deletions anvil/src/input_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::{
use slog::Logger;

#[cfg(feature = "udev")]
use smithay::backend::session::auto::AutoSession;
use smithay::backend::session::{auto::AutoSession, Session};
use smithay::{
backend::input::{
self, Event, InputBackend, InputHandler, KeyState, KeyboardKeyEvent, PointerAxisEvent,
Expand Down Expand Up @@ -131,13 +131,15 @@ impl<B: InputBackend> InputHandler<B> for AnvilInputHandler {
info!(self.log, "Quitting.");
self.running.store(false, Ordering::SeqCst);
}
#[cfg(feature = "tty_lauch")]
KeyAction::VtSwitch(vt) => if let Some(ref mut session) = self.session {
info!(log, "Trying to switch to vt {}", vt);
if let Err(err) = session.change_vt(vt) {
error!(log, "Error switching to vt {}: {}", vt, err);
#[cfg(feature = "udev")]
KeyAction::VtSwitch(vt) => {
if let Some(ref mut session) = self.session {
info!(log, "Trying to switch to vt {}", vt);
if let Err(err) = session.change_vt(vt) {
error!(log, "Error switching to vt {}: {}", vt, err);
}
}
},
}
KeyAction::Run(cmd) => {
info!(self.log, "Starting program"; "cmd" => cmd.clone());
if let Err(e) = Command::new(&cmd).spawn() {
Expand Down
11 changes: 0 additions & 11 deletions anvil/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ use smithay::wayland_server::{calloop::EventLoop, Display};
mod shaders;
mod glium_drawer;
mod input_handler;
#[cfg(feature = "tty_launch")]
mod raw_drm;
mod shell;
mod shm_load;
#[cfg(feature = "udev")]
Expand All @@ -29,8 +27,6 @@ mod winit;
static POSSIBLE_BACKENDS: &'static [&'static str] = &[
#[cfg(feature = "winit")]
"--winit : Run anvil as a X11 or Wayland client using winit.",
#[cfg(feature = "tty_launch")]
"--tty-raw : Run anvil as a raw DRM client (requires root).",
#[cfg(feature = "udev")]
"--tty-udev : Run anvil as a tty udev client (requires root if without logind).",
];
Expand All @@ -54,13 +50,6 @@ fn main() {
crit!(log, "Failed to initialize winit backend.");
}
}
#[cfg(feature = "tty_launch")]
Some("--tty-raw") => {
info!(log, "Starting anvil on a tty using raw DRM");
if let Err(()) = raw_drm::run_raw_drm(display, event_loop, log.clone()) {
crit!(log, "Failed to initialize tty backend.");
}
}
#[cfg(feature = "udev")]
Some("--tty-udev") => {
info!(log, "Starting anvil on a tty using udev");
Expand Down
Loading

0 comments on commit 60bb5e8

Please sign in to comment.