Fix damage issue when multiple buffers are in use

wldash was originally written to expect server-side shm buffer
optimizations, which make it so only a single buffer has to be in use.
This simplifies damage tracking and repaint needs.

Support for using multiple buffers was added to support e.g., jay, but
the damage handling was not in place for this to work. Fix that by
tracking damage per buffer.
This commit is contained in:
Kenny Levinsen
2025-02-27 16:38:52 +01:00
parent 40aec97f79
commit 9fd054fc2c
2 changed files with 16 additions and 10 deletions
+2
View File
@@ -83,6 +83,7 @@ pub struct ShmBuffer {
pub buffer: wl_buffer::WlBuffer, pub buffer: wl_buffer::WlBuffer,
pub refcnt: u32, pub refcnt: u32,
pub id: u32, pub id: u32,
pub last_damage: Vec<Geometry>,
} }
impl ShmBuffer { impl ShmBuffer {
@@ -111,6 +112,7 @@ impl ShmBuffer {
mmap, mmap,
buffer, buffer,
id, id,
last_damage: Vec::new(),
}) })
} }
+14 -10
View File
@@ -220,11 +220,6 @@ fn main() {
keyrepeat_sender, keyrepeat_sender,
); );
let mut damage = Vec::new();
for _ in 0..state.widgets.len() {
damage.push(Geometry::new());
}
// Initial setup // Initial setup
// //
while state.running && !state.ready { while state.running && !state.ready {
@@ -249,7 +244,7 @@ fn main() {
force = true; force = true;
} }
// We expect to see the usual shm optimization let mut bufcnt = state.bufmgr.buffers.len();
let buf = match state.bufmgr.next_buffer() { let buf = match state.bufmgr.next_buffer() {
Some(b) => b, Some(b) => b,
None => { None => {
@@ -257,6 +252,8 @@ fn main() {
continue; continue;
} }
state.add_buffer(&qhandle); state.add_buffer(&qhandle);
bufcnt = state.bufmgr.buffers.len();
match state.bufmgr.next_buffer() { match state.bufmgr.next_buffer() {
Some(b) => b, Some(b) => b,
None => { None => {
@@ -266,6 +263,12 @@ fn main() {
} }
}; };
if buf.last_damage.len() == 0 {
for _ in 0..state.widgets.len() {
buf.last_damage.push(Geometry::new());
}
}
state.dirty = false; state.dirty = false;
buf.acquire(); buf.acquire();
let mut bufview = BufferView::new( let mut bufview = BufferView::new(
@@ -279,17 +282,18 @@ fn main() {
if force || widget.get_dirty() { if force || widget.get_dirty() {
let geo = widget.geometry(); let geo = widget.geometry();
let mut subview = bufview.subgeometry(geo); let mut subview = bufview.subgeometry(geo);
damage[idx] = widget.draw(&mut state.fonts.unwrap().borrow_mut(), &mut subview); buf.last_damage[idx] =
widget.draw(&mut state.fonts.unwrap().borrow_mut(), &mut subview);
} }
} }
surface.damage_buffer(0, 0, 0x7FFFFFFF, 0x7FFFFFFF); surface.damage_buffer(0, 0, 0x7FFFFFFF, 0x7FFFFFFF);
} else { } else {
let mut drew = false; let mut drew = false;
for (idx, widget) in state.widgets.iter_mut().enumerate() { for (idx, widget) in state.widgets.iter_mut().enumerate() {
if widget.get_dirty() { if bufcnt > 1 || widget.get_dirty() {
drew = true; drew = true;
let old_damage = damage[idx]; let old_damage = buf.last_damage[idx];
bufview.subgeometry(old_damage).clear(); bufview.subgeometry(old_damage).clear();
let geo = widget.geometry(); let geo = widget.geometry();
@@ -298,7 +302,7 @@ fn main() {
let new_damage = let new_damage =
widget.draw(&mut state.fonts.unwrap().borrow_mut(), &mut subview); widget.draw(&mut state.fonts.unwrap().borrow_mut(), &mut subview);
let combined_damage = new_damage.expand(old_damage); let combined_damage = new_damage.expand(old_damage);
damage[idx] = new_damage; buf.last_damage[idx] = new_damage;
surface.damage_buffer( surface.damage_buffer(
combined_damage.x as i32, combined_damage.x as i32,