mirror of
https://github.com/Smithay/smithay.git
synced 2024-09-28 03:21:14 +02:00
allocator/gbm: Allow customizing usage flags
This commit is contained in:
parent
d2b7e33af4
commit
cc3ba5aefc
7 changed files with 136 additions and 31 deletions
|
@ -81,6 +81,7 @@ backend_x11 = ["x11rb", "x11rb/dri3", "x11rb/xfixes", "x11rb/present", "x11rb_ev
|
|||
backend_drm = ["drm", "drm-ffi"]
|
||||
backend_gbm = ["gbm", "cc", "pkg-config"]
|
||||
backend_gbm_has_fd_for_plane = []
|
||||
backend_gbm_has_create_with_modifiers2 = []
|
||||
backend_egl = ["gl_generator", "libloading"]
|
||||
backend_libinput = ["input"]
|
||||
backend_session = []
|
||||
|
|
|
@ -33,6 +33,7 @@ use smithay::{
|
|||
};
|
||||
use smithay::{
|
||||
backend::{
|
||||
allocator::gbm::{GbmAllocator, GbmBufferFlags, GbmDevice},
|
||||
drm::{
|
||||
DrmDevice, DrmDeviceFd, DrmError, DrmEvent, DrmEventMetadata, DrmNode, GbmBufferedSurface,
|
||||
NodeType,
|
||||
|
@ -70,7 +71,6 @@ use smithay::{
|
|||
Device as ControlDevice,
|
||||
},
|
||||
},
|
||||
gbm::Device as GbmDevice,
|
||||
input::Libinput,
|
||||
nix::{fcntl::OFlag, sys::stat::dev_t},
|
||||
wayland_protocols::wp::presentation_time::server::wp_presentation_feedback,
|
||||
|
@ -366,7 +366,7 @@ pub fn run_udev(log: Logger) {
|
|||
}
|
||||
}
|
||||
|
||||
pub type RenderSurface = GbmBufferedSurface<GbmDevice<DrmDeviceFd>, Option<OutputPresentationFeedback>>;
|
||||
pub type RenderSurface = GbmBufferedSurface<GbmAllocator<DrmDeviceFd>, Option<OutputPresentationFeedback>>;
|
||||
|
||||
struct SurfaceData {
|
||||
dh: DisplayHandle,
|
||||
|
@ -469,14 +469,18 @@ fn scan_connectors(
|
|||
}
|
||||
};
|
||||
|
||||
let gbm_surface =
|
||||
match GbmBufferedSurface::new(surface, gbm.clone(), formats.clone(), logger.clone()) {
|
||||
Ok(renderer) => renderer,
|
||||
Err(err) => {
|
||||
warn!(logger, "Failed to create rendering surface: {}", err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let gbm_surface = match GbmBufferedSurface::new(
|
||||
surface,
|
||||
GbmAllocator::new(gbm.clone(), GbmBufferFlags::RENDERING | GbmBufferFlags::SCANOUT),
|
||||
formats.clone(),
|
||||
logger.clone(),
|
||||
) {
|
||||
Ok(renderer) => renderer,
|
||||
Err(err) => {
|
||||
warn!(logger, "Failed to create rendering surface: {}", err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let size = mode.size();
|
||||
let mode = Mode {
|
||||
|
|
|
@ -16,7 +16,10 @@ use smithay::backend::renderer::ImportMem;
|
|||
#[cfg(feature = "egl")]
|
||||
use smithay::{
|
||||
backend::{
|
||||
allocator::dmabuf::Dmabuf,
|
||||
allocator::{
|
||||
dmabuf::Dmabuf,
|
||||
gbm::{GbmAllocator, GbmBufferFlags},
|
||||
},
|
||||
renderer::{ImportDma, ImportEgl},
|
||||
},
|
||||
delegate_dmabuf,
|
||||
|
@ -112,7 +115,7 @@ pub fn run_x11(log: Logger) {
|
|||
let surface = handle
|
||||
.create_surface(
|
||||
&window,
|
||||
device,
|
||||
GbmAllocator::new(device, GbmBufferFlags::RENDERING),
|
||||
context
|
||||
.dmabuf_render_formats()
|
||||
.iter()
|
||||
|
|
32
build.rs
32
build.rs
|
@ -89,10 +89,42 @@ fn test_gbm_bo_fd_for_plane() {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
feature = "backend_gbm",
|
||||
not(feature = "backend_gbm_has_create_with_modifiers2")
|
||||
))]
|
||||
fn test_gbm_bo_create_with_modifiers2() {
|
||||
let gbm = match pkg_config::probe_library("gbm") {
|
||||
Ok(lib) => lib,
|
||||
Err(_) => {
|
||||
println!(
|
||||
"cargo:warning=failed to find gbm, assuming gbm_bo_create_with_modifiers2 is unavailable"
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let has_gbm_bo_create_with_modifiers2 = cc::Build::new()
|
||||
.file("test_gbm_bo_create_with_modifiers2.c")
|
||||
.includes(gbm.include_paths)
|
||||
.warnings_into_errors(true)
|
||||
.try_compile("test_gbm_bo_create_with_modifiers2")
|
||||
.is_ok();
|
||||
|
||||
if has_gbm_bo_create_with_modifiers2 {
|
||||
println!("cargo:rustc-cfg=feature=\"backend_gbm_has_create_with_modifiers2\"");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
#[cfg(any(feature = "backend_egl", feature = "renderer_gl"))]
|
||||
gl_generate();
|
||||
|
||||
#[cfg(all(feature = "backend_gbm", not(feature = "backend_gbm_has_fd_for_plane")))]
|
||||
test_gbm_bo_fd_for_plane();
|
||||
#[cfg(all(
|
||||
feature = "backend_gbm",
|
||||
not(feature = "backend_gbm_has_create_with_modifiers2")
|
||||
))]
|
||||
test_gbm_bo_create_with_modifiers2();
|
||||
}
|
||||
|
|
|
@ -10,9 +10,82 @@ use super::{
|
|||
};
|
||||
use crate::utils::{Buffer as BufferCoords, Size};
|
||||
pub use gbm::{BufferObject as GbmBuffer, BufferObjectFlags as GbmBufferFlags, Device as GbmDevice};
|
||||
use std::os::unix::io::{AsFd, AsRawFd};
|
||||
use std::{
|
||||
convert::{AsMut, AsRef},
|
||||
os::unix::io::{AsFd, AsRawFd, BorrowedFd},
|
||||
};
|
||||
|
||||
impl<A: AsFd + 'static> Allocator for GbmDevice<A> {
|
||||
/// Light wrapper around an [`GbmDevice`] to implement the [`Allocator`]-trait
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GbmAllocator<A: AsFd + 'static> {
|
||||
device: GbmDevice<A>,
|
||||
default_flags: GbmBufferFlags,
|
||||
}
|
||||
|
||||
impl<A: AsFd + 'static> AsRef<GbmDevice<A>> for GbmAllocator<A> {
|
||||
fn as_ref(&self) -> &GbmDevice<A> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: AsFd + 'static> AsMut<GbmDevice<A>> for GbmAllocator<A> {
|
||||
fn as_mut(&mut self) -> &mut GbmDevice<A> {
|
||||
&mut self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: AsFd + 'static> AsFd for GbmAllocator<A> {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
self.device.as_fd()
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: AsFd + 'static> GbmAllocator<A> {
|
||||
/// Create a new [`GbmAllocator`] from a [`GbmDevice`] with some default usage flags,
|
||||
/// to be used when [`Allocator::create_buffer`] is invoked.
|
||||
pub fn new(device: GbmDevice<A>, default_flags: GbmBufferFlags) -> GbmAllocator<A> {
|
||||
GbmAllocator {
|
||||
device,
|
||||
default_flags,
|
||||
}
|
||||
}
|
||||
|
||||
/// Alternative to [`Allocator::create_buffer`], if you need a one-off buffer with
|
||||
/// a different set of usage flags.
|
||||
fn create_buffer_with_flags(
|
||||
&mut self,
|
||||
width: u32,
|
||||
height: u32,
|
||||
fourcc: Fourcc,
|
||||
modifiers: &[Modifier],
|
||||
flags: GbmBufferFlags,
|
||||
) -> Result<GbmBuffer<()>, std::io::Error> {
|
||||
#[cfg(feature = "backend_gbm_has_create_with_modifiers2")]
|
||||
let result = self.device.create_buffer_object_with_modifiers2(
|
||||
width,
|
||||
height,
|
||||
fourcc,
|
||||
modifiers.iter().copied(),
|
||||
flags,
|
||||
);
|
||||
#[cfg(not(feature = "backend_gbm_has_create_with_modifiers2"))]
|
||||
let result =
|
||||
self.create_buffer_object_with_modifiers(width, height, fourcc, modifiers.iter().copied());
|
||||
|
||||
match result {
|
||||
Ok(bo) => Ok(bo),
|
||||
Err(err) => {
|
||||
if modifiers.contains(&Modifier::Invalid) || modifiers.contains(&Modifier::Linear) {
|
||||
self.device.create_buffer_object(width, height, fourcc, flags)
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: AsFd + 'static> Allocator for GbmAllocator<A> {
|
||||
type Buffer = GbmBuffer<()>;
|
||||
type Error = std::io::Error;
|
||||
|
||||
|
@ -23,20 +96,7 @@ impl<A: AsFd + 'static> Allocator for GbmDevice<A> {
|
|||
fourcc: Fourcc,
|
||||
modifiers: &[Modifier],
|
||||
) -> Result<GbmBuffer<()>, Self::Error> {
|
||||
match self.create_buffer_object_with_modifiers(width, height, fourcc, modifiers.iter().copied()) {
|
||||
Ok(bo) => Ok(bo),
|
||||
Err(err) => {
|
||||
if modifiers.contains(&Modifier::Invalid) || modifiers.contains(&Modifier::Linear) {
|
||||
let mut usage = GbmBufferFlags::SCANOUT | GbmBufferFlags::RENDERING;
|
||||
if !modifiers.contains(&Modifier::Invalid) {
|
||||
usage |= GbmBufferFlags::LINEAR;
|
||||
}
|
||||
self.create_buffer_object(width, height, fourcc, usage)
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
self.create_buffer_with_flags(width, height, fourcc, modifiers, self.default_flags)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
//! ```rust,no_run
|
||||
//! # use std::{sync::{Arc, Mutex}, error::Error};
|
||||
//! # use smithay::backend::x11::{X11Backend, X11Surface, WindowBuilder};
|
||||
//! use smithay::backend::allocator::gbm::{GbmAllocator, GbmDevice, GbmBufferFlags};
|
||||
//! use smithay::backend::egl::{EGLDisplay, EGLContext};
|
||||
//! use smithay::reexports::gbm;
|
||||
//! use smithay::utils::DeviceFd;
|
||||
//! use std::collections::HashSet;
|
||||
//!
|
||||
|
@ -40,7 +40,7 @@
|
|||
//! // Get the DRM node used by the X server for direct rendering.
|
||||
//! let (_drm_node, fd) = x_handle.drm_node()?;
|
||||
//! // Create the gbm device for allocating buffers
|
||||
//! let device = gbm::Device::new(DeviceFd::from(fd))?;
|
||||
//! let device = GbmDevice::new(DeviceFd::from(fd))?;
|
||||
//! // Initialize EGL to retrieve the support modifier list
|
||||
//! let egl = unsafe { EGLDisplay::new(device.clone(), logger.clone()).expect("Failed to create EGLDisplay") };
|
||||
//! let context = EGLContext::new(&egl, logger).expect("Failed to create EGLContext");
|
||||
|
@ -48,7 +48,7 @@
|
|||
//!
|
||||
//! // Finally create the X11 surface, you will use this to obtain buffers that will be presented to the
|
||||
//! // window.
|
||||
//! let surface = x_handle.create_surface(&window, device, modifiers.into_iter());
|
||||
//! let surface = x_handle.create_surface(&window, GbmAllocator::new(device, GbmBufferFlags::RENDERING), modifiers.into_iter());
|
||||
//!
|
||||
//! // Insert the backend into the event loop to receive events.
|
||||
//! handle.insert_source(backend, |event, _window, state| {
|
||||
|
|
5
test_gbm_bo_create_with_modifiers2.c
Normal file
5
test_gbm_bo_create_with_modifiers2.c
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include <gbm.h>
|
||||
|
||||
void test() {
|
||||
gbm_bo_create_with_modifiers2(NULL, 0, 0, 0, NULL, 0, 0);
|
||||
}
|
Loading…
Reference in a new issue