dim_screen/
buffer.rs

1use smithay_client_toolkit::{
2    reexports::{
3        client::{
4            protocol::{wl_buffer::WlBuffer, wl_shm},
5            QueueHandle,
6        },
7        protocols::wp::single_pixel_buffer::v1::client::wp_single_pixel_buffer_manager_v1::WpSinglePixelBufferManagerV1,
8    },
9    registry::SimpleGlobal,
10    shm::{
11        slot::{self, SlotPool},
12        Shm,
13    },
14};
15
16use crate::DimData;
17
18/// Abstracts away which is the best buffer manager available
19pub enum BufferManager {
20    SinglePixel(SimpleGlobal<WpSinglePixelBufferManagerV1, 1>),
21    /// Should be used as fallback, when single pixel buffer is not available
22    Shm(Shm, SlotPool),
23}
24
25pub enum BufferType {
26    Wl(WlBuffer),
27    Shared(slot::Buffer),
28}
29
30impl BufferManager {
31    /// Generate a new buffer from the owned buffer manager type
32    pub fn get_buffer(&mut self, qh: &QueueHandle<DimData>, alpha: f32) -> BufferType {
33        match self {
34            BufferManager::SinglePixel(simple_global) => {
35                // pre-multiply alpha
36                let alpha = (u32::MAX as f32 * alpha) as u32;
37
38                BufferType::Wl(
39                    simple_global
40                        .get()
41                        .expect("failed to get buffer")
42                        .create_u32_rgba_buffer(0, 0, 0, alpha, qh, ()),
43                )
44            }
45
46            // create a singe pixel buffer ourselves (to be resized by viewporter as well)
47            BufferManager::Shm(_, pool) => {
48                let (buffer, canvas) = pool
49                    .create_buffer(1, 1, 4, wl_shm::Format::Argb8888)
50                    .expect("Failed to get buffer from slot pool!");
51
52                // ARGB is actually backwards being little-endian, so we set BGR to 0 for black so
53                (0..3).for_each(|i| {
54                    canvas[i] = 0;
55                });
56                // then, we set pre-multiplied alpha
57                canvas[3] = (u8::MAX as f32 * alpha) as u8;
58
59                BufferType::Shared(buffer)
60            }
61        }
62    }
63}