Skip to content

Commit 61aae04

Browse files
kekrbyWhatAmISupposedToPutHere
authored andcommitted
Redraw only the buttons whose states changed and provide damage
information to the kernel
1 parent de61ab9 commit 61aae04

2 files changed

Lines changed: 68 additions & 30 deletions

File tree

src/display.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,4 +192,7 @@ impl DrmBackend {
192192
pub fn map(&mut self) -> Result<DumbMapping> {
193193
Ok(self.card.map_dumb_buffer(&mut self.db)?)
194194
}
195+
pub fn fb_info(&self) -> Result<framebuffer::Info> {
196+
Ok(self.card.get_framebuffer(self.fb)?)
197+
}
195198
}

src/main.rs

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,27 @@ enum ButtonImage {
7272

7373
struct Button {
7474
image: ButtonImage,
75+
changed: bool,
76+
active: bool,
7577
action: Key
7678
}
7779

7880
impl Button {
7981
fn new_text(text: &'static str, action: Key) -> Button {
8082
Button {
81-
action, image: ButtonImage::Text(text)
83+
action,
84+
active: false,
85+
changed: false,
86+
image: ButtonImage::Text(text)
8287
}
8388
}
8489
fn new_svg(path: &'static str, action: Key) -> Button {
8590
let svg = Loader::new().read_path(format!("/usr/share/tiny-dfr/{}.svg", path)).unwrap();
8691
Button {
87-
action, image: ButtonImage::Svg(svg)
92+
action,
93+
active: false,
94+
changed: false,
95+
image: ButtonImage::Svg(svg)
8896
}
8997
}
9098
fn render(&self, c: &Context, button_left_edge: f64, button_width: u64, y_shift: f64) {
@@ -108,15 +116,28 @@ impl Button {
108116
}
109117
}
110118
}
119+
fn set_active<F>(&mut self, uinput: &mut UInputHandle<F>, active: bool) where F: AsRawFd {
120+
if self.active != active {
121+
self.active = active;
122+
self.changed = true;
123+
124+
toggle_key(uinput, self.action, active as i32);
125+
}
126+
}
111127
}
112128

113129
struct FunctionLayer {
114130
buttons: Vec<Button>
115131
}
116132

117133
impl FunctionLayer {
118-
fn draw(&self, config: &Config, surface: &Surface, active_buttons: &[bool], pixel_shift: (f64, f64)) {
134+
fn draw(&mut self, config: &Config, surface: &Surface, pixel_shift: (f64, f64), complete_redraw: bool) -> Vec<ClipRect> {
119135
let c = Context::new(&surface).unwrap();
136+
let mut modified_regions = if complete_redraw {
137+
vec![ClipRect::new(0, 0, DFR_HEIGHT as u16, DFR_WIDTH as u16)]
138+
} else {
139+
Vec::new()
140+
};
120141
c.translate(DFR_HEIGHT as f64, 0.0);
121142
c.rotate((90.0f64).to_radians());
122143
let pixel_shift_width = if config.enable_pixel_shift { PIXEL_SHIFT_WIDTH_PX } else { 0 };
@@ -126,19 +147,30 @@ impl FunctionLayer {
126147
let top = (DFR_HEIGHT as f64) * 0.85;
127148
let (pixel_shift_x, pixel_shift_y) = pixel_shift;
128149

129-
c.set_source_rgb(0.0, 0.0, 0.0);
130-
c.paint().unwrap();
150+
if complete_redraw {
151+
c.set_source_rgb(0.0, 0.0, 0.0);
152+
c.paint().unwrap();
153+
}
131154
c.set_font_face(&config.font_face);
132155
c.set_font_size(32.0);
133-
for (i, button) in self.buttons.iter().enumerate() {
156+
for (i, button) in self.buttons.iter_mut().enumerate() {
157+
if !button.changed && !complete_redraw {
158+
continue;
159+
};
160+
134161
let left_edge = (i as f64 * (button_width + BUTTON_SPACING_PX as f64)).floor() + pixel_shift_x + (pixel_shift_width / 2) as f64;
135-
let color = if active_buttons[i] {
162+
let color = if button.active {
136163
BUTTON_COLOR_ACTIVE
137164
} else if config.show_button_outlines {
138165
BUTTON_COLOR_INACTIVE
139166
} else {
140167
0.0
141168
};
169+
if !complete_redraw {
170+
c.set_source_rgb(0.0, 0.0, 0.0);
171+
c.rectangle(left_edge, bot - radius, button_width, top - bot + radius * 2.0);
172+
c.fill().unwrap();
173+
}
142174
c.set_source_rgb(color, color, color);
143175
// draw box with rounded corners
144176
c.new_sub_path();
@@ -177,7 +209,20 @@ impl FunctionLayer {
177209
c.fill().unwrap();
178210
c.set_source_rgb(1.0, 1.0, 1.0);
179211
button.render(&c, left_edge, button_width.ceil() as u64, pixel_shift_y);
212+
213+
button.changed = false;
214+
215+
if !complete_redraw {
216+
modified_regions.push(ClipRect::new(
217+
DFR_HEIGHT as u16 - top as u16 - radius as u16,
218+
left_edge as u16,
219+
DFR_HEIGHT as u16 - bot as u16 + radius as u16,
220+
left_edge as u16 + button_width as u16
221+
));
222+
}
180223
}
224+
225+
modified_regions
181226
}
182227
}
183228

@@ -306,10 +351,11 @@ fn main() {
306351
Button::new_svg("volume_up", Key::VolumeUp)
307352
]
308353
};
309-
let layers = if config.media_layer_default { [media_layer, fkey_layer] } else { [fkey_layer, media_layer] };
310-
let mut button_states = [vec![false; 12], vec![false; 12]];
311-
let mut needs_redraw = true;
354+
let mut layers = if config.media_layer_default { [media_layer, fkey_layer] } else { [fkey_layer, media_layer] };
355+
let mut needs_complete_redraw = true;
312356
let mut drm = DrmBackend::open_card().unwrap();
357+
let fb_info = drm.fb_info().unwrap();
358+
313359
let mut input_tb = Libinput::new_with_udev(Interface);
314360
let mut input_main = Libinput::new_with_udev(Interface);
315361
input_tb.udev_assign_seat("seat-touchbar").unwrap();
@@ -349,23 +395,22 @@ fn main() {
349395
if config.enable_pixel_shift {
350396
let (pixel_shift_needs_redraw, pixel_shift_next_timeout_ms) = pixel_shift.update();
351397
if pixel_shift_needs_redraw {
352-
needs_redraw = true;
398+
needs_complete_redraw = true;
353399
}
354400
next_timeout_ms = min(next_timeout_ms, pixel_shift_next_timeout_ms);
355401
}
356402

357-
358-
if needs_redraw {
359-
needs_redraw = false;
403+
if needs_complete_redraw || layers[active_layer].buttons.iter().any(|b| b.changed) {
360404
let shift = if config.enable_pixel_shift {
361405
pixel_shift.get()
362406
} else {
363407
(0.0, 0.0)
364408
};
365-
layers[active_layer].draw(&config, &surface, &button_states[active_layer], shift);
409+
let clips = layers[active_layer].draw(&config, &surface, shift, needs_complete_redraw);
366410
let data = surface.data().unwrap();
367411
drm.map().unwrap().as_mut()[..data.len()].copy_from_slice(&data);
368-
drm.dirty(&[ClipRect::new(0, 0, DFR_HEIGHT as u16, DFR_WIDTH as u16)]).unwrap();
412+
drm.dirty(&clips).unwrap();
413+
needs_complete_redraw = false;
369414
}
370415

371416
poll(&mut [pollfd_tb, pollfd_main], next_timeout_ms).unwrap();
@@ -388,7 +433,7 @@ fn main() {
388433
};
389434
if active_layer != new_layer {
390435
active_layer = new_layer;
391-
needs_redraw = true;
436+
needs_complete_redraw = true;
392437
}
393438
}
394439
},
@@ -403,9 +448,7 @@ fn main() {
403448
let btn = (x / (DFR_WIDTH as f64 / layers[active_layer].buttons.len() as f64)) as u32;
404449
if button_hit(layers[active_layer].buttons.len() as u32, btn, x, y) {
405450
touches.insert(dn.seat_slot(), (active_layer, btn));
406-
button_states[active_layer][btn as usize] = true;
407-
needs_redraw = true;
408-
toggle_key(&mut uinput, layers[active_layer].buttons[btn as usize].action, 1);
451+
layers[active_layer].buttons[btn as usize].set_active(&mut uinput, true);
409452
}
410453
},
411454
TouchEvent::Motion(mtn) => {
@@ -417,22 +460,14 @@ fn main() {
417460
let y = mtn.y_transformed(DFR_HEIGHT as u32);
418461
let (layer, btn) = *touches.get(&mtn.seat_slot()).unwrap();
419462
let hit = button_hit(layers[layer].buttons.len() as u32, btn, x, y);
420-
if button_states[layer][btn as usize] != hit {
421-
button_states[layer][btn as usize] = hit;
422-
needs_redraw = true;
423-
toggle_key(&mut uinput, layers[active_layer].buttons[btn as usize].action, hit as i32);
424-
}
463+
layers[layer].buttons[btn as usize].set_active(&mut uinput, hit);
425464
},
426465
TouchEvent::Up(up) => {
427466
if !touches.contains_key(&up.seat_slot()) {
428467
continue;
429468
}
430469
let (layer, btn) = *touches.get(&up.seat_slot()).unwrap();
431-
if button_states[layer][btn as usize] {
432-
button_states[layer][btn as usize] = false;
433-
needs_redraw = true;
434-
toggle_key(&mut uinput, layers[active_layer].buttons[btn as usize].action, 0);
435-
}
470+
layers[layer].buttons[btn as usize].set_active(&mut uinput, false);
436471
}
437472
_ => {}
438473
}

0 commit comments

Comments
 (0)