Skip to main content

rlvgl_platform/
display.rs

1//! Traits and helpers for display drivers.
2use alloc::vec;
3use alloc::vec::Vec;
4use rlvgl_core::widget::{Color, Rect};
5
6use crate::screen::Screen;
7
8/// Trait implemented by display drivers.
9pub trait DisplayDriver {
10    /// Return the screen geometry (logical size + scan rotation).
11    ///
12    /// Applications use [`Screen::logical_size`] to size widgets;
13    /// renderers and compositors consult [`Screen::rotation`] to map
14    /// logical coordinates onto the physical framebuffer.
15    fn screen(&self) -> Screen;
16
17    /// Flush a rectangular region of pixels to the display.
18    ///
19    /// `area` and `colors` are in **logical** coordinates. The driver
20    /// is responsible for rotating them into the physical framebuffer
21    /// according to its [`Screen::rotation`].
22    fn flush(&mut self, area: Rect, colors: &[Color]);
23
24    /// Optional vertical sync hook.
25    fn vsync(&mut self) {}
26}
27
28/// Dummy headless driver used for tests.
29pub struct DummyDisplay;
30
31impl DisplayDriver for DummyDisplay {
32    fn screen(&self) -> Screen {
33        Screen::landscape(0, 0)
34    }
35    fn flush(&mut self, _area: Rect, _colors: &[Color]) {}
36}
37
38/// In-memory framebuffer driver for tests and headless rendering.
39pub struct BufferDisplay {
40    /// Width of the framebuffer in pixels.
41    pub width: usize,
42    /// Height of the framebuffer in pixels.
43    pub height: usize,
44    /// Pixel buffer stored in row-major order.
45    pub buffer: Vec<Color>,
46}
47
48impl BufferDisplay {
49    /// Create a framebuffer with the specified dimensions.
50    pub fn new(width: usize, height: usize) -> Self {
51        Self {
52            width,
53            height,
54            buffer: vec![Color(0, 0, 0, 255); width * height],
55        }
56    }
57}
58
59impl DisplayDriver for BufferDisplay {
60    fn screen(&self) -> Screen {
61        Screen::landscape(self.width as u32, self.height as u32)
62    }
63    fn flush(&mut self, area: Rect, colors: &[Color]) {
64        for y in 0..area.height as usize {
65            for x in 0..area.width as usize {
66                let idx = (area.y as usize + y) * self.width + (area.x as usize + x);
67                self.buffer[idx] = colors[y * area.width as usize + x];
68            }
69        }
70    }
71}