desktop: Only render surface damage, if window was not moved

This commit is contained in:
Victor Brekenfeld 2021-11-28 22:30:17 +01:00
parent 98906555f5
commit 44829d8fba
2 changed files with 60 additions and 8 deletions

View File

@ -287,14 +287,15 @@ impl Space {
if old_geo.map(|old_geo| old_geo != geo).unwrap_or(false) { if old_geo.map(|old_geo| old_geo != geo).unwrap_or(false) {
// Add damage for the old position of the window // Add damage for the old position of the window
damage.push(old_geo.unwrap()); damage.push(old_geo.unwrap());
} /* else {
// window stayed at its place
// TODO: Only push surface damage
// But this would need to take subsurfaces into account and accumulate damage at least.
// Even better would be if damage would be ignored that is hidden by subsurfaces...
}*/
// Add damage for the new position (see TODO above for a better approach)
damage.push(geo); damage.push(geo);
} else {
// window stayed at its place
let loc = window_loc(window, &self.id);
damage.extend(window.accumulated_damage().into_iter().map(|mut rect| {
rect.loc += loc;
rect
}));
}
} }
// That is all completely new damage, which we need to store for subsequent renders // That is all completely new damage, which we need to store for subsequent renders

View File

@ -374,6 +374,57 @@ impl Window {
found.into_inner() found.into_inner()
} }
/// Damage of all the surfaces of this window
pub(super) fn accumulated_damage(&self) -> Vec<Rectangle<i32, Logical>> {
let mut damage = Vec::new();
let location = (0, 0).into();
if let Some(surface) = self.0.toplevel.get_surface() {
with_surface_tree_upward(
surface,
location,
|_surface, states, location| {
let mut location = *location;
if let Some(data) = states.data_map.get::<RefCell<SurfaceState>>() {
let data = data.borrow();
if data.texture.is_none() {
if states.role == Some("subsurface") {
let current = states.cached_state.current::<SubsurfaceCachedState>();
location += current.location;
}
return TraversalAction::DoChildren(location);
}
}
TraversalAction::SkipChildren
},
|_surface, states, location| {
let mut location = *location;
if let Some(data) = states.data_map.get::<RefCell<SurfaceState>>() {
let data = data.borrow();
let attributes = states.cached_state.current::<SurfaceAttributes>();
if data.texture.is_none() {
if states.role == Some("subsurface") {
let current = states.cached_state.current::<SubsurfaceCachedState>();
location += current.location;
}
damage.extend(attributes.damage.iter().map(|dmg| {
let mut rect = match dmg {
Damage::Buffer(rect) => rect.to_logical(attributes.buffer_scale),
Damage::Surface(rect) => *rect,
};
rect.loc += location;
rect
}));
}
}
},
|_, _, _| true,
)
}
damage
}
pub fn toplevel(&self) -> &Kind { pub fn toplevel(&self) -> &Kind {
&self.0.toplevel &self.0.toplevel
} }