Skip to content

Commit 9d2850e

Browse files
Implement #1
1 parent 4a0a352 commit 9d2850e

4 files changed

Lines changed: 83 additions & 8 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ image = { version = "0", default-features = false, features = ["png"] }
1818
[target.'cfg(unix)'.dependencies]
1919
evdev = "0"
2020
linuxfb = "0"
21+
memmap = "0"
2122

2223
[build-dependencies]
2324
slint-build = "1.12.1"

src/config/display_fb.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize};
1010
pub struct DisplayFramebufferConfig {
1111
pub fb_path: String,
1212
pub event_path: Option<String>,
13+
pub buffering: Option<String>,
1314
}
1415

1516
impl DisplayInit for DisplayFramebufferConfig {
@@ -23,13 +24,20 @@ impl DisplayInit for DisplayFramebufferConfig {
2324
}
2425
};
2526

27+
let double_buffering = match self.buffering.clone().unwrap_or(String::from("double")).to_lowercase().as_str()
28+
{
29+
"double" => true,
30+
"single" => false,
31+
_ => panic!("Config value {:?} is unsupported for buffering. Supported is \"Single\" or \"Double\"", self.buffering)
32+
};
33+
2634
let mut touch_device = None;
2735

2836
if let Some(event_path) = &self.event_path {
2937
touch_device = Some(Device::open(event_path)?);
3038
}
3139

32-
slint::platform::set_platform(Box::new(FramebufferPlatform::new(fb, touch_device)))
40+
slint::platform::set_platform(Box::new(FramebufferPlatform::new(fb, touch_device, double_buffering)))
3341
.expect("set platform");
3442

3543
let ui = AppWindow::new()?;

src/hardware/framebuffer_platform.rs

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use evdev::Device;
44
use linuxfb::{double::Buffer, Framebuffer};
5+
use memmap::MmapMut;
56
use slint::{
67
platform::{
78
software_renderer::{
@@ -14,21 +15,78 @@ use slint::{
1415
};
1516
use std::{
1617
cell::RefCell,
17-
collections::VecDeque,
1818
rc::Rc,
19-
sync::{Arc, Mutex},
2019
time::{Duration, Instant},
2120
};
2221

2322
use crate::hardware::EvdevMtTouchPlatform;
2423

24+
trait FramebufferHandler
25+
{
26+
fn as_mut_slice(&mut self) -> &mut [u8];
27+
fn flip(&mut self) -> Result<(), linuxfb::Error>;
28+
}
29+
30+
struct SingleBufferFramebuffer
31+
{
32+
fb: Framebuffer,
33+
map: MmapMut,
34+
}
35+
36+
impl SingleBufferFramebuffer
37+
{
38+
fn new(fb : Framebuffer) -> Result<SingleBufferFramebuffer, linuxfb::Error>
39+
{
40+
let map = fb.map()?;
41+
Ok(SingleBufferFramebuffer { fb: fb, map: map })
42+
}
43+
}
44+
45+
impl FramebufferHandler for SingleBufferFramebuffer
46+
{
47+
fn as_mut_slice(&mut self) -> &mut [u8]
48+
{
49+
&mut self.map[..]
50+
}
51+
52+
fn flip(&mut self) -> Result<(), linuxfb::Error> {
53+
// Do nothing
54+
Ok(())
55+
}
56+
}
57+
58+
struct DoubleBufferFramebuffer
59+
{
60+
buffer: Buffer,
61+
}
62+
63+
impl DoubleBufferFramebuffer
64+
{
65+
fn new(fb : Framebuffer) -> Result<DoubleBufferFramebuffer, linuxfb::Error>
66+
{
67+
let buffer = Buffer::new(fb)?;
68+
Ok(DoubleBufferFramebuffer { buffer: buffer })
69+
}
70+
}
71+
72+
impl FramebufferHandler for DoubleBufferFramebuffer
73+
{
74+
fn as_mut_slice(&mut self) -> &mut [u8] {
75+
self.buffer.as_mut_slice()
76+
}
77+
78+
fn flip(&mut self) -> Result<(), linuxfb::Error> {
79+
self.buffer.flip()
80+
}
81+
}
82+
2583
pub trait TouchPlatform {
2684
fn process_touch_events(&self) -> Vec<WindowEvent>;
2785
}
2886

2987
pub struct FramebufferPlatform {
3088
window: Rc<MinimalSoftwareWindow>,
31-
fb: RefCell<Buffer>,
89+
fb: RefCell<Box<dyn FramebufferHandler>>,
3290
width: usize,
3391
height: usize,
3492
stride: usize,
@@ -38,7 +96,7 @@ pub struct FramebufferPlatform {
3896
}
3997

4098
impl FramebufferPlatform {
41-
pub fn new(fb: Framebuffer, touch_device: Option<Device>) -> Self {
99+
pub fn new(fb: Framebuffer, touch_device: Option<Device>, double_buffering: bool) -> Self {
42100
let size = fb.get_size();
43101
let bytes_per_pixel = fb.get_bytes_per_pixel();
44102
let physical_size = fb.get_physical_size();
@@ -60,12 +118,19 @@ impl FramebufferPlatform {
60118
println!("No input device configured");
61119
}
62120

63-
let window = MinimalSoftwareWindow::new(RepaintBufferType::SwappedBuffers);
121+
let window = MinimalSoftwareWindow::new(if double_buffering { RepaintBufferType::SwappedBuffers } else { RepaintBufferType::ReusedBuffer });
64122
window.set_size(PhysicalSize::new(size.0, size.1));
65123

124+
let framebuffer_handler: Box<dyn FramebufferHandler> = match double_buffering
125+
{
126+
true => Box::new(DoubleBufferFramebuffer::new(fb).expect("Failed to initialise double buffer")),
127+
false => Box::new(SingleBufferFramebuffer::new(fb).expect("Failed to initialise single buffer"))
128+
};
129+
130+
66131
Self {
67132
window,
68-
fb: RefCell::new(Buffer::new(fb).unwrap()),
133+
fb: RefCell::new(framebuffer_handler),
69134
width: size.0 as usize,
70135
height: size.1 as usize,
71136
stride: size.0 as usize,
@@ -158,7 +223,7 @@ impl Platform for FramebufferPlatform {
158223
}
159224

160225
self.window.draw_if_needed(|renderer| {
161-
let frame: &mut [u8] = fb.as_mut_slice();
226+
let frame = fb.as_mut_slice();
162227
if self.bytes_per_pixel == 2 {
163228
let (_, pixels, _) = unsafe { frame.align_to_mut::<Rgb565Pixel>() };
164229
renderer.render(pixels, self.stride);

0 commit comments

Comments
 (0)