lint: fmt
This commit is contained in:
parent
31b6d84442
commit
9300e35093
|
@ -16,7 +16,10 @@ use smithay::backend::egl::display::EGLBufferReader;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::{
|
backend::{
|
||||||
egl::{BufferAccessError, EGLImages, Format},
|
egl::{BufferAccessError, EGLImages, Format},
|
||||||
graphics::{gl::GLGraphicsBackend, glium::{GliumGraphicsBackend, Frame}},
|
graphics::{
|
||||||
|
gl::GLGraphicsBackend,
|
||||||
|
glium::{Frame, GliumGraphicsBackend},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
reexports::wayland_server::protocol::{wl_buffer, wl_surface},
|
reexports::wayland_server::protocol::{wl_buffer, wl_surface},
|
||||||
wayland::{
|
wayland::{
|
||||||
|
@ -159,7 +162,10 @@ impl<F: GLGraphicsBackend + 'static> GliumDrawer<F> {
|
||||||
let images = if let Some(display) = &self.egl_buffer_reader.borrow().as_ref() {
|
let images = if let Some(display) = &self.egl_buffer_reader.borrow().as_ref() {
|
||||||
display.egl_buffer_contents(buffer)
|
display.egl_buffer_contents(buffer)
|
||||||
} else {
|
} else {
|
||||||
Err(BufferAccessError::NotManaged(buffer, smithay::backend::egl::EGLError::BadDisplay))
|
Err(BufferAccessError::NotManaged(
|
||||||
|
buffer,
|
||||||
|
smithay::backend::egl::EGLError::BadDisplay,
|
||||||
|
))
|
||||||
};
|
};
|
||||||
match images {
|
match images {
|
||||||
Ok(images) => {
|
Ok(images) => {
|
||||||
|
|
|
@ -319,7 +319,9 @@ impl<S: SessionNotifier, Data: 'static> UdevHandlerImpl<S, Data> {
|
||||||
for crtc in res_handles.filter_crtcs(encoder_info.possible_crtcs()) {
|
for crtc in res_handles.filter_crtcs(encoder_info.possible_crtcs()) {
|
||||||
if let Entry::Vacant(entry) = backends.entry(crtc) {
|
if let Entry::Vacant(entry) = backends.entry(crtc) {
|
||||||
let renderer = GliumDrawer::init(
|
let renderer = GliumDrawer::init(
|
||||||
device.create_surface(crtc, connector_info.modes()[0], &[connector_info.handle()]).unwrap(),
|
device
|
||||||
|
.create_surface(crtc, connector_info.modes()[0], &[connector_info.handle()])
|
||||||
|
.unwrap(),
|
||||||
egl_buffer_reader.clone(),
|
egl_buffer_reader.clone(),
|
||||||
logger.clone(),
|
logger.clone(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -56,7 +56,8 @@ fn main() {
|
||||||
let mut options = OpenOptions::new();
|
let mut options = OpenOptions::new();
|
||||||
options.read(true);
|
options.read(true);
|
||||||
options.write(true);
|
options.write(true);
|
||||||
let mut device = AtomicDrmDevice::new(options.open("/dev/dri/card0").unwrap(), true, log.clone()).unwrap();
|
let mut device =
|
||||||
|
AtomicDrmDevice::new(options.open("/dev/dri/card0").unwrap(), true, log.clone()).unwrap();
|
||||||
|
|
||||||
// Get a set of all modesetting resource handles (excluding planes):
|
// Get a set of all modesetting resource handles (excluding planes):
|
||||||
let res_handles = Device::resource_handles(&device).unwrap();
|
let res_handles = Device::resource_handles(&device).unwrap();
|
||||||
|
@ -96,7 +97,11 @@ fn main() {
|
||||||
let mode = connector_info.modes()[0]; // Use first mode (usually highest resoltion, but in reality you should filter and sort and check and match with other connectors, if you use more then one.)
|
let mode = connector_info.modes()[0]; // Use first mode (usually highest resoltion, but in reality you should filter and sort and check and match with other connectors, if you use more then one.)
|
||||||
|
|
||||||
// Initialize the hardware backend
|
// Initialize the hardware backend
|
||||||
let surface = Rc::new(device.create_surface(crtc, mode, &[connector_info.handle()]).unwrap());
|
let surface = Rc::new(
|
||||||
|
device
|
||||||
|
.create_surface(crtc, mode, &[connector_info.handle()])
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
for conn in surface.current_connectors().into_iter() {
|
for conn in surface.current_connectors().into_iter() {
|
||||||
if conn != connector_info.handle() {
|
if conn != connector_info.handle() {
|
||||||
|
|
|
@ -40,7 +40,8 @@ fn main() {
|
||||||
let mut options = OpenOptions::new();
|
let mut options = OpenOptions::new();
|
||||||
options.read(true);
|
options.read(true);
|
||||||
options.write(true);
|
options.write(true);
|
||||||
let mut device = LegacyDrmDevice::new(options.open("/dev/dri/card0").unwrap(), true, log.clone()).unwrap();
|
let mut device =
|
||||||
|
LegacyDrmDevice::new(options.open("/dev/dri/card0").unwrap(), true, log.clone()).unwrap();
|
||||||
|
|
||||||
// Get a set of all modesetting resource handles (excluding planes):
|
// Get a set of all modesetting resource handles (excluding planes):
|
||||||
let res_handles = Device::resource_handles(&device).unwrap();
|
let res_handles = Device::resource_handles(&device).unwrap();
|
||||||
|
@ -78,7 +79,11 @@ fn main() {
|
||||||
let mode = connector_info.modes()[0]; // Use first mode (usually highest resoltion, but in reality you should filter and sort and check and match with other connectors, if you use more then one.)
|
let mode = connector_info.modes()[0]; // Use first mode (usually highest resoltion, but in reality you should filter and sort and check and match with other connectors, if you use more then one.)
|
||||||
|
|
||||||
// Initialize the hardware backend
|
// Initialize the hardware backend
|
||||||
let surface = Rc::new(device.create_surface(crtc, mode, &[connector_info.handle()]).unwrap());
|
let surface = Rc::new(
|
||||||
|
device
|
||||||
|
.create_surface(crtc, mode, &[connector_info.handle()])
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lets create buffers and framebuffers.
|
* Lets create buffers and framebuffers.
|
||||||
|
|
|
@ -19,7 +19,8 @@ use std::sync::{
|
||||||
|
|
||||||
use drm::control::{atomic::AtomicModeReq, AtomicCommitFlags, Device as ControlDevice, Event};
|
use drm::control::{atomic::AtomicModeReq, AtomicCommitFlags, Device as ControlDevice, Event};
|
||||||
use drm::control::{
|
use drm::control::{
|
||||||
connector, crtc, encoder, framebuffer, plane, property, Mode, PropertyValueSet, ResourceHandle, ResourceHandles,
|
connector, crtc, encoder, framebuffer, plane, property, Mode, PropertyValueSet, ResourceHandle,
|
||||||
|
ResourceHandles,
|
||||||
};
|
};
|
||||||
use drm::SystemError as DrmError;
|
use drm::SystemError as DrmError;
|
||||||
use drm::{ClientCapability, Device as BasicDevice};
|
use drm::{ClientCapability, Device as BasicDevice};
|
||||||
|
@ -279,25 +280,38 @@ impl<A: AsRawFd + 'static> AtomicDrmDevice<A> {
|
||||||
// Disable all connectors as initial state
|
// Disable all connectors as initial state
|
||||||
let mut req = AtomicModeReq::new();
|
let mut req = AtomicModeReq::new();
|
||||||
for conn in res_handles.connectors() {
|
for conn in res_handles.connectors() {
|
||||||
let prop = dev.prop_mapping.0.get(&conn)
|
let prop = dev
|
||||||
.expect("Unknown handle").get("CRTC_ID")
|
.prop_mapping
|
||||||
|
.0
|
||||||
|
.get(&conn)
|
||||||
|
.expect("Unknown handle")
|
||||||
|
.get("CRTC_ID")
|
||||||
.expect("Unknown property CRTC_ID");
|
.expect("Unknown property CRTC_ID");
|
||||||
req.add_property(*conn, *prop, property::Value::CRTC(None));
|
req.add_property(*conn, *prop, property::Value::CRTC(None));
|
||||||
}
|
}
|
||||||
// A crtc without a connector has no mode, we also need to reset that.
|
// A crtc without a connector has no mode, we also need to reset that.
|
||||||
// Otherwise the commit will not be accepted.
|
// Otherwise the commit will not be accepted.
|
||||||
for crtc in res_handles.crtcs() {
|
for crtc in res_handles.crtcs() {
|
||||||
let active_prop = dev.prop_mapping.1.get(&crtc)
|
let active_prop = dev
|
||||||
.expect("Unknown handle").get("ACTIVE")
|
.prop_mapping
|
||||||
|
.1
|
||||||
|
.get(&crtc)
|
||||||
|
.expect("Unknown handle")
|
||||||
|
.get("ACTIVE")
|
||||||
.expect("Unknown property ACTIVE");
|
.expect("Unknown property ACTIVE");
|
||||||
let mode_prop = dev.prop_mapping.1.get(&crtc)
|
let mode_prop = dev
|
||||||
.expect("Unknown handle").get("MODE_ID")
|
.prop_mapping
|
||||||
|
.1
|
||||||
|
.get(&crtc)
|
||||||
|
.expect("Unknown handle")
|
||||||
|
.get("MODE_ID")
|
||||||
.expect("Unknown property MODE_ID");
|
.expect("Unknown property MODE_ID");
|
||||||
req.add_property(*crtc, *mode_prop, property::Value::Unknown(0));
|
req.add_property(*crtc, *mode_prop, property::Value::Unknown(0));
|
||||||
req.add_property(*crtc, *active_prop, property::Value::Boolean(false));
|
req.add_property(*crtc, *active_prop, property::Value::Boolean(false));
|
||||||
}
|
}
|
||||||
dev.atomic_commit(&[AtomicCommitFlags::AllowModeset], req)
|
dev.atomic_commit(&[AtomicCommitFlags::AllowModeset], req)
|
||||||
.compat().map_err(|source| Error::Access {
|
.compat()
|
||||||
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Failed to disable connectors",
|
errmsg: "Failed to disable connectors",
|
||||||
dev: dev.dev_path(),
|
dev: dev.dev_path(),
|
||||||
source,
|
source,
|
||||||
|
@ -339,7 +353,12 @@ impl<A: AsRawFd + 'static> Device for AtomicDrmDevice<A> {
|
||||||
let _ = self.handler.take();
|
let _ = self.handler.take();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_surface(&mut self, crtc: crtc::Handle, mode: Mode, connectors: &[connector::Handle]) -> Result<AtomicDrmSurface<A>, Error> {
|
fn create_surface(
|
||||||
|
&mut self,
|
||||||
|
crtc: crtc::Handle,
|
||||||
|
mode: Mode,
|
||||||
|
connectors: &[connector::Handle],
|
||||||
|
) -> Result<AtomicDrmSurface<A>, Error> {
|
||||||
if self.backends.borrow().contains_key(&crtc) {
|
if self.backends.borrow().contains_key(&crtc) {
|
||||||
return Err(Error::CrtcAlreadyInUse(crtc));
|
return Err(Error::CrtcAlreadyInUse(crtc));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
//! to an open [`Session`](::backend::session::Session).
|
//! to an open [`Session`](::backend::session::Session).
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use drm::control::{crtc, property, Device as ControlDevice, AtomicCommitFlags, atomic::AtomicModeReq};
|
use drm::control::{atomic::AtomicModeReq, crtc, property, AtomicCommitFlags, Device as ControlDevice};
|
||||||
use drm::Device as BasicDevice;
|
use drm::Device as BasicDevice;
|
||||||
|
use failure::ResultExt;
|
||||||
use nix::libc::dev_t;
|
use nix::libc::dev_t;
|
||||||
use nix::sys::stat;
|
use nix::sys::stat;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
@ -13,7 +14,6 @@ use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use failure::ResultExt;
|
|
||||||
|
|
||||||
use super::{AtomicDrmDevice, AtomicDrmSurfaceInternal, Dev};
|
use super::{AtomicDrmDevice, AtomicDrmSurfaceInternal, Dev};
|
||||||
use crate::backend::drm::{common::Error, DevPath};
|
use crate::backend::drm::{common::Error, DevPath};
|
||||||
|
@ -114,31 +114,44 @@ impl<A: AsRawFd + 'static> AtomicDrmDeviceObserver<A> {
|
||||||
.map_err(|source| Error::Access {
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Error loading drm resources",
|
errmsg: "Error loading drm resources",
|
||||||
dev: dev.dev_path(),
|
dev: dev.dev_path(),
|
||||||
source
|
source,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Disable all connectors (otherwise we might run into conflicting commits when restarting the rendering loop)
|
// Disable all connectors (otherwise we might run into conflicting commits when restarting the rendering loop)
|
||||||
let mut req = AtomicModeReq::new();
|
let mut req = AtomicModeReq::new();
|
||||||
for conn in res_handles.connectors() {
|
for conn in res_handles.connectors() {
|
||||||
let prop = dev.prop_mapping.0.get(&conn)
|
let prop = dev
|
||||||
.expect("Unknown handle").get("CRTC_ID")
|
.prop_mapping
|
||||||
|
.0
|
||||||
|
.get(&conn)
|
||||||
|
.expect("Unknown handle")
|
||||||
|
.get("CRTC_ID")
|
||||||
.expect("Unknown property CRTC_ID");
|
.expect("Unknown property CRTC_ID");
|
||||||
req.add_property(*conn, *prop, property::Value::CRTC(None));
|
req.add_property(*conn, *prop, property::Value::CRTC(None));
|
||||||
}
|
}
|
||||||
// A crtc without a connector has no mode, we also need to reset that.
|
// A crtc without a connector has no mode, we also need to reset that.
|
||||||
// Otherwise the commit will not be accepted.
|
// Otherwise the commit will not be accepted.
|
||||||
for crtc in res_handles.crtcs() {
|
for crtc in res_handles.crtcs() {
|
||||||
let mode_prop = dev.prop_mapping.1.get(&crtc)
|
let mode_prop = dev
|
||||||
.expect("Unknown handle").get("MODE_ID")
|
.prop_mapping
|
||||||
|
.1
|
||||||
|
.get(&crtc)
|
||||||
|
.expect("Unknown handle")
|
||||||
|
.get("MODE_ID")
|
||||||
.expect("Unknown property MODE_ID");
|
.expect("Unknown property MODE_ID");
|
||||||
let active_prop = dev.prop_mapping.1.get(&crtc)
|
let active_prop = dev
|
||||||
.expect("Unknown handle").get("ACTIVE")
|
.prop_mapping
|
||||||
|
.1
|
||||||
|
.get(&crtc)
|
||||||
|
.expect("Unknown handle")
|
||||||
|
.get("ACTIVE")
|
||||||
.expect("Unknown property ACTIVE");
|
.expect("Unknown property ACTIVE");
|
||||||
req.add_property(*crtc, *active_prop, property::Value::Boolean(false));
|
req.add_property(*crtc, *active_prop, property::Value::Boolean(false));
|
||||||
req.add_property(*crtc, *mode_prop, property::Value::Unknown(0));
|
req.add_property(*crtc, *mode_prop, property::Value::Unknown(0));
|
||||||
}
|
}
|
||||||
dev.atomic_commit(&[AtomicCommitFlags::AllowModeset], req)
|
dev.atomic_commit(&[AtomicCommitFlags::AllowModeset], req)
|
||||||
.compat().map_err(|source| Error::Access {
|
.compat()
|
||||||
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Failed to disable connectors",
|
errmsg: "Failed to disable connectors",
|
||||||
dev: dev.dev_path(),
|
dev: dev.dev_path(),
|
||||||
source,
|
source,
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
use drm::buffer::Buffer;
|
use drm::buffer::Buffer;
|
||||||
use drm::control::atomic::AtomicModeReq;
|
use drm::control::atomic::AtomicModeReq;
|
||||||
use drm::control::Device as ControlDevice;
|
use drm::control::Device as ControlDevice;
|
||||||
use drm::control::{connector, crtc, dumbbuffer::DumbBuffer, framebuffer, plane, property, AtomicCommitFlags, Mode, PlaneType};
|
use drm::control::{
|
||||||
|
connector, crtc, dumbbuffer::DumbBuffer, framebuffer, plane, property, AtomicCommitFlags, Mode, PlaneType,
|
||||||
|
};
|
||||||
use drm::Device as BasicDevice;
|
use drm::Device as BasicDevice;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::{RwLock, atomic::Ordering};
|
use std::sync::{atomic::Ordering, RwLock};
|
||||||
|
|
||||||
use failure::ResultExt as FailureResultExt;
|
use failure::ResultExt as FailureResultExt;
|
||||||
|
|
||||||
|
@ -57,7 +59,13 @@ impl<A: AsRawFd + 'static> BasicDevice for AtomicDrmSurfaceInternal<A> {}
|
||||||
impl<A: AsRawFd + 'static> ControlDevice for AtomicDrmSurfaceInternal<A> {}
|
impl<A: AsRawFd + 'static> ControlDevice for AtomicDrmSurfaceInternal<A> {}
|
||||||
|
|
||||||
impl<A: AsRawFd + 'static> AtomicDrmSurfaceInternal<A> {
|
impl<A: AsRawFd + 'static> AtomicDrmSurfaceInternal<A> {
|
||||||
pub(crate) fn new(dev: Rc<Dev<A>>, crtc: crtc::Handle, mode: Mode, connectors: &[connector::Handle], logger: ::slog::Logger) -> Result<Self, Error> {
|
pub(crate) fn new(
|
||||||
|
dev: Rc<Dev<A>>,
|
||||||
|
crtc: crtc::Handle,
|
||||||
|
mode: Mode,
|
||||||
|
connectors: &[connector::Handle],
|
||||||
|
logger: ::slog::Logger,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
let crtc_info = dev.get_crtc(crtc).compat().map_err(|source| Error::Access {
|
let crtc_info = dev.get_crtc(crtc).compat().map_err(|source| Error::Access {
|
||||||
errmsg: "Error loading crtc info",
|
errmsg: "Error loading crtc info",
|
||||||
dev: dev.dev_path(),
|
dev: dev.dev_path(),
|
||||||
|
@ -70,7 +78,8 @@ impl<A: AsRawFd + 'static> AtomicDrmSurfaceInternal<A> {
|
||||||
// So we cheat, because it works and is easier to handle later.
|
// So we cheat, because it works and is easier to handle later.
|
||||||
let current_mode = crtc_info.mode().unwrap_or_else(|| unsafe { std::mem::zeroed() });
|
let current_mode = crtc_info.mode().unwrap_or_else(|| unsafe { std::mem::zeroed() });
|
||||||
let current_blob = match crtc_info.mode() {
|
let current_blob = match crtc_info.mode() {
|
||||||
Some(mode) => dev.create_property_blob(mode)
|
Some(mode) => dev
|
||||||
|
.create_property_blob(mode)
|
||||||
.compat()
|
.compat()
|
||||||
.map_err(|source| Error::Access {
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Failed to create Property Blob for mode",
|
errmsg: "Failed to create Property Blob for mode",
|
||||||
|
@ -80,7 +89,8 @@ impl<A: AsRawFd + 'static> AtomicDrmSurfaceInternal<A> {
|
||||||
None => property::Value::Unknown(0),
|
None => property::Value::Unknown(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
let blob = dev.create_property_blob(mode)
|
let blob = dev
|
||||||
|
.create_property_blob(mode)
|
||||||
.compat()
|
.compat()
|
||||||
.map_err(|source| Error::Access {
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Failed to create Property Blob for mode",
|
errmsg: "Failed to create Property Blob for mode",
|
||||||
|
@ -96,7 +106,6 @@ impl<A: AsRawFd + 'static> AtomicDrmSurfaceInternal<A> {
|
||||||
source,
|
source,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
|
||||||
let mut current_connectors = HashSet::new();
|
let mut current_connectors = HashSet::new();
|
||||||
for conn in res_handles.connectors() {
|
for conn in res_handles.connectors() {
|
||||||
let crtc_prop = dev
|
let crtc_prop = dev
|
||||||
|
@ -163,15 +172,21 @@ impl<A: AsRawFd + 'static> AtomicDrmSurfaceInternal<A> {
|
||||||
|
|
||||||
fn create_test_buffer(&self, mode: &Mode) -> Result<framebuffer::Handle, Error> {
|
fn create_test_buffer(&self, mode: &Mode) -> Result<framebuffer::Handle, Error> {
|
||||||
let (w, h) = mode.size();
|
let (w, h) = mode.size();
|
||||||
let db = self.create_dumb_buffer((w as u32, h as u32), drm::buffer::format::PixelFormat::ARGB8888).compat().map_err(|source| Error::Access {
|
let db = self
|
||||||
|
.create_dumb_buffer((w as u32, h as u32), drm::buffer::format::PixelFormat::ARGB8888)
|
||||||
|
.compat()
|
||||||
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Failed to create dumb buffer",
|
errmsg: "Failed to create dumb buffer",
|
||||||
dev: self.dev_path(),
|
dev: self.dev_path(),
|
||||||
source
|
source,
|
||||||
})?;
|
})?;
|
||||||
let fb = self.add_framebuffer(&db).compat().map_err(|source| Error::Access {
|
let fb = self
|
||||||
|
.add_framebuffer(&db)
|
||||||
|
.compat()
|
||||||
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Failed to create framebuffer",
|
errmsg: "Failed to create framebuffer",
|
||||||
dev: self.dev_path(),
|
dev: self.dev_path(),
|
||||||
source
|
source,
|
||||||
})?;
|
})?;
|
||||||
if let Some((old_db, old_fb)) = self.test_buffer.replace(Some((db, fb))) {
|
if let Some((old_db, old_fb)) = self.test_buffer.replace(Some((db, fb))) {
|
||||||
let _ = self.destroy_framebuffer(old_fb);
|
let _ = self.destroy_framebuffer(old_fb);
|
||||||
|
@ -210,16 +225,31 @@ impl<A: AsRawFd + 'static> Drop for AtomicDrmSurfaceInternal<A> {
|
||||||
let current = self.state.read().unwrap();
|
let current = self.state.read().unwrap();
|
||||||
let mut req = AtomicModeReq::new();
|
let mut req = AtomicModeReq::new();
|
||||||
for conn in current.connectors.iter() {
|
for conn in current.connectors.iter() {
|
||||||
let prop = self.dev.prop_mapping.0.get(&conn)
|
let prop = self
|
||||||
.expect("Unknown Handle").get("CRTC_ID")
|
.dev
|
||||||
|
.prop_mapping
|
||||||
|
.0
|
||||||
|
.get(&conn)
|
||||||
|
.expect("Unknown Handle")
|
||||||
|
.get("CRTC_ID")
|
||||||
.expect("Unknown property CRTC_ID");
|
.expect("Unknown property CRTC_ID");
|
||||||
req.add_property(*conn, *prop, property::Value::CRTC(None));
|
req.add_property(*conn, *prop, property::Value::CRTC(None));
|
||||||
}
|
}
|
||||||
let active_prop = self.dev.prop_mapping.1.get(&self.crtc)
|
let active_prop = self
|
||||||
.expect("Unknown Handle").get("ACTIVE")
|
.dev
|
||||||
|
.prop_mapping
|
||||||
|
.1
|
||||||
|
.get(&self.crtc)
|
||||||
|
.expect("Unknown Handle")
|
||||||
|
.get("ACTIVE")
|
||||||
.expect("Unknown property ACTIVE");
|
.expect("Unknown property ACTIVE");
|
||||||
let mode_prop = self.dev.prop_mapping.1.get(&self.crtc)
|
let mode_prop = self
|
||||||
.expect("Unknown Handle").get("MODE_ID")
|
.dev
|
||||||
|
.prop_mapping
|
||||||
|
.1
|
||||||
|
.get(&self.crtc)
|
||||||
|
.expect("Unknown Handle")
|
||||||
|
.get("MODE_ID")
|
||||||
.expect("Unknown property MODE_ID");
|
.expect("Unknown property MODE_ID");
|
||||||
|
|
||||||
req.add_property(self.crtc, *active_prop, property::Value::Boolean(false));
|
req.add_property(self.crtc, *active_prop, property::Value::Boolean(false));
|
||||||
|
@ -453,11 +483,7 @@ impl<A: AsRawFd + 'static> RawSurface for AtomicDrmSurfaceInternal<A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if current.mode != pending.mode {
|
if current.mode != pending.mode {
|
||||||
info!(
|
info!(self.logger, "Setting new mode: {:?}", pending.mode.name());
|
||||||
self.logger,
|
|
||||||
"Setting new mode: {:?}",
|
|
||||||
pending.mode.name()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trace!(self.logger, "Testing screen config");
|
trace!(self.logger, "Testing screen config");
|
||||||
|
@ -533,8 +559,7 @@ impl<A: AsRawFd + 'static> RawSurface for AtomicDrmSurfaceInternal<A> {
|
||||||
return Err(Error::DeviceInactive);
|
return Err(Error::DeviceInactive);
|
||||||
}
|
}
|
||||||
|
|
||||||
let req = self
|
let req = self.build_request(
|
||||||
.build_request(
|
|
||||||
&mut [].iter(),
|
&mut [].iter(),
|
||||||
&mut [].iter(),
|
&mut [].iter(),
|
||||||
&self.planes,
|
&self.planes,
|
||||||
|
@ -548,10 +573,11 @@ impl<A: AsRawFd + 'static> RawSurface for AtomicDrmSurfaceInternal<A> {
|
||||||
&[AtomicCommitFlags::PageFlipEvent, AtomicCommitFlags::Nonblock],
|
&[AtomicCommitFlags::PageFlipEvent, AtomicCommitFlags::Nonblock],
|
||||||
req,
|
req,
|
||||||
)
|
)
|
||||||
.compat().map_err(|source| Error::Access {
|
.compat()
|
||||||
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Page flip commit failed",
|
errmsg: "Page flip commit failed",
|
||||||
dev: self.dev_path(),
|
dev: self.dev_path(),
|
||||||
source
|
source,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -22,8 +22,8 @@ use drm::{
|
||||||
#[cfg(feature = "renderer_gl")]
|
#[cfg(feature = "renderer_gl")]
|
||||||
use nix::libc::c_void;
|
use nix::libc::c_void;
|
||||||
use nix::libc::dev_t;
|
use nix::libc::dev_t;
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
#[cfg(feature = "use_system_lib")]
|
#[cfg(feature = "use_system_lib")]
|
||||||
use wayland_server::Display;
|
use wayland_server::Display;
|
||||||
|
|
||||||
|
@ -175,15 +175,17 @@ impl<A: AsRawFd + Clone + 'static> FallbackDevice<AtomicDrmDevice<A>, LegacyDrmD
|
||||||
info!(log, "Trying to initialize AtomicDrmDevice");
|
info!(log, "Trying to initialize AtomicDrmDevice");
|
||||||
|
|
||||||
if env::var("SMITHAY_USE_LEGACY")
|
if env::var("SMITHAY_USE_LEGACY")
|
||||||
.map(|x|
|
.map(|x| {
|
||||||
x == "1"
|
x == "1" || x.to_lowercase() == "true" || x.to_lowercase() == "yes" || x.to_lowercase() == "y"
|
||||||
|| x.to_lowercase() == "true"
|
})
|
||||||
|| x.to_lowercase() == "yes"
|
.unwrap_or(false)
|
||||||
|| x.to_lowercase() == "y"
|
|
||||||
).unwrap_or(false)
|
|
||||||
{
|
{
|
||||||
info!(log, "SMITHAY_USE_LEGACY is set. Forcing LegacyDrmDevice.");
|
info!(log, "SMITHAY_USE_LEGACY is set. Forcing LegacyDrmDevice.");
|
||||||
return Ok(FallbackDevice::Fallback(LegacyDrmDevice::new(fd, disable_connectors, log)?));
|
return Ok(FallbackDevice::Fallback(LegacyDrmDevice::new(
|
||||||
|
fd,
|
||||||
|
disable_connectors,
|
||||||
|
log,
|
||||||
|
)?));
|
||||||
}
|
}
|
||||||
|
|
||||||
match AtomicDrmDevice::new(fd.clone(), disable_connectors, log.clone()) {
|
match AtomicDrmDevice::new(fd.clone(), disable_connectors, log.clone()) {
|
||||||
|
@ -191,7 +193,11 @@ impl<A: AsRawFd + Clone + 'static> FallbackDevice<AtomicDrmDevice<A>, LegacyDrmD
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!(log, "Failed to initialize preferred AtomicDrmDevice: {}", err);
|
error!(log, "Failed to initialize preferred AtomicDrmDevice: {}", err);
|
||||||
info!(log, "Falling back to fallback LegacyDrmDevice");
|
info!(log, "Falling back to fallback LegacyDrmDevice");
|
||||||
Ok(FallbackDevice::Fallback(LegacyDrmDevice::new(fd, disable_connectors, log)?))
|
Ok(FallbackDevice::Fallback(LegacyDrmDevice::new(
|
||||||
|
fd,
|
||||||
|
disable_connectors,
|
||||||
|
log,
|
||||||
|
)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,10 +263,19 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fallback_device_impl!(clear_handler, &mut Self);
|
fallback_device_impl!(clear_handler, &mut Self);
|
||||||
fn create_surface(&mut self, crtc: crtc::Handle, mode: Mode, connectors: &[connector::Handle]) -> Result<Self::Surface, E> {
|
fn create_surface(
|
||||||
|
&mut self,
|
||||||
|
crtc: crtc::Handle,
|
||||||
|
mode: Mode,
|
||||||
|
connectors: &[connector::Handle],
|
||||||
|
) -> Result<Self::Surface, E> {
|
||||||
match self {
|
match self {
|
||||||
FallbackDevice::Preference(dev) => Ok(FallbackSurface::Preference(dev.create_surface(crtc, mode, connectors)?)),
|
FallbackDevice::Preference(dev) => Ok(FallbackSurface::Preference(
|
||||||
FallbackDevice::Fallback(dev) => Ok(FallbackSurface::Fallback(dev.create_surface(crtc, mode, connectors)?)),
|
dev.create_surface(crtc, mode, connectors)?,
|
||||||
|
)),
|
||||||
|
FallbackDevice::Fallback(dev) => Ok(FallbackSurface::Fallback(
|
||||||
|
dev.create_surface(crtc, mode, connectors)?,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fallback_device_impl!(process_events, &mut Self);
|
fallback_device_impl!(process_events, &mut Self);
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
//! and [`Surface`](::backend::drm::Surface) implementations of the `backend::drm` module.
|
//! and [`Surface`](::backend::drm::Surface) implementations of the `backend::drm` module.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
|
use crate::backend::graphics::SwapBuffersError;
|
||||||
use drm::control::{connector, crtc, Mode, RawResourceHandle};
|
use drm::control::{connector, crtc, Mode, RawResourceHandle};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use crate::backend::graphics::SwapBuffersError;
|
|
||||||
|
|
||||||
pub mod fallback;
|
pub mod fallback;
|
||||||
|
|
||||||
|
@ -81,10 +81,17 @@ impl Into<SwapBuffersError> for Error {
|
||||||
dev: _,
|
dev: _,
|
||||||
source,
|
source,
|
||||||
} if match source.get_ref() {
|
} if match source.get_ref() {
|
||||||
drm::SystemError::Unknown { errno: nix::errno::Errno::EBUSY } => true,
|
drm::SystemError::Unknown {
|
||||||
drm::SystemError::Unknown { errno: nix::errno::Errno::EINTR } => true,
|
errno: nix::errno::Errno::EBUSY,
|
||||||
|
} => true,
|
||||||
|
drm::SystemError::Unknown {
|
||||||
|
errno: nix::errno::Errno::EINTR,
|
||||||
|
} => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
} => SwapBuffersError::TemporaryFailure(Box::new(source)),
|
} =>
|
||||||
|
{
|
||||||
|
SwapBuffersError::TemporaryFailure(Box::new(source))
|
||||||
|
}
|
||||||
x => SwapBuffersError::ContextLost(Box::new(x)),
|
x => SwapBuffersError::ContextLost(Box::new(x)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,9 @@ use wayland_server::Display;
|
||||||
|
|
||||||
use super::{Device, DeviceHandler, Surface};
|
use super::{Device, DeviceHandler, Surface};
|
||||||
use crate::backend::egl::native::{Backend, NativeDisplay, NativeSurface};
|
use crate::backend::egl::native::{Backend, NativeDisplay, NativeSurface};
|
||||||
use crate::backend::egl::{Error as EGLError, EGLError as RawEGLError, SurfaceCreationError};
|
|
||||||
#[cfg(feature = "use_system_lib")]
|
#[cfg(feature = "use_system_lib")]
|
||||||
use crate::backend::egl::{display::EGLBufferReader, EGLGraphicsBackend};
|
use crate::backend::egl::{display::EGLBufferReader, EGLGraphicsBackend};
|
||||||
|
use crate::backend::egl::{EGLError as RawEGLError, Error as EGLError, SurfaceCreationError};
|
||||||
|
|
||||||
mod surface;
|
mod surface;
|
||||||
pub use self::surface::*;
|
pub use self::surface::*;
|
||||||
|
@ -49,7 +49,9 @@ type Arguments = (crtc::Handle, Mode, Vec<connector::Handle>);
|
||||||
pub struct EglDevice<B, D>
|
pub struct EglDevice<B, D>
|
||||||
where
|
where
|
||||||
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
||||||
D: Device + NativeDisplay<B, Arguments = Arguments, Error=<<D as Device>::Surface as Surface>::Error> + 'static,
|
D: Device
|
||||||
|
+ NativeDisplay<B, Arguments = Arguments, Error = <<D as Device>::Surface as Surface>::Error>
|
||||||
|
+ 'static,
|
||||||
<D as Device>::Surface: NativeSurface,
|
<D as Device>::Surface: NativeSurface,
|
||||||
{
|
{
|
||||||
dev: EGLDisplay<B, D>,
|
dev: EGLDisplay<B, D>,
|
||||||
|
@ -61,7 +63,9 @@ where
|
||||||
impl<B, D> AsRawFd for EglDevice<B, D>
|
impl<B, D> AsRawFd for EglDevice<B, D>
|
||||||
where
|
where
|
||||||
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
||||||
D: Device + NativeDisplay<B, Arguments = Arguments, Error=<<D as Device>::Surface as Surface>::Error> + 'static,
|
D: Device
|
||||||
|
+ NativeDisplay<B, Arguments = Arguments, Error = <<D as Device>::Surface as Surface>::Error>
|
||||||
|
+ 'static,
|
||||||
<D as Device>::Surface: NativeSurface,
|
<D as Device>::Surface: NativeSurface,
|
||||||
{
|
{
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
|
@ -72,7 +76,9 @@ where
|
||||||
impl<B, D> EglDevice<B, D>
|
impl<B, D> EglDevice<B, D>
|
||||||
where
|
where
|
||||||
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
||||||
D: Device + NativeDisplay<B, Arguments = Arguments, Error=<<D as Device>::Surface as Surface>::Error> + 'static,
|
D: Device
|
||||||
|
+ NativeDisplay<B, Arguments = Arguments, Error = <<D as Device>::Surface as Surface>::Error>
|
||||||
|
+ 'static,
|
||||||
<D as Device>::Surface: NativeSurface,
|
<D as Device>::Surface: NativeSurface,
|
||||||
{
|
{
|
||||||
/// Try to create a new [`EglDevice`] from an open device.
|
/// Try to create a new [`EglDevice`] from an open device.
|
||||||
|
@ -127,7 +133,9 @@ where
|
||||||
struct InternalDeviceHandler<B, D>
|
struct InternalDeviceHandler<B, D>
|
||||||
where
|
where
|
||||||
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
||||||
D: Device + NativeDisplay<B, Arguments = Arguments, Error=<<D as Device>::Surface as Surface>::Error> + 'static,
|
D: Device
|
||||||
|
+ NativeDisplay<B, Arguments = Arguments, Error = <<D as Device>::Surface as Surface>::Error>
|
||||||
|
+ 'static,
|
||||||
<D as Device>::Surface: NativeSurface,
|
<D as Device>::Surface: NativeSurface,
|
||||||
{
|
{
|
||||||
handler: Box<dyn DeviceHandler<Device = EglDevice<B, D>> + 'static>,
|
handler: Box<dyn DeviceHandler<Device = EglDevice<B, D>> + 'static>,
|
||||||
|
@ -136,7 +144,9 @@ where
|
||||||
impl<B, D> DeviceHandler for InternalDeviceHandler<B, D>
|
impl<B, D> DeviceHandler for InternalDeviceHandler<B, D>
|
||||||
where
|
where
|
||||||
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
||||||
D: Device + NativeDisplay<B, Arguments = Arguments, Error=<<D as Device>::Surface as Surface>::Error> + 'static,
|
D: Device
|
||||||
|
+ NativeDisplay<B, Arguments = Arguments, Error = <<D as Device>::Surface as Surface>::Error>
|
||||||
|
+ 'static,
|
||||||
<D as Device>::Surface: NativeSurface,
|
<D as Device>::Surface: NativeSurface,
|
||||||
{
|
{
|
||||||
type Device = D;
|
type Device = D;
|
||||||
|
@ -152,7 +162,9 @@ where
|
||||||
impl<B, D> Device for EglDevice<B, D>
|
impl<B, D> Device for EglDevice<B, D>
|
||||||
where
|
where
|
||||||
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
||||||
D: Device + NativeDisplay<B, Arguments = Arguments, Error=<<D as Device>::Surface as Surface>::Error> + 'static,
|
D: Device
|
||||||
|
+ NativeDisplay<B, Arguments = Arguments, Error = <<D as Device>::Surface as Surface>::Error>
|
||||||
|
+ 'static,
|
||||||
<D as Device>::Surface: NativeSurface,
|
<D as Device>::Surface: NativeSurface,
|
||||||
{
|
{
|
||||||
type Surface = EglSurface<<D as Device>::Surface>;
|
type Surface = EglSurface<<D as Device>::Surface>;
|
||||||
|
@ -231,7 +243,9 @@ where
|
||||||
impl<B, D> EGLGraphicsBackend for EglDevice<B, D>
|
impl<B, D> EGLGraphicsBackend for EglDevice<B, D>
|
||||||
where
|
where
|
||||||
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
||||||
D: Device + NativeDisplay<B, Arguments = Arguments, Error=<<D as Device>::Surface as Surface>::Error> + 'static,
|
D: Device
|
||||||
|
+ NativeDisplay<B, Arguments = Arguments, Error = <<D as Device>::Surface as Surface>::Error>
|
||||||
|
+ 'static,
|
||||||
<D as Device>::Surface: NativeSurface,
|
<D as Device>::Surface: NativeSurface,
|
||||||
{
|
{
|
||||||
fn bind_wl_display(&self, display: &Display) -> Result<EGLBufferReader, EGLError> {
|
fn bind_wl_display(&self, display: &Display) -> Result<EGLBufferReader, EGLError> {
|
||||||
|
@ -242,7 +256,9 @@ where
|
||||||
impl<B, D> Drop for EglDevice<B, D>
|
impl<B, D> Drop for EglDevice<B, D>
|
||||||
where
|
where
|
||||||
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
||||||
D: Device + NativeDisplay<B, Arguments = Arguments, Error=<<D as Device>::Surface as Surface>::Error> + 'static,
|
D: Device
|
||||||
|
+ NativeDisplay<B, Arguments = Arguments, Error = <<D as Device>::Surface as Surface>::Error>
|
||||||
|
+ 'static,
|
||||||
<D as Device>::Surface: NativeSurface,
|
<D as Device>::Surface: NativeSurface,
|
||||||
{
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//! to an open [`Session`](::backend::session::Session).
|
//! to an open [`Session`](::backend::session::Session).
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use drm::control::{crtc, connector, Mode};
|
use drm::control::{connector, crtc, Mode};
|
||||||
use std::os::unix::io::RawFd;
|
use std::os::unix::io::RawFd;
|
||||||
|
|
||||||
use super::EglDevice;
|
use super::EglDevice;
|
||||||
|
@ -22,7 +22,13 @@ impl<S, B, D> AsSessionObserver<EglDeviceObserver<S>> for EglDevice<B, D>
|
||||||
where
|
where
|
||||||
S: SessionObserver + 'static,
|
S: SessionObserver + 'static,
|
||||||
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
||||||
D: Device + NativeDisplay<B, Arguments = (crtc::Handle, Mode, Vec<connector::Handle>), Error=<<D as Device>::Surface as Surface>::Error> + AsSessionObserver<S> + 'static,
|
D: Device
|
||||||
|
+ NativeDisplay<
|
||||||
|
B,
|
||||||
|
Arguments = (crtc::Handle, Mode, Vec<connector::Handle>),
|
||||||
|
Error = <<D as Device>::Surface as Surface>::Error,
|
||||||
|
> + AsSessionObserver<S>
|
||||||
|
+ 'static,
|
||||||
<D as Device>::Surface: NativeSurface,
|
<D as Device>::Surface: NativeSurface,
|
||||||
{
|
{
|
||||||
fn observer(&mut self) -> EglDeviceObserver<S> {
|
fn observer(&mut self) -> EglDeviceObserver<S> {
|
||||||
|
|
|
@ -99,7 +99,9 @@ where
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(x) => x.into(),
|
Err(x) => x.into(),
|
||||||
})
|
})
|
||||||
} else { Ok(()) }
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_proc_address(&self, symbol: &str) -> *const c_void {
|
fn get_proc_address(&self, symbol: &str) -> *const c_void {
|
||||||
|
@ -116,7 +118,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn make_current(&self) -> ::std::result::Result<(), SwapBuffersError> {
|
unsafe fn make_current(&self) -> ::std::result::Result<(), SwapBuffersError> {
|
||||||
self.context.make_current_with_surface(&self.surface).map_err(Into::into)
|
self.context
|
||||||
|
.make_current_with_surface(&self.surface)
|
||||||
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_pixel_format(&self) -> PixelFormat {
|
fn get_pixel_format(&self) -> PixelFormat {
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
use crate::backend::drm::{Device, RawDevice, Surface};
|
use crate::backend::drm::{Device, RawDevice, Surface};
|
||||||
use crate::backend::egl::ffi;
|
use crate::backend::egl::ffi;
|
||||||
use crate::backend::egl::native::{Backend, NativeDisplay, NativeSurface};
|
use crate::backend::egl::native::{Backend, NativeDisplay, NativeSurface};
|
||||||
use crate::backend::egl::{Error as EglBackendError, EGLError, wrap_egl_call};
|
use crate::backend::egl::{wrap_egl_call, EGLError, Error as EglBackendError};
|
||||||
|
|
||||||
use super::{Error, GbmDevice, GbmSurface};
|
use super::{Error, GbmDevice, GbmSurface};
|
||||||
|
|
||||||
use drm::control::{crtc, connector, Device as ControlDevice, Mode};
|
use drm::control::{connector, crtc, Device as ControlDevice, Mode};
|
||||||
use gbm::AsRaw;
|
use gbm::AsRaw;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
@ -36,13 +36,19 @@ impl<D: RawDevice + 'static> Backend for Gbm<D> {
|
||||||
{
|
{
|
||||||
if has_dp_extension("EGL_KHR_platform_gbm") && ffi::egl::GetPlatformDisplay::is_loaded() {
|
if has_dp_extension("EGL_KHR_platform_gbm") && ffi::egl::GetPlatformDisplay::is_loaded() {
|
||||||
trace!(log, "EGL Display Initialization via EGL_KHR_platform_gbm");
|
trace!(log, "EGL Display Initialization via EGL_KHR_platform_gbm");
|
||||||
wrap_egl_call(|| ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_GBM_KHR, display as *mut _, ptr::null()))
|
wrap_egl_call(|| {
|
||||||
|
ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_GBM_KHR, display as *mut _, ptr::null())
|
||||||
|
})
|
||||||
} else if has_dp_extension("EGL_MESA_platform_gbm") && ffi::egl::GetPlatformDisplayEXT::is_loaded() {
|
} else if has_dp_extension("EGL_MESA_platform_gbm") && ffi::egl::GetPlatformDisplayEXT::is_loaded() {
|
||||||
trace!(log, "EGL Display Initialization via EGL_MESA_platform_gbm");
|
trace!(log, "EGL Display Initialization via EGL_MESA_platform_gbm");
|
||||||
wrap_egl_call(|| ffi::egl::GetPlatformDisplayEXT(ffi::egl::PLATFORM_GBM_MESA, display as *mut _, ptr::null()))
|
wrap_egl_call(|| {
|
||||||
|
ffi::egl::GetPlatformDisplayEXT(ffi::egl::PLATFORM_GBM_MESA, display as *mut _, ptr::null())
|
||||||
|
})
|
||||||
} else if has_dp_extension("EGL_MESA_platform_gbm") && ffi::egl::GetPlatformDisplay::is_loaded() {
|
} else if has_dp_extension("EGL_MESA_platform_gbm") && ffi::egl::GetPlatformDisplay::is_loaded() {
|
||||||
trace!(log, "EGL Display Initialization via EGL_MESA_platform_gbm");
|
trace!(log, "EGL Display Initialization via EGL_MESA_platform_gbm");
|
||||||
wrap_egl_call(|| ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_GBM_MESA, display as *mut _, ptr::null()))
|
wrap_egl_call(|| {
|
||||||
|
ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_GBM_MESA, display as *mut _, ptr::null())
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
trace!(log, "Default EGL Display Initialization via GetDisplay");
|
trace!(log, "Default EGL Display Initialization via GetDisplay");
|
||||||
wrap_egl_call(|| ffi::egl::GetDisplay(display as *mut _))
|
wrap_egl_call(|| ffi::egl::GetDisplay(display as *mut _))
|
||||||
|
|
|
@ -171,13 +171,11 @@ impl<D: RawDevice + ControlDevice + 'static> Device for GbmDevice<D> {
|
||||||
) -> Result<GbmSurface<D>, Error<<<D as Device>::Surface as Surface>::Error>> {
|
) -> Result<GbmSurface<D>, Error<<<D as Device>::Surface as Surface>::Error>> {
|
||||||
info!(self.logger, "Initializing GbmSurface");
|
info!(self.logger, "Initializing GbmSurface");
|
||||||
|
|
||||||
let drm_surface =
|
let drm_surface = Device::create_surface(&mut **self.dev.borrow_mut(), crtc, mode, connectors)
|
||||||
Device::create_surface(&mut **self.dev.borrow_mut(), crtc, mode, connectors).map_err(Error::Underlying)?;
|
.map_err(Error::Underlying)?;
|
||||||
|
|
||||||
// initialize the surface
|
// initialize the surface
|
||||||
let (w, h) = drm_surface
|
let (w, h) = drm_surface.pending_mode().size();
|
||||||
.pending_mode()
|
|
||||||
.size();
|
|
||||||
let surface = self
|
let surface = self
|
||||||
.dev
|
.dev
|
||||||
.borrow()
|
.borrow()
|
||||||
|
@ -260,16 +258,24 @@ impl<D: RawDevice + ControlDevice + 'static> Drop for GbmDevice<D> {
|
||||||
|
|
||||||
impl<E> Into<SwapBuffersError> for Error<E>
|
impl<E> Into<SwapBuffersError> for Error<E>
|
||||||
where
|
where
|
||||||
E: std::error::Error + Into<SwapBuffersError> + 'static
|
E: std::error::Error + Into<SwapBuffersError> + 'static,
|
||||||
{
|
{
|
||||||
fn into(self) -> SwapBuffersError {
|
fn into(self) -> SwapBuffersError {
|
||||||
match self {
|
match self {
|
||||||
Error::FrontBuffersExhausted => SwapBuffersError::AlreadySwapped,
|
Error::FrontBuffersExhausted => SwapBuffersError::AlreadySwapped,
|
||||||
Error::FramebufferCreationFailed(x) if match x.get_ref() {
|
Error::FramebufferCreationFailed(x)
|
||||||
&drm::SystemError::Unknown { errno: nix::errno::Errno::EBUSY } => true,
|
if match x.get_ref() {
|
||||||
&drm::SystemError::Unknown { errno: nix::errno::Errno::EINTR } => true,
|
&drm::SystemError::Unknown {
|
||||||
_ => false
|
errno: nix::errno::Errno::EBUSY,
|
||||||
} => SwapBuffersError::TemporaryFailure(Box::new(x)),
|
} => true,
|
||||||
|
&drm::SystemError::Unknown {
|
||||||
|
errno: nix::errno::Errno::EINTR,
|
||||||
|
} => true,
|
||||||
|
_ => false,
|
||||||
|
} =>
|
||||||
|
{
|
||||||
|
SwapBuffersError::TemporaryFailure(Box::new(x))
|
||||||
|
}
|
||||||
Error::Underlying(x) => x.into(),
|
Error::Underlying(x) => x.into(),
|
||||||
x => SwapBuffersError::ContextLost(Box::new(x)),
|
x => SwapBuffersError::ContextLost(Box::new(x)),
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,9 +81,7 @@ impl<
|
||||||
|
|
||||||
let &(ref cursor, ref hotspot): &(BufferObject<()>, (u32, u32)) =
|
let &(ref cursor, ref hotspot): &(BufferObject<()>, (u32, u32)) =
|
||||||
unsafe { &*backend.cursor.as_ptr() };
|
unsafe { &*backend.cursor.as_ptr() };
|
||||||
if backend.crtc.set_cursor_representation(cursor, *hotspot)
|
if backend.crtc.set_cursor_representation(cursor, *hotspot).is_err() {
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
if let Err(err) = backend.dev.borrow().set_cursor(*crtc, Some(cursor)) {
|
if let Err(err) = backend.dev.borrow().set_cursor(*crtc, Some(cursor)) {
|
||||||
error!(self.logger, "Failed to reset cursor. Error: {}", err);
|
error!(self.logger, "Failed to reset cursor. Error: {}", err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ use super::super::{Device, RawDevice, RawSurface, Surface};
|
||||||
use super::Error;
|
use super::Error;
|
||||||
|
|
||||||
use drm::control::{connector, crtc, framebuffer, Device as ControlDevice, Mode};
|
use drm::control::{connector, crtc, framebuffer, Device as ControlDevice, Mode};
|
||||||
|
use failure::ResultExt;
|
||||||
use gbm::{self, BufferObject, BufferObjectFlags, Format as GbmFormat, SurfaceBufferHandle};
|
use gbm::{self, BufferObject, BufferObjectFlags, Format as GbmFormat, SurfaceBufferHandle};
|
||||||
use image::{ImageBuffer, Rgba};
|
use image::{ImageBuffer, Rgba};
|
||||||
use failure::ResultExt;
|
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -89,9 +89,7 @@ impl<D: RawDevice + 'static> GbmSurfaceInternal<D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recreate(&self) -> Result<(), Error<<<D as Device>::Surface as Surface>::Error>> {
|
pub fn recreate(&self) -> Result<(), Error<<<D as Device>::Surface as Surface>::Error>> {
|
||||||
let (w, h) = self
|
let (w, h) = self.pending_mode().size();
|
||||||
.pending_mode()
|
|
||||||
.size();
|
|
||||||
|
|
||||||
// Recreate the surface and the related resources to match the new
|
// Recreate the surface and the related resources to match the new
|
||||||
// resolution.
|
// resolution.
|
||||||
|
|
|
@ -190,32 +190,54 @@ impl<A: AsRawFd + 'static> LegacyDrmDevice<A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: AsRawFd + 'static> Dev<A> {
|
impl<A: AsRawFd + 'static> Dev<A> {
|
||||||
pub(in crate::backend::drm::legacy) fn set_connector_state(&self, connectors: impl Iterator<Item=connector::Handle>, enabled: bool) -> Result<(), Error> {
|
pub(in crate::backend::drm::legacy) fn set_connector_state(
|
||||||
|
&self,
|
||||||
|
connectors: impl Iterator<Item = connector::Handle>,
|
||||||
|
enabled: bool,
|
||||||
|
) -> Result<(), Error> {
|
||||||
for conn in connectors {
|
for conn in connectors {
|
||||||
let info = self.get_connector(conn).compat().map_err(|source| Error::Access {
|
let info = self
|
||||||
|
.get_connector(conn)
|
||||||
|
.compat()
|
||||||
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Failed to get connector infos",
|
errmsg: "Failed to get connector infos",
|
||||||
dev: self.dev_path(),
|
dev: self.dev_path(),
|
||||||
source
|
source,
|
||||||
})?;
|
})?;
|
||||||
if info.state() == connector::State::Connected {
|
if info.state() == connector::State::Connected {
|
||||||
let props = self.get_properties(conn).compat().map_err(|source| Error::Access {
|
let props = self
|
||||||
|
.get_properties(conn)
|
||||||
|
.compat()
|
||||||
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Failed to get properties for connector",
|
errmsg: "Failed to get properties for connector",
|
||||||
dev: self.dev_path(),
|
dev: self.dev_path(),
|
||||||
source
|
source,
|
||||||
})?;
|
})?;
|
||||||
let (handles, _) = props.as_props_and_values();
|
let (handles, _) = props.as_props_and_values();
|
||||||
for handle in handles {
|
for handle in handles {
|
||||||
let info = self.get_property(*handle).compat().map_err(|source| Error::Access {
|
let info = self
|
||||||
|
.get_property(*handle)
|
||||||
|
.compat()
|
||||||
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Failed to get property of connector",
|
errmsg: "Failed to get property of connector",
|
||||||
dev: self.dev_path(),
|
dev: self.dev_path(),
|
||||||
source
|
source,
|
||||||
})?;
|
})?;
|
||||||
if info.name().to_str().map(|x| x == "DPMS").unwrap_or(false) {
|
if info.name().to_str().map(|x| x == "DPMS").unwrap_or(false) {
|
||||||
self.set_property(conn, *handle, if enabled { 0 /*DRM_MODE_DPMS_ON*/} else { 3 /*DRM_MODE_DPMS_OFF*/})
|
self.set_property(
|
||||||
.compat().map_err(|source| Error::Access {
|
conn,
|
||||||
|
*handle,
|
||||||
|
if enabled {
|
||||||
|
0 /*DRM_MODE_DPMS_ON*/
|
||||||
|
} else {
|
||||||
|
3 /*DRM_MODE_DPMS_OFF*/
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.compat()
|
||||||
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Failed to set property of connector",
|
errmsg: "Failed to set property of connector",
|
||||||
dev: self.dev_path(),
|
dev: self.dev_path(),
|
||||||
source
|
source,
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,7 +271,12 @@ impl<A: AsRawFd + 'static> Device for LegacyDrmDevice<A> {
|
||||||
let _ = self.handler.take();
|
let _ = self.handler.take();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_surface(&mut self, crtc: crtc::Handle, mode: Mode, connectors: &[connector::Handle]) -> Result<LegacyDrmSurface<A>, Error> {
|
fn create_surface(
|
||||||
|
&mut self,
|
||||||
|
crtc: crtc::Handle,
|
||||||
|
mode: Mode,
|
||||||
|
connectors: &[connector::Handle],
|
||||||
|
) -> Result<LegacyDrmSurface<A>, Error> {
|
||||||
if self.backends.borrow().contains_key(&crtc) {
|
if self.backends.borrow().contains_key(&crtc) {
|
||||||
return Err(Error::CrtcAlreadyInUse(crtc));
|
return Err(Error::CrtcAlreadyInUse(crtc));
|
||||||
}
|
}
|
||||||
|
@ -263,7 +290,10 @@ impl<A: AsRawFd + 'static> Device for LegacyDrmDevice<A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let backend = Rc::new(LegacyDrmSurfaceInternal::new(
|
let backend = Rc::new(LegacyDrmSurfaceInternal::new(
|
||||||
self.dev.clone(), crtc, mode, connectors,
|
self.dev.clone(),
|
||||||
|
crtc,
|
||||||
|
mode,
|
||||||
|
connectors,
|
||||||
self.logger.new(o!("crtc" => format!("{:?}", crtc))),
|
self.logger.new(o!("crtc" => format!("{:?}", crtc))),
|
||||||
)?);
|
)?);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
use drm::control::{crtc, Device as ControlDevice};
|
use drm::control::{crtc, Device as ControlDevice};
|
||||||
use drm::Device as BasicDevice;
|
use drm::Device as BasicDevice;
|
||||||
|
use failure::ResultExt;
|
||||||
use nix::libc::dev_t;
|
use nix::libc::dev_t;
|
||||||
use nix::sys::stat;
|
use nix::sys::stat;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
@ -13,9 +14,8 @@ use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use failure::ResultExt;
|
|
||||||
|
|
||||||
use super::{Dev, LegacyDrmDevice, LegacyDrmSurfaceInternal, Error, DevPath};
|
use super::{Dev, DevPath, Error, LegacyDrmDevice, LegacyDrmSurfaceInternal};
|
||||||
use crate::backend::session::{AsSessionObserver, SessionObserver};
|
use crate::backend::session::{AsSessionObserver, SessionObserver};
|
||||||
|
|
||||||
/// [`SessionObserver`](SessionObserver)
|
/// [`SessionObserver`](SessionObserver)
|
||||||
|
@ -125,7 +125,10 @@ impl<A: AsRawFd + 'static> LegacyDrmDeviceObserver<A> {
|
||||||
// set current connectors
|
// set current connectors
|
||||||
current.connectors.clear();
|
current.connectors.clear();
|
||||||
for conn in res_handles.connectors() {
|
for conn in res_handles.connectors() {
|
||||||
let conn_info = dev.get_connector(*conn).compat().map_err(|source| Error::Access {
|
let conn_info =
|
||||||
|
dev.get_connector(*conn)
|
||||||
|
.compat()
|
||||||
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Could not load connector info",
|
errmsg: "Could not load connector info",
|
||||||
dev: dev.dev_path(),
|
dev: dev.dev_path(),
|
||||||
source,
|
source,
|
||||||
|
@ -143,7 +146,10 @@ impl<A: AsRawFd + 'static> LegacyDrmDeviceObserver<A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// set current mode
|
// set current mode
|
||||||
let crtc_info = dev.get_crtc(surface.crtc).compat().map_err(|source| Error::Access {
|
let crtc_info = dev
|
||||||
|
.get_crtc(surface.crtc)
|
||||||
|
.compat()
|
||||||
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Could not load crtc info",
|
errmsg: "Could not load crtc info",
|
||||||
dev: dev.dev_path(),
|
dev: dev.dev_path(),
|
||||||
source,
|
source,
|
||||||
|
|
|
@ -8,7 +8,7 @@ use drm::Device as BasicDevice;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::{RwLock, atomic::Ordering};
|
use std::sync::{atomic::Ordering, RwLock};
|
||||||
|
|
||||||
use crate::backend::drm::{common::Error, DevPath, RawSurface, Surface};
|
use crate::backend::drm::{common::Error, DevPath, RawSurface, Surface};
|
||||||
use crate::backend::graphics::CursorBackend;
|
use crate::backend::graphics::CursorBackend;
|
||||||
|
@ -241,11 +241,7 @@ impl<A: AsRawFd + 'static> RawSurface for LegacyDrmSurfaceInternal<A> {
|
||||||
self.dev.set_connector_state(added.copied(), true)?;
|
self.dev.set_connector_state(added.copied(), true)?;
|
||||||
|
|
||||||
if current.mode != pending.mode {
|
if current.mode != pending.mode {
|
||||||
info!(
|
info!(self.logger, "Setting new mode: {:?}", pending.mode.name());
|
||||||
self.logger,
|
|
||||||
"Setting new mode: {:?}",
|
|
||||||
pending.mode.name()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +293,8 @@ impl<A: AsRawFd + 'static> RawSurface for LegacyDrmSurfaceInternal<A> {
|
||||||
framebuffer,
|
framebuffer,
|
||||||
&[PageFlipFlags::PageFlipEvent],
|
&[PageFlipFlags::PageFlipEvent],
|
||||||
None,
|
None,
|
||||||
).compat()
|
)
|
||||||
|
.compat()
|
||||||
.map_err(|source| Error::Access {
|
.map_err(|source| Error::Access {
|
||||||
errmsg: "Failed to page flip",
|
errmsg: "Failed to page flip",
|
||||||
dev: self.dev_path(),
|
dev: self.dev_path(),
|
||||||
|
@ -307,7 +304,13 @@ impl<A: AsRawFd + 'static> RawSurface for LegacyDrmSurfaceInternal<A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: AsRawFd + 'static> LegacyDrmSurfaceInternal<A> {
|
impl<A: AsRawFd + 'static> LegacyDrmSurfaceInternal<A> {
|
||||||
pub(crate) fn new(dev: Rc<Dev<A>>, crtc: crtc::Handle, mode: Mode, connectors: &[connector::Handle], logger: ::slog::Logger) -> Result<LegacyDrmSurfaceInternal<A>, Error> {
|
pub(crate) fn new(
|
||||||
|
dev: Rc<Dev<A>>,
|
||||||
|
crtc: crtc::Handle,
|
||||||
|
mode: Mode,
|
||||||
|
connectors: &[connector::Handle],
|
||||||
|
logger: ::slog::Logger,
|
||||||
|
) -> Result<LegacyDrmSurfaceInternal<A>, Error> {
|
||||||
// Try to enumarate the current state to set the initial state variable correctly
|
// Try to enumarate the current state to set the initial state variable correctly
|
||||||
let crtc_info = dev.get_crtc(crtc).compat().map_err(|source| Error::Access {
|
let crtc_info = dev.get_crtc(crtc).compat().map_err(|source| Error::Access {
|
||||||
errmsg: "Error loading crtc info",
|
errmsg: "Error loading crtc info",
|
||||||
|
@ -349,8 +352,14 @@ impl<A: AsRawFd + 'static> LegacyDrmSurfaceInternal<A> {
|
||||||
// A better fix would probably be making mode an `Option`, but that would mean
|
// A better fix would probably be making mode an `Option`, but that would mean
|
||||||
// we need to be sure, we require a mode to always be set without relying on the compiler.
|
// we need to be sure, we require a mode to always be set without relying on the compiler.
|
||||||
// So we cheat, because it works and is easier to handle later.
|
// So we cheat, because it works and is easier to handle later.
|
||||||
let state = State { mode: current_mode.unwrap_or_else(|| unsafe { std::mem::zeroed() }), connectors: current_connectors };
|
let state = State {
|
||||||
let pending = State { mode, connectors: connectors.into_iter().copied().collect() };
|
mode: current_mode.unwrap_or_else(|| unsafe { std::mem::zeroed() }),
|
||||||
|
connectors: current_connectors,
|
||||||
|
};
|
||||||
|
let pending = State {
|
||||||
|
mode,
|
||||||
|
connectors: connectors.into_iter().copied().collect(),
|
||||||
|
};
|
||||||
|
|
||||||
let surface = LegacyDrmSurfaceInternal {
|
let surface = LegacyDrmSurfaceInternal {
|
||||||
dev,
|
dev,
|
||||||
|
@ -428,7 +437,10 @@ impl<A: AsRawFd + 'static> Drop for LegacyDrmSurfaceInternal<A> {
|
||||||
let _ = self.set_cursor(self.crtc, Option::<&DumbBuffer>::None);
|
let _ = self.set_cursor(self.crtc, Option::<&DumbBuffer>::None);
|
||||||
// disable connectors again
|
// disable connectors again
|
||||||
let current = self.state.read().unwrap();
|
let current = self.state.read().unwrap();
|
||||||
if let Ok(_) = self.dev.set_connector_state(current.connectors.iter().copied(), false) {
|
if let Ok(_) = self
|
||||||
|
.dev
|
||||||
|
.set_connector_state(current.connectors.iter().copied(), false)
|
||||||
|
{
|
||||||
// null commit
|
// null commit
|
||||||
let _ = self.set_crtc(self.crtc, None, (0, 0), &[], None);
|
let _ = self.set_crtc(self.crtc, None, (0, 0), &[], None);
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ pub trait Device: AsRawFd + DevPath {
|
||||||
&mut self,
|
&mut self,
|
||||||
crtc: crtc::Handle,
|
crtc: crtc::Handle,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
connectors: &[connector::Handle]
|
connectors: &[connector::Handle],
|
||||||
) -> Result<Self::Surface, <Self::Surface as Surface>::Error>;
|
) -> Result<Self::Surface, <Self::Surface as Surface>::Error>;
|
||||||
|
|
||||||
/// Processes any open events of the underlying file descriptor.
|
/// Processes any open events of the underlying file descriptor.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! EGL context related structs
|
//! EGL context related structs
|
||||||
|
|
||||||
use super::{ffi, Error, MakeCurrentError, wrap_egl_call};
|
use super::{ffi, wrap_egl_call, Error, MakeCurrentError};
|
||||||
use crate::backend::egl::display::{EGLDisplay, EGLDisplayHandle};
|
use crate::backend::egl::display::{EGLDisplay, EGLDisplayHandle};
|
||||||
use crate::backend::egl::native::NativeSurface;
|
use crate::backend::egl::native::NativeSurface;
|
||||||
use crate::backend::egl::{native, EGLSurface};
|
use crate::backend::egl::{native, EGLSurface};
|
||||||
|
@ -100,7 +100,8 @@ impl EGLContext {
|
||||||
ptr::null(),
|
ptr::null(),
|
||||||
context_attributes.as_ptr(),
|
context_attributes.as_ptr(),
|
||||||
)
|
)
|
||||||
}).map_err(Error::CreationFailed)?;
|
})
|
||||||
|
.map_err(Error::CreationFailed)?;
|
||||||
|
|
||||||
info!(log, "EGL context created");
|
info!(log, "EGL context created");
|
||||||
|
|
||||||
|
@ -119,16 +120,15 @@ impl EGLContext {
|
||||||
///
|
///
|
||||||
/// This function is marked unsafe, because the context cannot be made current
|
/// This function is marked unsafe, because the context cannot be made current
|
||||||
/// on multiple threads.
|
/// on multiple threads.
|
||||||
pub unsafe fn make_current_with_surface<N>(
|
pub unsafe fn make_current_with_surface<N>(&self, surface: &EGLSurface<N>) -> Result<(), MakeCurrentError>
|
||||||
&self,
|
|
||||||
surface: &EGLSurface<N>,
|
|
||||||
) -> Result<(), MakeCurrentError>
|
|
||||||
where
|
where
|
||||||
N: NativeSurface,
|
N: NativeSurface,
|
||||||
{
|
{
|
||||||
let surface_ptr = surface.surface.get();
|
let surface_ptr = surface.surface.get();
|
||||||
|
|
||||||
wrap_egl_call(|| ffi::egl::MakeCurrent(**self.display, surface_ptr, surface_ptr, self.context)).map(|_| ()).map_err(Into::into)
|
wrap_egl_call(|| ffi::egl::MakeCurrent(**self.display, surface_ptr, surface_ptr, self.context))
|
||||||
|
.map(|_| ())
|
||||||
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes the OpenGL context the current context in the current thread with no surface bound.
|
/// Makes the OpenGL context the current context in the current thread with no surface bound.
|
||||||
|
@ -138,7 +138,16 @@ impl EGLContext {
|
||||||
/// This function is marked unsafe, because the context cannot be made current
|
/// This function is marked unsafe, because the context cannot be made current
|
||||||
/// on multiple threads without being unbound again (see `unbind`)
|
/// on multiple threads without being unbound again (see `unbind`)
|
||||||
pub unsafe fn make_current(&self) -> Result<(), MakeCurrentError> {
|
pub unsafe fn make_current(&self) -> Result<(), MakeCurrentError> {
|
||||||
wrap_egl_call(|| ffi::egl::MakeCurrent(**self.display, ffi::egl::NO_SURFACE, ffi::egl::NO_SURFACE, self.context)).map(|_| ()).map_err(Into::into)
|
wrap_egl_call(|| {
|
||||||
|
ffi::egl::MakeCurrent(
|
||||||
|
**self.display,
|
||||||
|
ffi::egl::NO_SURFACE,
|
||||||
|
ffi::egl::NO_SURFACE,
|
||||||
|
self.context,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.map(|_| ())
|
||||||
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the OpenGL context is the current one in the thread.
|
/// Returns true if the OpenGL context is the current one in the thread.
|
||||||
|
@ -161,7 +170,14 @@ impl EGLContext {
|
||||||
/// This does nothing if this context is not the current context
|
/// This does nothing if this context is not the current context
|
||||||
pub fn unbind(&self) -> Result<(), MakeCurrentError> {
|
pub fn unbind(&self) -> Result<(), MakeCurrentError> {
|
||||||
if self.is_current() {
|
if self.is_current() {
|
||||||
wrap_egl_call(|| unsafe { ffi::egl::MakeCurrent(**self.display, ffi::egl::NO_SURFACE, ffi::egl::NO_SURFACE, ffi::egl::NO_CONTEXT)})?;
|
wrap_egl_call(|| unsafe {
|
||||||
|
ffi::egl::MakeCurrent(
|
||||||
|
**self.display,
|
||||||
|
ffi::egl::NO_SURFACE,
|
||||||
|
ffi::egl::NO_SURFACE,
|
||||||
|
ffi::egl::NO_CONTEXT,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
#[cfg(feature = "use_system_lib")]
|
#[cfg(feature = "use_system_lib")]
|
||||||
use crate::backend::egl::EGLGraphicsBackend;
|
use crate::backend::egl::EGLGraphicsBackend;
|
||||||
use crate::backend::egl::{
|
use crate::backend::egl::{
|
||||||
ffi, get_proc_address, native, BufferAccessError, SurfaceCreationError, EGLContext, EGLImages, EGLSurface, Error, Format, EGLError, wrap_egl_call,
|
ffi, get_proc_address, native, wrap_egl_call, BufferAccessError, EGLContext, EGLError, EGLImages,
|
||||||
|
EGLSurface, Error, Format, SurfaceCreationError,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -94,7 +95,9 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLDisplay<B, N> {
|
||||||
|
|
||||||
// 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
|
||||||
let dp_extensions = unsafe {
|
let dp_extensions = unsafe {
|
||||||
let p = wrap_egl_call(|| ffi::egl::QueryString(ffi::egl::NO_DISPLAY, ffi::egl::EXTENSIONS as i32)).map_err(Error::InitFailed)?;
|
let p =
|
||||||
|
wrap_egl_call(|| ffi::egl::QueryString(ffi::egl::NO_DISPLAY, ffi::egl::EXTENSIONS as i32))
|
||||||
|
.map_err(Error::InitFailed)?;
|
||||||
|
|
||||||
// this possibility is available only with EGL 1.5 or EGL_EXT_platform_base, otherwise
|
// this possibility is available only with EGL 1.5 or EGL_EXT_platform_base, otherwise
|
||||||
// `eglQueryString` returns an error
|
// `eglQueryString` returns an error
|
||||||
|
@ -108,13 +111,19 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLDisplay<B, N> {
|
||||||
};
|
};
|
||||||
debug!(log, "EGL No-Display Extensions: {:?}", dp_extensions);
|
debug!(log, "EGL No-Display Extensions: {:?}", dp_extensions);
|
||||||
|
|
||||||
let display = unsafe { B::get_display(ptr, |e: &str| dp_extensions.iter().any(|s| s == e), log.clone()).map_err(Error::DisplayNotSupported)? };
|
let display = unsafe {
|
||||||
|
B::get_display(ptr, |e: &str| dp_extensions.iter().any(|s| s == e), log.clone())
|
||||||
|
.map_err(Error::DisplayNotSupported)?
|
||||||
|
};
|
||||||
|
|
||||||
let egl_version = {
|
let egl_version = {
|
||||||
let mut major: MaybeUninit<ffi::egl::types::EGLint> = MaybeUninit::uninit();
|
let mut major: MaybeUninit<ffi::egl::types::EGLint> = MaybeUninit::uninit();
|
||||||
let mut minor: MaybeUninit<ffi::egl::types::EGLint> = MaybeUninit::uninit();
|
let mut minor: MaybeUninit<ffi::egl::types::EGLint> = MaybeUninit::uninit();
|
||||||
|
|
||||||
wrap_egl_call(|| unsafe { ffi::egl::Initialize(display, major.as_mut_ptr(), minor.as_mut_ptr()) }).map_err(Error::InitFailed)?;
|
wrap_egl_call(|| unsafe {
|
||||||
|
ffi::egl::Initialize(display, major.as_mut_ptr(), minor.as_mut_ptr())
|
||||||
|
})
|
||||||
|
.map_err(Error::InitFailed)?;
|
||||||
|
|
||||||
let major = unsafe { major.assume_init() };
|
let major = unsafe { major.assume_init() };
|
||||||
let minor = unsafe { minor.assume_init() };
|
let minor = unsafe { minor.assume_init() };
|
||||||
|
@ -128,7 +137,12 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLDisplay<B, N> {
|
||||||
// the list of extensions supported by the client once initialized is different from the
|
// the list of extensions supported by the client once initialized is different from the
|
||||||
// list of extensions obtained earlier
|
// list of extensions obtained earlier
|
||||||
let extensions = if egl_version >= (1, 2) {
|
let extensions = if egl_version >= (1, 2) {
|
||||||
let p = unsafe { CStr::from_ptr(wrap_egl_call(|| ffi::egl::QueryString(display, ffi::egl::EXTENSIONS as i32)).map_err(Error::InitFailed)?) };
|
let p = unsafe {
|
||||||
|
CStr::from_ptr(
|
||||||
|
wrap_egl_call(|| ffi::egl::QueryString(display, ffi::egl::EXTENSIONS as i32))
|
||||||
|
.map_err(Error::InitFailed)?,
|
||||||
|
)
|
||||||
|
};
|
||||||
let list = String::from_utf8(p.to_bytes().to_vec()).unwrap_or_else(|_| String::new());
|
let list = String::from_utf8(p.to_bytes().to_vec()).unwrap_or_else(|_| String::new());
|
||||||
list.split(' ').map(|e| e.to_string()).collect::<Vec<_>>()
|
list.split(' ').map(|e| e.to_string()).collect::<Vec<_>>()
|
||||||
} else {
|
} else {
|
||||||
|
@ -139,7 +153,8 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLDisplay<B, N> {
|
||||||
if egl_version >= (1, 2) {
|
if egl_version >= (1, 2) {
|
||||||
return Err(Error::OpenGlesNotSupported(None));
|
return Err(Error::OpenGlesNotSupported(None));
|
||||||
}
|
}
|
||||||
wrap_egl_call(|| unsafe { ffi::egl::BindAPI(ffi::egl::OPENGL_ES_API) }).map_err(|source| Error::OpenGlesNotSupported(Some(source)))?;
|
wrap_egl_call(|| unsafe { ffi::egl::BindAPI(ffi::egl::OPENGL_ES_API) })
|
||||||
|
.map_err(|source| Error::OpenGlesNotSupported(Some(source)))?;
|
||||||
|
|
||||||
Ok(EGLDisplay {
|
Ok(EGLDisplay {
|
||||||
native: RefCell::new(native),
|
native: RefCell::new(native),
|
||||||
|
@ -212,7 +227,8 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLDisplay<B, N> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
reqs.create_attributes(&mut out, &self.logger).map_err(|()| Error::NoAvailablePixelFormat)?;
|
reqs.create_attributes(&mut out, &self.logger)
|
||||||
|
.map_err(|()| Error::NoAvailablePixelFormat)?;
|
||||||
|
|
||||||
out.push(ffi::egl::NONE as c_int);
|
out.push(ffi::egl::NONE as c_int);
|
||||||
out
|
out
|
||||||
|
@ -228,7 +244,8 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLDisplay<B, N> {
|
||||||
0,
|
0,
|
||||||
&mut num_configs,
|
&mut num_configs,
|
||||||
)
|
)
|
||||||
}).map_err(Error::ConfigFailed)?;
|
})
|
||||||
|
.map_err(Error::ConfigFailed)?;
|
||||||
if num_configs == 0 {
|
if num_configs == 0 {
|
||||||
return Err(Error::NoAvailablePixelFormat);
|
return Err(Error::NoAvailablePixelFormat);
|
||||||
}
|
}
|
||||||
|
@ -242,8 +259,11 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLDisplay<B, N> {
|
||||||
num_configs,
|
num_configs,
|
||||||
&mut num_configs,
|
&mut num_configs,
|
||||||
)
|
)
|
||||||
}).map_err(Error::ConfigFailed)?;
|
})
|
||||||
unsafe { config_ids.set_len(num_configs as usize); }
|
.map_err(Error::ConfigFailed)?;
|
||||||
|
unsafe {
|
||||||
|
config_ids.set_len(num_configs as usize);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Deeper swap intervals might have some uses
|
// TODO: Deeper swap intervals might have some uses
|
||||||
let desired_swap_interval = if attributes.vsync { 1 } else { 0 };
|
let desired_swap_interval = if attributes.vsync { 1 } else { 0 };
|
||||||
|
@ -252,24 +272,28 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLDisplay<B, N> {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|config| unsafe {
|
.map(|config| unsafe {
|
||||||
let mut min_swap_interval = 0;
|
let mut min_swap_interval = 0;
|
||||||
wrap_egl_call(|| ffi::egl::GetConfigAttrib(
|
wrap_egl_call(|| {
|
||||||
|
ffi::egl::GetConfigAttrib(
|
||||||
**self.display,
|
**self.display,
|
||||||
config,
|
config,
|
||||||
ffi::egl::MIN_SWAP_INTERVAL as ffi::egl::types::EGLint,
|
ffi::egl::MIN_SWAP_INTERVAL as ffi::egl::types::EGLint,
|
||||||
&mut min_swap_interval,
|
&mut min_swap_interval,
|
||||||
))?;
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
if desired_swap_interval < min_swap_interval {
|
if desired_swap_interval < min_swap_interval {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut max_swap_interval = 0;
|
let mut max_swap_interval = 0;
|
||||||
wrap_egl_call(|| ffi::egl::GetConfigAttrib(
|
wrap_egl_call(|| {
|
||||||
|
ffi::egl::GetConfigAttrib(
|
||||||
**self.display,
|
**self.display,
|
||||||
config,
|
config,
|
||||||
ffi::egl::MAX_SWAP_INTERVAL as ffi::egl::types::EGLint,
|
ffi::egl::MAX_SWAP_INTERVAL as ffi::egl::types::EGLint,
|
||||||
&mut max_swap_interval,
|
&mut max_swap_interval,
|
||||||
))?;
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
if desired_swap_interval > max_swap_interval {
|
if desired_swap_interval > max_swap_interval {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
|
@ -277,8 +301,11 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLDisplay<B, N> {
|
||||||
|
|
||||||
Ok(Some(config))
|
Ok(Some(config))
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<Option<ffi::egl::types::EGLConfig>>, EGLError>>().map_err(Error::ConfigFailed)?
|
.collect::<Result<Vec<Option<ffi::egl::types::EGLConfig>>, EGLError>>()
|
||||||
.into_iter().flat_map(|x| x).collect::<Vec<_>>();
|
.map_err(Error::ConfigFailed)?
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(|x| x)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if config_ids.is_empty() {
|
if config_ids.is_empty() {
|
||||||
return Err(Error::NoAvailablePixelFormat);
|
return Err(Error::NoAvailablePixelFormat);
|
||||||
|
@ -291,12 +318,15 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLDisplay<B, N> {
|
||||||
macro_rules! attrib {
|
macro_rules! attrib {
|
||||||
($display:expr, $config:expr, $attr:expr) => {{
|
($display:expr, $config:expr, $attr:expr) => {{
|
||||||
let mut value = MaybeUninit::uninit();
|
let mut value = MaybeUninit::uninit();
|
||||||
wrap_egl_call(|| ffi::egl::GetConfigAttrib(
|
wrap_egl_call(|| {
|
||||||
|
ffi::egl::GetConfigAttrib(
|
||||||
**$display,
|
**$display,
|
||||||
$config,
|
$config,
|
||||||
$attr as ffi::egl::types::EGLint,
|
$attr as ffi::egl::types::EGLint,
|
||||||
value.as_mut_ptr(),
|
value.as_mut_ptr(),
|
||||||
)).map_err(Error::ConfigFailed)?;
|
)
|
||||||
|
})
|
||||||
|
.map_err(Error::ConfigFailed)?;
|
||||||
value.assume_init()
|
value.assume_init()
|
||||||
}};
|
}};
|
||||||
};
|
};
|
||||||
|
@ -343,7 +373,11 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLDisplay<B, N> {
|
||||||
args: N::Arguments,
|
args: N::Arguments,
|
||||||
) -> Result<EGLSurface<B::Surface>, SurfaceCreationError<N::Error>> {
|
) -> Result<EGLSurface<B::Surface>, SurfaceCreationError<N::Error>> {
|
||||||
trace!(self.logger, "Creating EGL window surface.");
|
trace!(self.logger, "Creating EGL window surface.");
|
||||||
let surface = self.native.borrow_mut().create_surface(args).map_err(SurfaceCreationError::NativeSurfaceCreationFailed)?;
|
let surface = self
|
||||||
|
.native
|
||||||
|
.borrow_mut()
|
||||||
|
.create_surface(args)
|
||||||
|
.map_err(SurfaceCreationError::NativeSurfaceCreationFailed)?;
|
||||||
|
|
||||||
EGLSurface::new(
|
EGLSurface::new(
|
||||||
self.display.clone(),
|
self.display.clone(),
|
||||||
|
@ -356,7 +390,8 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLDisplay<B, N> {
|
||||||
.map(|x| {
|
.map(|x| {
|
||||||
debug!(self.logger, "EGL surface successfully created");
|
debug!(self.logger, "EGL surface successfully created");
|
||||||
x
|
x
|
||||||
}).map_err(SurfaceCreationError::EGLSurfaceCreationFailed)
|
})
|
||||||
|
.map_err(SurfaceCreationError::EGLSurfaceCreationFailed)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the runtime egl version of this display
|
/// Returns the runtime egl version of this display
|
||||||
|
@ -407,7 +442,10 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLGraphicsBackend for EGL
|
||||||
if !self.extensions.iter().any(|s| s == "EGL_WL_bind_wayland_display") {
|
if !self.extensions.iter().any(|s| s == "EGL_WL_bind_wayland_display") {
|
||||||
return Err(Error::EglExtensionNotSupported(&["EGL_WL_bind_wayland_display"]));
|
return Err(Error::EglExtensionNotSupported(&["EGL_WL_bind_wayland_display"]));
|
||||||
}
|
}
|
||||||
wrap_egl_call(|| unsafe { ffi::egl::BindWaylandDisplayWL(**self.display, display.c_ptr() as *mut _) }).map_err(Error::OtherEGLDisplayAlreadyBound)?;
|
wrap_egl_call(|| unsafe {
|
||||||
|
ffi::egl::BindWaylandDisplayWL(**self.display, display.c_ptr() as *mut _)
|
||||||
|
})
|
||||||
|
.map_err(Error::OtherEGLDisplayAlreadyBound)?;
|
||||||
Ok(EGLBufferReader::new(self.display.clone(), display.c_ptr()))
|
Ok(EGLBufferReader::new(self.display.clone(), display.c_ptr()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -454,7 +492,8 @@ impl EGLBufferReader {
|
||||||
ffi::egl::EGL_TEXTURE_FORMAT,
|
ffi::egl::EGL_TEXTURE_FORMAT,
|
||||||
&mut format,
|
&mut format,
|
||||||
)
|
)
|
||||||
}).map_err(|source| BufferAccessError::NotManaged(buffer.clone(), source))?;
|
})
|
||||||
|
.map_err(|source| BufferAccessError::NotManaged(buffer.clone(), source))?;
|
||||||
|
|
||||||
let format = match format {
|
let format = match format {
|
||||||
x if x == ffi::egl::TEXTURE_RGB as i32 => Format::RGB,
|
x if x == ffi::egl::TEXTURE_RGB as i32 => Format::RGB,
|
||||||
|
@ -474,7 +513,8 @@ impl EGLBufferReader {
|
||||||
ffi::egl::WIDTH as i32,
|
ffi::egl::WIDTH as i32,
|
||||||
&mut width,
|
&mut width,
|
||||||
)
|
)
|
||||||
}).map_err(|source| BufferAccessError::NotManaged(buffer.clone(), source))?;
|
})
|
||||||
|
.map_err(|source| BufferAccessError::NotManaged(buffer.clone(), source))?;
|
||||||
|
|
||||||
let mut height: i32 = 0;
|
let mut height: i32 = 0;
|
||||||
wrap_egl_call(|| unsafe {
|
wrap_egl_call(|| unsafe {
|
||||||
|
@ -484,7 +524,8 @@ impl EGLBufferReader {
|
||||||
ffi::egl::HEIGHT as i32,
|
ffi::egl::HEIGHT as i32,
|
||||||
&mut height,
|
&mut height,
|
||||||
)
|
)
|
||||||
}).map_err(|source| BufferAccessError::NotManaged(buffer.clone(), source))?;
|
})
|
||||||
|
.map_err(|source| BufferAccessError::NotManaged(buffer.clone(), source))?;
|
||||||
|
|
||||||
let mut inverted: i32 = 0;
|
let mut inverted: i32 = 0;
|
||||||
wrap_egl_call(|| unsafe {
|
wrap_egl_call(|| unsafe {
|
||||||
|
@ -494,7 +535,8 @@ impl EGLBufferReader {
|
||||||
ffi::egl::WAYLAND_Y_INVERTED_WL,
|
ffi::egl::WAYLAND_Y_INVERTED_WL,
|
||||||
&mut inverted,
|
&mut inverted,
|
||||||
)
|
)
|
||||||
}).map_err(|source| BufferAccessError::NotManaged(buffer.clone(), source))?;
|
})
|
||||||
|
.map_err(|source| BufferAccessError::NotManaged(buffer.clone(), source))?;
|
||||||
|
|
||||||
let mut images = Vec::with_capacity(format.num_planes());
|
let mut images = Vec::with_capacity(format.num_planes());
|
||||||
for i in 0..format.num_planes() {
|
for i in 0..format.num_planes() {
|
||||||
|
@ -512,7 +554,8 @@ impl EGLBufferReader {
|
||||||
buffer.as_ref().c_ptr() as *mut _,
|
buffer.as_ref().c_ptr() as *mut _,
|
||||||
out.as_ptr(),
|
out.as_ptr(),
|
||||||
)
|
)
|
||||||
}).map_err(BufferAccessError::EGLImageCreationFailed)?;
|
})
|
||||||
|
.map_err(BufferAccessError::EGLImageCreationFailed)?;
|
||||||
image
|
image
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,9 @@ pub enum Error {
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum EGLError {
|
pub enum EGLError {
|
||||||
/// EGL is not initialized, or could not be initialized, for the specified EGL display connection.
|
/// EGL is not initialized, or could not be initialized, for the specified EGL display connection.
|
||||||
#[error("EGL is not initialized, or could not be initialized, for the specified EGL display connection.")]
|
#[error(
|
||||||
|
"EGL is not initialized, or could not be initialized, for the specified EGL display connection."
|
||||||
|
)]
|
||||||
NotInitialized,
|
NotInitialized,
|
||||||
/// EGL cannot access a requested resource (for example a context is bound in another thread).
|
/// EGL cannot access a requested resource (for example a context is bound in another thread).
|
||||||
#[error("EGL cannot access a requested resource (for example a context is bound in another thread).")]
|
#[error("EGL cannot access a requested resource (for example a context is bound in another thread).")]
|
||||||
|
|
|
@ -19,7 +19,10 @@
|
||||||
//! of an EGL-based [`WlBuffer`](wayland_server::protocol::wl_buffer::WlBuffer) for rendering.
|
//! of an EGL-based [`WlBuffer`](wayland_server::protocol::wl_buffer::WlBuffer) for rendering.
|
||||||
|
|
||||||
#[cfg(feature = "renderer_gl")]
|
#[cfg(feature = "renderer_gl")]
|
||||||
use crate::backend::graphics::{SwapBuffersError as GraphicsSwapBuffersError, gl::{ffi as gl_ffi, GLGraphicsBackend}};
|
use crate::backend::graphics::{
|
||||||
|
gl::{ffi as gl_ffi, GLGraphicsBackend},
|
||||||
|
SwapBuffersError as GraphicsSwapBuffersError,
|
||||||
|
};
|
||||||
use nix::libc::c_uint;
|
use nix::libc::c_uint;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
#[cfg(feature = "wayland_frontend")]
|
#[cfg(feature = "wayland_frontend")]
|
||||||
|
@ -116,7 +119,7 @@ pub enum SurfaceCreationError<E: std::error::Error + 'static> {
|
||||||
NativeSurfaceCreationFailed(#[source] E),
|
NativeSurfaceCreationFailed(#[source] E),
|
||||||
/// EGL surface creation failed
|
/// EGL surface creation failed
|
||||||
#[error("EGL surface creation failed. Err: {0:}")]
|
#[error("EGL surface creation failed. Err: {0:}")]
|
||||||
EGLSurfaceCreationFailed(#[source] EGLError)
|
EGLSurfaceCreationFailed(#[source] EGLError),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error that can happen when swapping buffers.
|
/// Error that can happen when swapping buffers.
|
||||||
|
@ -138,10 +141,14 @@ impl<E: std::error::Error> std::convert::TryFrom<SwapBuffersError<E>> for Graphi
|
||||||
fn try_from(value: SwapBuffersError<E>) -> Result<Self, Self::Error> {
|
fn try_from(value: SwapBuffersError<E>) -> Result<Self, Self::Error> {
|
||||||
match value {
|
match value {
|
||||||
// bad surface is answered with a surface recreation in `swap_buffers`
|
// bad surface is answered with a surface recreation in `swap_buffers`
|
||||||
x @ SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface) => Ok(GraphicsSwapBuffersError::TemporaryFailure(Box::new(x))),
|
x @ SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface) => {
|
||||||
|
Ok(GraphicsSwapBuffersError::TemporaryFailure(Box::new(x)))
|
||||||
|
}
|
||||||
// the rest is either never happening or are unrecoverable
|
// the rest is either never happening or are unrecoverable
|
||||||
x @ SwapBuffersError::EGLSwapBuffers(_) => Ok(GraphicsSwapBuffersError::ContextLost(Box::new(x))),
|
x @ SwapBuffersError::EGLSwapBuffers(_) => Ok(GraphicsSwapBuffersError::ContextLost(Box::new(x))),
|
||||||
x @ SwapBuffersError::EGLCreateWindowSurface(_) => Ok(GraphicsSwapBuffersError::ContextLost(Box::new(x))),
|
x @ SwapBuffersError::EGLCreateWindowSurface(_) => {
|
||||||
|
Ok(GraphicsSwapBuffersError::ContextLost(Box::new(x)))
|
||||||
|
}
|
||||||
SwapBuffersError::Underlying(e) => Err(e),
|
SwapBuffersError::Underlying(e) => Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,16 +171,22 @@ impl From<MakeCurrentError> for GraphicsSwapBuffersError {
|
||||||
|
|
||||||
Except for the first case all of these recoverable. This conversation is mostly used in winit & EglSurface, where compatible context and surfaces are build.
|
Except for the first case all of these recoverable. This conversation is mostly used in winit & EglSurface, where compatible context and surfaces are build.
|
||||||
*/
|
*/
|
||||||
x @ MakeCurrentError(EGLError::BadAccess) => GraphicsSwapBuffersError::TemporaryFailure(Box::new(x)),
|
x @ MakeCurrentError(EGLError::BadAccess) => {
|
||||||
|
GraphicsSwapBuffersError::TemporaryFailure(Box::new(x))
|
||||||
|
}
|
||||||
// BadSurface would result in a recreation in `eglSwapBuffers` -> recoverable
|
// BadSurface would result in a recreation in `eglSwapBuffers` -> recoverable
|
||||||
x @ MakeCurrentError(EGLError::BadSurface) => GraphicsSwapBuffersError::TemporaryFailure(Box::new(x)),
|
x @ MakeCurrentError(EGLError::BadSurface) => {
|
||||||
|
GraphicsSwapBuffersError::TemporaryFailure(Box::new(x))
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
From khronos docs:
|
From khronos docs:
|
||||||
If the previous context of the calling thread has unflushed commands, and the previous surface is no longer valid, an EGL_BAD_CURRENT_SURFACE error is generated.
|
If the previous context of the calling thread has unflushed commands, and the previous surface is no longer valid, an EGL_BAD_CURRENT_SURFACE error is generated.
|
||||||
|
|
||||||
This does not consern this or future `makeCurrent`-calls.
|
This does not consern this or future `makeCurrent`-calls.
|
||||||
*/
|
*/
|
||||||
x @ MakeCurrentError(EGLError::BadCurrentSurface) => GraphicsSwapBuffersError::TemporaryFailure(Box::new(x)),
|
x @ MakeCurrentError(EGLError::BadCurrentSurface) => {
|
||||||
|
GraphicsSwapBuffersError::TemporaryFailure(Box::new(x))
|
||||||
|
}
|
||||||
// the rest is either never happening or are unrecoverable
|
// the rest is either never happening or are unrecoverable
|
||||||
x => GraphicsSwapBuffersError::ContextLost(Box::new(x)),
|
x => GraphicsSwapBuffersError::ContextLost(Box::new(x)),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Type safe native types for safe context/surface creation
|
//! Type safe native types for safe context/surface creation
|
||||||
|
|
||||||
use super::{ffi, Error, EGLError, wrap_egl_call};
|
use super::{ffi, wrap_egl_call, EGLError, Error};
|
||||||
|
|
||||||
#[cfg(feature = "backend_winit")]
|
#[cfg(feature = "backend_winit")]
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
@ -47,11 +47,19 @@ impl Backend for Wayland {
|
||||||
{
|
{
|
||||||
if has_dp_extension("EGL_KHR_platform_wayland") && ffi::egl::GetPlatformDisplay::is_loaded() {
|
if has_dp_extension("EGL_KHR_platform_wayland") && ffi::egl::GetPlatformDisplay::is_loaded() {
|
||||||
trace!(log, "EGL Display Initialization via EGL_KHR_platform_wayland");
|
trace!(log, "EGL Display Initialization via EGL_KHR_platform_wayland");
|
||||||
wrap_egl_call(|| ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_WAYLAND_KHR, display as *mut _, ptr::null()))
|
wrap_egl_call(|| {
|
||||||
|
ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_WAYLAND_KHR, display as *mut _, ptr::null())
|
||||||
|
})
|
||||||
} else if has_dp_extension("EGL_EXT_platform_wayland") && ffi::egl::GetPlatformDisplayEXT::is_loaded()
|
} else if has_dp_extension("EGL_EXT_platform_wayland") && ffi::egl::GetPlatformDisplayEXT::is_loaded()
|
||||||
{
|
{
|
||||||
trace!(log, "EGL Display Initialization via EGL_EXT_platform_wayland");
|
trace!(log, "EGL Display Initialization via EGL_EXT_platform_wayland");
|
||||||
wrap_egl_call(|| ffi::egl::GetPlatformDisplayEXT(ffi::egl::PLATFORM_WAYLAND_EXT, display as *mut _, ptr::null()))
|
wrap_egl_call(|| {
|
||||||
|
ffi::egl::GetPlatformDisplayEXT(
|
||||||
|
ffi::egl::PLATFORM_WAYLAND_EXT,
|
||||||
|
display as *mut _,
|
||||||
|
ptr::null(),
|
||||||
|
)
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
trace!(log, "Default EGL Display Initialization via GetDisplay");
|
trace!(log, "Default EGL Display Initialization via GetDisplay");
|
||||||
wrap_egl_call(|| ffi::egl::GetDisplay(display as *mut _))
|
wrap_egl_call(|| ffi::egl::GetDisplay(display as *mut _))
|
||||||
|
@ -79,10 +87,14 @@ impl Backend for X11 {
|
||||||
{
|
{
|
||||||
if has_dp_extension("EGL_KHR_platform_x11") && ffi::egl::GetPlatformDisplay::is_loaded() {
|
if has_dp_extension("EGL_KHR_platform_x11") && ffi::egl::GetPlatformDisplay::is_loaded() {
|
||||||
trace!(log, "EGL Display Initialization via EGL_KHR_platform_x11");
|
trace!(log, "EGL Display Initialization via EGL_KHR_platform_x11");
|
||||||
wrap_egl_call(|| ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_X11_KHR, display as *mut _, ptr::null()))
|
wrap_egl_call(|| {
|
||||||
|
ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_X11_KHR, display as *mut _, ptr::null())
|
||||||
|
})
|
||||||
} else if has_dp_extension("EGL_EXT_platform_x11") && ffi::egl::GetPlatformDisplayEXT::is_loaded() {
|
} else if has_dp_extension("EGL_EXT_platform_x11") && ffi::egl::GetPlatformDisplayEXT::is_loaded() {
|
||||||
trace!(log, "EGL Display Initialization via EGL_EXT_platform_x11");
|
trace!(log, "EGL Display Initialization via EGL_EXT_platform_x11");
|
||||||
wrap_egl_call(|| ffi::egl::GetPlatformDisplayEXT(ffi::egl::PLATFORM_X11_EXT, display as *mut _, ptr::null()))
|
wrap_egl_call(|| {
|
||||||
|
ffi::egl::GetPlatformDisplayEXT(ffi::egl::PLATFORM_X11_EXT, display as *mut _, ptr::null())
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
trace!(log, "Default EGL Display Initialization via GetDisplay");
|
trace!(log, "Default EGL Display Initialization via GetDisplay");
|
||||||
wrap_egl_call(|| ffi::egl::GetDisplay(display as *mut _))
|
wrap_egl_call(|| ffi::egl::GetDisplay(display as *mut _))
|
||||||
|
@ -203,7 +215,9 @@ pub unsafe trait NativeSurface {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Never {}
|
pub enum Never {}
|
||||||
impl std::fmt::Display for Never {
|
impl std::fmt::Display for Never {
|
||||||
fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { unreachable!() }
|
fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl std::error::Error for Never {}
|
impl std::error::Error for Never {}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! EGL surface related structs
|
//! EGL surface related structs
|
||||||
|
|
||||||
use super::{ffi, native, EGLError, SwapBuffersError, wrap_egl_call};
|
use super::{ffi, native, wrap_egl_call, EGLError, SwapBuffersError};
|
||||||
use crate::backend::egl::display::EGLDisplayHandle;
|
use crate::backend::egl::display::EGLDisplayHandle;
|
||||||
use crate::backend::graphics::PixelFormat;
|
use crate::backend::graphics::PixelFormat;
|
||||||
use nix::libc::c_int;
|
use nix::libc::c_int;
|
||||||
|
@ -90,10 +90,16 @@ impl<N: native::NativeSurface> EGLSurface<N> {
|
||||||
wrap_egl_call(|| unsafe { ffi::egl::SwapBuffers(**self.display, surface as *const _) })
|
wrap_egl_call(|| unsafe { ffi::egl::SwapBuffers(**self.display, surface as *const _) })
|
||||||
.map_err(SwapBuffersError::EGLSwapBuffers)
|
.map_err(SwapBuffersError::EGLSwapBuffers)
|
||||||
.and_then(|_| self.native.swap_buffers().map_err(SwapBuffersError::Underlying))
|
.and_then(|_| self.native.swap_buffers().map_err(SwapBuffersError::Underlying))
|
||||||
} else { Ok(()) };
|
} else {
|
||||||
|
Ok(())
|
||||||
|
};
|
||||||
|
|
||||||
// workaround for missing `PartialEq` impl
|
// workaround for missing `PartialEq` impl
|
||||||
let is_bad_surface = if let Err(SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface)) = result { true } else { false };
|
let is_bad_surface = if let Err(SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface)) = result {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
if self.native.needs_recreation() || surface.is_null() || is_bad_surface {
|
if self.native.needs_recreation() || surface.is_null() || is_bad_surface {
|
||||||
self.native.recreate().map_err(SwapBuffersError::Underlying)?;
|
self.native.recreate().map_err(SwapBuffersError::Underlying)?;
|
||||||
|
@ -101,12 +107,15 @@ impl<N: native::NativeSurface> EGLSurface<N> {
|
||||||
let _ = unsafe { ffi::egl::DestroySurface(**self.display, surface as *const _) };
|
let _ = unsafe { ffi::egl::DestroySurface(**self.display, surface as *const _) };
|
||||||
}
|
}
|
||||||
self.surface.set(unsafe {
|
self.surface.set(unsafe {
|
||||||
wrap_egl_call(|| ffi::egl::CreateWindowSurface(
|
wrap_egl_call(|| {
|
||||||
|
ffi::egl::CreateWindowSurface(
|
||||||
**self.display,
|
**self.display,
|
||||||
self.config_id,
|
self.config_id,
|
||||||
self.native.ptr(),
|
self.native.ptr(),
|
||||||
self.surface_attributes.as_ptr(),
|
self.surface_attributes.as_ptr(),
|
||||||
)).map_err(SwapBuffersError::EGLCreateWindowSurface)?
|
)
|
||||||
|
})
|
||||||
|
.map_err(SwapBuffersError::EGLCreateWindowSurface)?
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,10 @@ impl<T: GLGraphicsBackend + 'static> GliumGraphicsBackend<T> {
|
||||||
/// Note that destroying a [`Frame`] is immediate, even if vsync is enabled.
|
/// Note that destroying a [`Frame`] is immediate, even if vsync is enabled.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn draw(&self) -> Frame {
|
pub fn draw(&self) -> Frame {
|
||||||
Frame(glium::Frame::new(self.context.clone(), self.backend.get_framebuffer_dimensions()), self.error_channel.clone())
|
Frame(
|
||||||
|
glium::Frame::new(self.context.clone(), self.backend.get_framebuffer_dimensions()),
|
||||||
|
self.error_channel.clone(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Borrow the underlying backend.
|
/// Borrow the underlying backend.
|
||||||
|
@ -89,7 +92,7 @@ unsafe impl<T: GLGraphicsBackend> Backend for InternalBackend<T> {
|
||||||
SwapBuffersError::ContextLost(err) => {
|
SwapBuffersError::ContextLost(err) => {
|
||||||
self.1.set(Some(err));
|
self.1.set(Some(err));
|
||||||
GliumSwapBuffersError::ContextLost
|
GliumSwapBuffersError::ContextLost
|
||||||
},
|
}
|
||||||
SwapBuffersError::TemporaryFailure(err) => {
|
SwapBuffersError::TemporaryFailure(err) => {
|
||||||
self.1.set(Some(err));
|
self.1.set(Some(err));
|
||||||
GliumSwapBuffersError::AlreadySwapped
|
GliumSwapBuffersError::AlreadySwapped
|
||||||
|
@ -97,7 +100,9 @@ unsafe impl<T: GLGraphicsBackend> Backend for InternalBackend<T> {
|
||||||
// I do not think, this may happen, but why not
|
// I do not think, this may happen, but why not
|
||||||
SwapBuffersError::AlreadySwapped => GliumSwapBuffersError::AlreadySwapped,
|
SwapBuffersError::AlreadySwapped => GliumSwapBuffersError::AlreadySwapped,
|
||||||
})
|
})
|
||||||
} else { Ok(()) }
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn get_proc_address(&self, symbol: &str) -> *const c_void {
|
unsafe fn get_proc_address(&self, symbol: &str) -> *const c_void {
|
||||||
|
@ -143,7 +148,9 @@ impl Frame {
|
||||||
let err = self.1.take();
|
let err = self.1.take();
|
||||||
match (res, err) {
|
match (res, err) {
|
||||||
(Ok(()), _) => Ok(()),
|
(Ok(()), _) => Ok(()),
|
||||||
(Err(GliumSwapBuffersError::AlreadySwapped), Some(err)) => Err(SwapBuffersError::TemporaryFailure(err)),
|
(Err(GliumSwapBuffersError::AlreadySwapped), Some(err)) => {
|
||||||
|
Err(SwapBuffersError::TemporaryFailure(err))
|
||||||
|
}
|
||||||
(Err(GliumSwapBuffersError::AlreadySwapped), None) => Err(SwapBuffersError::AlreadySwapped),
|
(Err(GliumSwapBuffersError::AlreadySwapped), None) => Err(SwapBuffersError::AlreadySwapped),
|
||||||
(Err(GliumSwapBuffersError::ContextLost), Some(err)) => Err(SwapBuffersError::ContextLost(err)),
|
(Err(GliumSwapBuffersError::ContextLost), Some(err)) => Err(SwapBuffersError::ContextLost(err)),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -152,9 +159,14 @@ impl Frame {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl glium::Surface for Frame {
|
impl glium::Surface for Frame {
|
||||||
fn clear(&mut self, rect: Option<&glium::Rect>, color: Option<(f32, f32, f32, f32)>, color_srgb: bool,
|
fn clear(
|
||||||
depth: Option<f32>, stencil: Option<i32>)
|
&mut self,
|
||||||
{
|
rect: Option<&glium::Rect>,
|
||||||
|
color: Option<(f32, f32, f32, f32)>,
|
||||||
|
color_srgb: bool,
|
||||||
|
depth: Option<f32>,
|
||||||
|
stencil: Option<i32>,
|
||||||
|
) {
|
||||||
self.0.clear(rect, color, color_srgb, depth, stencil)
|
self.0.clear(rect, color, color_srgb, depth, stencil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,36 +182,61 @@ impl glium::Surface for Frame {
|
||||||
self.0.get_stencil_buffer_bits()
|
self.0.get_stencil_buffer_bits()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw<'a, 'b, V, I, U>(&mut self, v: V, i: I, program: &glium::Program, uniforms: &U,
|
fn draw<'a, 'b, V, I, U>(
|
||||||
draw_parameters: &glium::draw_parameters::DrawParameters<'_>) -> Result<(), glium::DrawError> where
|
&mut self,
|
||||||
V: glium::vertex::MultiVerticesSource<'b>, I: Into<glium::index::IndicesSource<'a>>,
|
v: V,
|
||||||
U: glium::uniforms::Uniforms
|
i: I,
|
||||||
|
program: &glium::Program,
|
||||||
|
uniforms: &U,
|
||||||
|
draw_parameters: &glium::draw_parameters::DrawParameters<'_>,
|
||||||
|
) -> Result<(), glium::DrawError>
|
||||||
|
where
|
||||||
|
V: glium::vertex::MultiVerticesSource<'b>,
|
||||||
|
I: Into<glium::index::IndicesSource<'a>>,
|
||||||
|
U: glium::uniforms::Uniforms,
|
||||||
{
|
{
|
||||||
self.0.draw(v, i, program, uniforms, draw_parameters)
|
self.0.draw(v, i, program, uniforms, draw_parameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn blit_from_frame(&self, source_rect: &glium::Rect, target_rect: &glium::BlitTarget,
|
fn blit_from_frame(
|
||||||
filter: glium::uniforms::MagnifySamplerFilter)
|
&self,
|
||||||
{
|
source_rect: &glium::Rect,
|
||||||
|
target_rect: &glium::BlitTarget,
|
||||||
|
filter: glium::uniforms::MagnifySamplerFilter,
|
||||||
|
) {
|
||||||
self.0.blit_from_frame(source_rect, target_rect, filter);
|
self.0.blit_from_frame(source_rect, target_rect, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn blit_from_simple_framebuffer(&self, source: &glium::framebuffer::SimpleFrameBuffer<'_>,
|
fn blit_from_simple_framebuffer(
|
||||||
source_rect: &glium::Rect, target_rect: &glium::BlitTarget,
|
&self,
|
||||||
filter: glium::uniforms::MagnifySamplerFilter)
|
source: &glium::framebuffer::SimpleFrameBuffer<'_>,
|
||||||
{
|
source_rect: &glium::Rect,
|
||||||
self.0.blit_from_simple_framebuffer(source, source_rect, target_rect, filter)
|
target_rect: &glium::BlitTarget,
|
||||||
|
filter: glium::uniforms::MagnifySamplerFilter,
|
||||||
|
) {
|
||||||
|
self.0
|
||||||
|
.blit_from_simple_framebuffer(source, source_rect, target_rect, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn blit_from_multioutput_framebuffer(&self, source: &glium::framebuffer::MultiOutputFrameBuffer<'_>,
|
fn blit_from_multioutput_framebuffer(
|
||||||
source_rect: &glium::Rect, target_rect: &glium::BlitTarget,
|
&self,
|
||||||
filter: glium::uniforms::MagnifySamplerFilter)
|
source: &glium::framebuffer::MultiOutputFrameBuffer<'_>,
|
||||||
{
|
source_rect: &glium::Rect,
|
||||||
self.0.blit_from_multioutput_framebuffer(source, source_rect, target_rect, filter)
|
target_rect: &glium::BlitTarget,
|
||||||
|
filter: glium::uniforms::MagnifySamplerFilter,
|
||||||
|
) {
|
||||||
|
self.0
|
||||||
|
.blit_from_multioutput_framebuffer(source, source_rect, target_rect, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn blit_color<S>(&self, source_rect: &glium::Rect, target: &S, target_rect: &glium::BlitTarget,
|
fn blit_color<S>(
|
||||||
filter: glium::uniforms::MagnifySamplerFilter) where S: glium::Surface
|
&self,
|
||||||
|
source_rect: &glium::Rect,
|
||||||
|
target: &S,
|
||||||
|
target_rect: &glium::BlitTarget,
|
||||||
|
filter: glium::uniforms::MagnifySamplerFilter,
|
||||||
|
) where
|
||||||
|
S: glium::Surface,
|
||||||
{
|
{
|
||||||
self.0.blit_color(source_rect, target, target_rect, filter)
|
self.0.blit_color(source_rect, target, target_rect, filter)
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub enum Error {
|
||||||
EGL(#[from] EGLError),
|
EGL(#[from] EGLError),
|
||||||
/// Surface Creation failed
|
/// Surface Creation failed
|
||||||
#[error("Surface creation failed: {0}")]
|
#[error("Surface creation failed: {0}")]
|
||||||
SurfaceCreationError(#[from] SurfaceCreationError<EGLError>)
|
SurfaceCreationError(#[from] SurfaceCreationError<EGLError>),
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Window {
|
enum Window {
|
||||||
|
@ -281,7 +281,9 @@ impl GLGraphicsBackend for WinitGraphicsBackend {
|
||||||
fn swap_buffers(&self) -> ::std::result::Result<(), SwapBuffersError> {
|
fn swap_buffers(&self) -> ::std::result::Result<(), SwapBuffersError> {
|
||||||
trace!(self.logger, "Swapping buffers");
|
trace!(self.logger, "Swapping buffers");
|
||||||
match *self.window {
|
match *self.window {
|
||||||
Window::Wayland { ref surface, .. } => surface.swap_buffers().map_err(|err| err.try_into().unwrap()),
|
Window::Wayland { ref surface, .. } => {
|
||||||
|
surface.swap_buffers().map_err(|err| err.try_into().unwrap())
|
||||||
|
}
|
||||||
Window::X11 { ref surface, .. } => surface.swap_buffers().map_err(|err| err.try_into().unwrap()),
|
Window::X11 { ref surface, .. } => surface.swap_buffers().map_err(|err| err.try_into().unwrap()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue