smithay/backend/allocator/
mod.rs

1//! Buffer allocation and management.
2//!
3//! Collection of common traits and implementations around
4//! buffer creation and handling from various sources.
5//!
6//! Allocators provided:
7//! - Dumb Buffers through [`crate::backend::drm::DrmDevice`]
8//! - Gbm Buffers through [`::gbm::Device`]
9//!
10//! Buffer types supported:
11//! - [DumbBuffers](dumb::DumbBuffer)
12//! - [GbmBuffers](::gbm::BufferObject)
13//! - [DmaBufs](dmabuf::Dmabuf)
14//!
15//! Helpers:
16//! - [`Swapchain`] to help with buffer management for framebuffers
17
18pub mod dmabuf;
19#[cfg(feature = "backend_drm")]
20pub mod dumb;
21pub mod format;
22#[cfg(feature = "backend_gbm")]
23pub mod gbm;
24#[cfg(feature = "backend_vulkan")]
25pub mod vulkan;
26
27mod swapchain;
28use std::{
29    cell::RefCell,
30    rc::Rc,
31    sync::{Arc, Mutex},
32};
33
34use crate::utils::{Buffer as BufferCoords, Size};
35pub use swapchain::{Slot, Swapchain};
36
37pub use drm_fourcc::{
38    DrmFormat as Format, DrmFourcc as Fourcc, DrmModifier as Modifier, DrmVendor as Vendor,
39    UnrecognizedFourcc, UnrecognizedVendor,
40};
41
42/// Common trait describing common properties of most types of buffers.
43pub trait Buffer {
44    /// Width of the two-dimensional buffer
45    fn width(&self) -> u32 {
46        self.size().w as u32
47    }
48    /// Height of the two-dimensional buffer
49    fn height(&self) -> u32 {
50        self.size().h as u32
51    }
52    /// Size of the two-dimensional buffer
53    fn size(&self) -> Size<i32, BufferCoords>;
54    /// Pixel format of the buffer
55    fn format(&self) -> Format;
56}
57
58/// Interface to create Buffers
59pub trait Allocator {
60    /// Buffer type produced by this allocator
61    type Buffer: Buffer;
62    /// Error type thrown if allocations fail
63    type Error: std::error::Error;
64
65    /// Try to create a buffer with the given dimensions and pixel format
66    fn create_buffer(
67        &mut self,
68        width: u32,
69        height: u32,
70        fourcc: Fourcc,
71        modifiers: &[Modifier],
72    ) -> Result<Self::Buffer, Self::Error>;
73}
74
75// General implementations for interior mutability.
76
77impl<A: Allocator> Allocator for Arc<Mutex<A>> {
78    type Buffer = A::Buffer;
79    type Error = A::Error;
80
81    fn create_buffer(
82        &mut self,
83        width: u32,
84        height: u32,
85        fourcc: Fourcc,
86        modifiers: &[Modifier],
87    ) -> Result<Self::Buffer, Self::Error> {
88        let mut guard = self.lock().unwrap();
89        guard.create_buffer(width, height, fourcc, modifiers)
90    }
91}
92
93impl<A: Allocator> Allocator for Rc<RefCell<A>> {
94    type Buffer = A::Buffer;
95    type Error = A::Error;
96
97    fn create_buffer(
98        &mut self,
99        width: u32,
100        height: u32,
101        fourcc: Fourcc,
102        modifiers: &[Modifier],
103    ) -> Result<Self::Buffer, Self::Error> {
104        self.borrow_mut().create_buffer(width, height, fourcc, modifiers)
105    }
106}
107
108impl<B: Buffer, E: std::error::Error> Allocator for Box<dyn Allocator<Buffer = B, Error = E> + 'static> {
109    type Buffer = B;
110    type Error = E;
111
112    fn create_buffer(
113        &mut self,
114        width: u32,
115        height: u32,
116        fourcc: Fourcc,
117        modifiers: &[Modifier],
118    ) -> Result<B, E> {
119        (**self).create_buffer(width, height, fourcc, modifiers)
120    }
121}