desktop: track damage per space/output
This commit is contained in:
parent
3b39d780fe
commit
94968e2d0f
|
@ -6,7 +6,7 @@ use crate::{
|
||||||
SurfaceAttributes, TraversalAction,
|
SurfaceAttributes, TraversalAction,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::cell::RefCell;
|
use std::{cell::RefCell, collections::HashSet};
|
||||||
use wayland_server::protocol::{wl_buffer::WlBuffer, wl_surface::WlSurface};
|
use wayland_server::protocol::{wl_buffer::WlBuffer, wl_surface::WlSurface};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -15,6 +15,7 @@ pub(crate) struct SurfaceState {
|
||||||
pub(crate) buffer_scale: i32,
|
pub(crate) buffer_scale: i32,
|
||||||
pub(crate) buffer: Option<WlBuffer>,
|
pub(crate) buffer: Option<WlBuffer>,
|
||||||
pub(crate) texture: Option<Box<dyn std::any::Any + 'static>>,
|
pub(crate) texture: Option<Box<dyn std::any::Any + 'static>>,
|
||||||
|
pub(crate) damage_seen: HashSet<(usize, *const ())>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SurfaceState {
|
impl SurfaceState {
|
||||||
|
@ -30,6 +31,7 @@ impl SurfaceState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.texture = None;
|
self.texture = None;
|
||||||
|
self.damage_seen.clear();
|
||||||
}
|
}
|
||||||
Some(BufferAssignment::Removed) => {
|
Some(BufferAssignment::Removed) => {
|
||||||
// remove the contents
|
// remove the contents
|
||||||
|
@ -38,6 +40,7 @@ impl SurfaceState {
|
||||||
buffer.release();
|
buffer.release();
|
||||||
};
|
};
|
||||||
self.texture = None;
|
self.texture = None;
|
||||||
|
self.damage_seen.clear();
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::renderer::{utils::draw_surface_tree, Frame, ImportAll, Renderer, Texture},
|
backend::renderer::{utils::draw_surface_tree, Frame, ImportAll, Renderer, Texture},
|
||||||
desktop::{utils::*, PopupManager},
|
desktop::{utils::*, PopupManager, Space},
|
||||||
utils::{user_data::UserDataMap, Logical, Point, Rectangle},
|
utils::{user_data::UserDataMap, Logical, Point, Rectangle},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::with_states,
|
compositor::with_states,
|
||||||
|
@ -423,17 +423,20 @@ impl LayerSurface {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Damage of all the surfaces of this layer
|
/// Damage of all the surfaces of this layer
|
||||||
pub(super) fn accumulated_damage(&self) -> Vec<Rectangle<i32, Logical>> {
|
pub(super) fn accumulated_damage(
|
||||||
|
&self,
|
||||||
|
for_values: Option<(&Space, &Output)>,
|
||||||
|
) -> Vec<Rectangle<i32, Logical>> {
|
||||||
let mut damage = Vec::new();
|
let mut damage = Vec::new();
|
||||||
if let Some(surface) = self.get_surface() {
|
if let Some(surface) = self.get_surface() {
|
||||||
damage.extend(damage_from_surface_tree(surface, (0, 0)));
|
damage.extend(damage_from_surface_tree(surface, (0, 0), for_values));
|
||||||
for (popup, location) in PopupManager::popups_for_surface(surface)
|
for (popup, location) in PopupManager::popups_for_surface(surface)
|
||||||
.ok()
|
.ok()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
{
|
{
|
||||||
if let Some(surface) = popup.get_surface() {
|
if let Some(surface) = popup.get_surface() {
|
||||||
let popup_damage = damage_from_surface_tree(surface, location);
|
let popup_damage = damage_from_surface_tree(surface, location, for_values);
|
||||||
damage.extend(popup_damage);
|
damage.extend(popup_damage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ pub enum SpaceError {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Space {
|
pub struct Space {
|
||||||
id: usize,
|
pub(super) id: usize,
|
||||||
// in z-order, back to front
|
// in z-order, back to front
|
||||||
windows: IndexSet<Window>,
|
windows: IndexSet<Window>,
|
||||||
outputs: Vec<Output>,
|
outputs: Vec<Output>,
|
||||||
|
@ -450,10 +450,15 @@ impl Space {
|
||||||
} else {
|
} else {
|
||||||
// window stayed at its place
|
// window stayed at its place
|
||||||
let loc = window_loc(window, &self.id);
|
let loc = window_loc(window, &self.id);
|
||||||
damage.extend(window.accumulated_damage().into_iter().map(|mut rect| {
|
damage.extend(
|
||||||
|
window
|
||||||
|
.accumulated_damage(Some((self, output)))
|
||||||
|
.into_iter()
|
||||||
|
.map(|mut rect| {
|
||||||
rect.loc += loc;
|
rect.loc += loc;
|
||||||
rect
|
rect
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for layer in layer_map.layers() {
|
for layer in layer_map.layers() {
|
||||||
|
@ -467,10 +472,15 @@ impl Space {
|
||||||
damage.push(geo);
|
damage.push(geo);
|
||||||
} else {
|
} else {
|
||||||
let location = geo.loc;
|
let location = geo.loc;
|
||||||
damage.extend(layer.accumulated_damage().into_iter().map(|mut rect| {
|
damage.extend(
|
||||||
|
layer
|
||||||
|
.accumulated_damage(Some((self, output)))
|
||||||
|
.into_iter()
|
||||||
|
.map(|mut rect| {
|
||||||
rect.loc += location;
|
rect.loc += location;
|
||||||
rect
|
rect
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::renderer::utils::SurfaceState,
|
backend::renderer::utils::SurfaceState,
|
||||||
|
desktop::Space,
|
||||||
utils::{Logical, Point, Rectangle, Size},
|
utils::{Logical, Point, Rectangle, Size},
|
||||||
wayland::compositor::{
|
wayland::{
|
||||||
|
compositor::{
|
||||||
with_surface_tree_downward, with_surface_tree_upward, Damage, SubsurfaceCachedState,
|
with_surface_tree_downward, with_surface_tree_upward, Damage, SubsurfaceCachedState,
|
||||||
SurfaceAttributes, TraversalAction,
|
SurfaceAttributes, TraversalAction,
|
||||||
},
|
},
|
||||||
|
output::Output,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use wayland_server::protocol::wl_surface;
|
use wayland_server::protocol::wl_surface;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::{cell::RefCell, sync::Arc};
|
||||||
|
|
||||||
impl SurfaceState {
|
impl SurfaceState {
|
||||||
/// Returns the size of the surface.
|
/// Returns the size of the surface.
|
||||||
|
@ -86,11 +90,13 @@ where
|
||||||
pub fn damage_from_surface_tree<P>(
|
pub fn damage_from_surface_tree<P>(
|
||||||
surface: &wl_surface::WlSurface,
|
surface: &wl_surface::WlSurface,
|
||||||
location: P,
|
location: P,
|
||||||
|
key: Option<(&Space, &Output)>,
|
||||||
) -> Vec<Rectangle<i32, Logical>>
|
) -> Vec<Rectangle<i32, Logical>>
|
||||||
where
|
where
|
||||||
P: Into<Point<i32, Logical>>,
|
P: Into<Point<i32, Logical>>,
|
||||||
{
|
{
|
||||||
let mut damage = Vec::new();
|
let mut damage = Vec::new();
|
||||||
|
let key = key.map(|(space, output)| (space.id, Arc::as_ptr(&output.inner) as *const ()));
|
||||||
with_surface_tree_upward(
|
with_surface_tree_upward(
|
||||||
surface,
|
surface,
|
||||||
location.into(),
|
location.into(),
|
||||||
|
@ -98,7 +104,11 @@ where
|
||||||
let mut location = *location;
|
let mut location = *location;
|
||||||
if let Some(data) = states.data_map.get::<RefCell<SurfaceState>>() {
|
if let Some(data) = states.data_map.get::<RefCell<SurfaceState>>() {
|
||||||
let data = data.borrow();
|
let data = data.borrow();
|
||||||
if data.texture.is_none() {
|
if key
|
||||||
|
.as_ref()
|
||||||
|
.map(|key| !data.damage_seen.contains(key))
|
||||||
|
.unwrap_or(true)
|
||||||
|
{
|
||||||
if states.role == Some("subsurface") {
|
if states.role == Some("subsurface") {
|
||||||
let current = states.cached_state.current::<SubsurfaceCachedState>();
|
let current = states.cached_state.current::<SubsurfaceCachedState>();
|
||||||
location += current.location;
|
location += current.location;
|
||||||
|
@ -110,10 +120,14 @@ where
|
||||||
|_surface, states, location| {
|
|_surface, states, location| {
|
||||||
let mut location = *location;
|
let mut location = *location;
|
||||||
if let Some(data) = states.data_map.get::<RefCell<SurfaceState>>() {
|
if let Some(data) = states.data_map.get::<RefCell<SurfaceState>>() {
|
||||||
let data = data.borrow();
|
let mut data = data.borrow_mut();
|
||||||
let attributes = states.cached_state.current::<SurfaceAttributes>();
|
let attributes = states.cached_state.current::<SurfaceAttributes>();
|
||||||
|
|
||||||
if data.texture.is_none() {
|
if key
|
||||||
|
.as_ref()
|
||||||
|
.map(|key| !data.damage_seen.contains(key))
|
||||||
|
.unwrap_or(true)
|
||||||
|
{
|
||||||
if states.role == Some("subsurface") {
|
if states.role == Some("subsurface") {
|
||||||
let current = states.cached_state.current::<SubsurfaceCachedState>();
|
let current = states.cached_state.current::<SubsurfaceCachedState>();
|
||||||
location += current.location;
|
location += current.location;
|
||||||
|
@ -127,6 +141,10 @@ where
|
||||||
rect.loc += location;
|
rect.loc += location;
|
||||||
rect
|
rect
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
if let Some(key) = key {
|
||||||
|
data.damage_seen.insert(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::renderer::{utils::draw_surface_tree, Frame, ImportAll, Renderer, Texture},
|
backend::renderer::{utils::draw_surface_tree, Frame, ImportAll, Renderer, Texture},
|
||||||
desktop::{utils::*, PopupManager},
|
desktop::{utils::*, PopupManager, Space},
|
||||||
utils::{Logical, Point, Rectangle},
|
utils::{Logical, Point, Rectangle},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::with_states,
|
compositor::with_states,
|
||||||
|
output::Output,
|
||||||
shell::xdg::{SurfaceCachedState, ToplevelSurface},
|
shell::xdg::{SurfaceCachedState, ToplevelSurface},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -245,17 +246,20 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Damage of all the surfaces of this window
|
/// Damage of all the surfaces of this window
|
||||||
pub(super) fn accumulated_damage(&self) -> Vec<Rectangle<i32, Logical>> {
|
pub(super) fn accumulated_damage(
|
||||||
|
&self,
|
||||||
|
for_values: Option<(&Space, &Output)>,
|
||||||
|
) -> Vec<Rectangle<i32, Logical>> {
|
||||||
let mut damage = Vec::new();
|
let mut damage = Vec::new();
|
||||||
if let Some(surface) = self.0.toplevel.get_surface() {
|
if let Some(surface) = self.0.toplevel.get_surface() {
|
||||||
damage.extend(damage_from_surface_tree(surface, (0, 0)));
|
damage.extend(damage_from_surface_tree(surface, (0, 0), for_values));
|
||||||
for (popup, location) in PopupManager::popups_for_surface(surface)
|
for (popup, location) in PopupManager::popups_for_surface(surface)
|
||||||
.ok()
|
.ok()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
{
|
{
|
||||||
if let Some(surface) = popup.get_surface() {
|
if let Some(surface) = popup.get_surface() {
|
||||||
let popup_damage = damage_from_surface_tree(surface, location);
|
let popup_damage = damage_from_surface_tree(surface, location, for_values);
|
||||||
damage.extend(popup_damage);
|
damage.extend(popup_damage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue