Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
fix(server): resolve lagging and duplicating window shadows during resize scaling
src/server/window.rs | 40 ++++++++++++++++++++++++++++++++++++++++
src/server/wlroots_log_wrapper.c | 24 ++++++++++++++++++++----
wrapper.h | 2 ++
3 files changed, 62 insertions(+), 4 deletions(-)
diff --git a/src/server/window.rs b/src/server/window.rs
index 61b9bbb..1c08ca8 100644
--- a/src/server/window.rs
+++ b/src/server/window.rs
@@ -1606,6 +1606,17 @@ impl Window {
} else if data.scale == 1.0 {
ffi::river_scene_buffer_set_dest_size_if_changed(buffer, 0, 0);
ffi::river_scene_node_set_position_if_changed(node, sx, sy);
+ } else {
+ let w = ffi::river_scene_buffer_get_width(buffer);
+ let h = ffi::river_scene_buffer_get_height(buffer);
+ let dest_w = (w as f64 * data.scale) as i32;
+ let dest_h = (h as f64 * data.scale) as i32;
+ ffi::river_scene_buffer_set_dest_size_if_changed(buffer, dest_w, dest_h);
+
+ let (px, py) = get_parent_position_relative_to(node, data.ancestor);
+ let dest_x = (px as f64 * (data.scale - 1.0)) as i32;
+ let dest_y = (py as f64 * (data.scale - 1.0)) as i32;
+ ffi::river_scene_node_set_position_if_changed(node, dest_x, dest_y);
}
}
@@ -1615,6 +1626,15 @@ impl Window {
Some(set_expose_scale_iterator),
&scale_data_surfaces as *const ScaleData as *mut std::ffi::c_void,
);
+
+ if self.surfaces.saved {
+ let scale_data_saved = ScaleData { scale: self.scale, ancestor: self.surfaces.saved_tree as *mut ffi::wlr_scene_node };
+ ffi::wlr_scene_node_for_each_buffer(
+ self.surfaces.saved_tree as *mut ffi::wlr_scene_node,
+ Some(set_expose_scale_iterator),
+ &scale_data_saved as *const ScaleData as *mut std::ffi::c_void,
+ );
+ }
let scale_data_popup = ScaleData { scale: self.scale, ancestor: self.popup_tree as *mut ffi::wlr_scene_node };
ffi::wlr_scene_node_for_each_buffer(
@@ -2694,6 +2714,17 @@ impl Decoration {
} else if data.scale == 1.0 {
ffi::river_scene_buffer_set_dest_size_if_changed(buffer, 0, 0);
ffi::river_scene_node_set_position_if_changed(node, sx, sy);
+ } else {
+ let w = ffi::river_scene_buffer_get_width(buffer);
+ let h = ffi::river_scene_buffer_get_height(buffer);
+ let dest_w = (w as f64 * data.scale) as i32;
+ let dest_h = (h as f64 * data.scale) as i32;
+ ffi::river_scene_buffer_set_dest_size_if_changed(buffer, dest_w, dest_h);
+
+ let (px, py) = get_parent_position_relative_to(node, data.ancestor);
+ let dest_x = (px as f64 * (data.scale - 1.0)) as i32;
+ let dest_y = (py as f64 * (data.scale - 1.0)) as i32;
+ ffi::river_scene_node_set_position_if_changed(node, dest_x, dest_y);
}
}
@@ -2704,6 +2735,15 @@ impl Decoration {
&scale_data as *const ScaleData as *mut std::ffi::c_void,
);
+ if self.surfaces.saved {
+ let scale_data_saved = ScaleData { scale, ancestor: self.surfaces.saved_tree as *mut ffi::wlr_scene_node };
+ ffi::wlr_scene_node_for_each_buffer(
+ self.surfaces.saved_tree as *mut ffi::wlr_scene_node,
+ Some(set_expose_scale_iterator),
+ &scale_data_saved as *const ScaleData as *mut std::ffi::c_void,
+ );
+ }
+
let children_head = ffi::river_scene_tree_get_children(self.surfaces.tree) as *mut WlList;
if (*children_head).next != children_head {
ffi::wlr_scene_subsurface_tree_set_clip(self.surfaces.tree as *mut ffi::wlr_scene_node, std::ptr::null());
diff --git a/src/server/wlroots_log_wrapper.c b/src/server/wlroots_log_wrapper.c
index 45c5114..6d7a13b 100644
--- a/src/server/wlroots_log_wrapper.c
+++ b/src/server/wlroots_log_wrapper.c
@@ -102,11 +102,17 @@ struct wl_signal *river_scene_node_get_destroy_signal(struct wlr_scene_node *nod
static void save_surface_tree_iter(struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data) {
struct wlr_scene_tree *saved_tree = user_data;
- struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_create(saved_tree, buffer->buffer);
+ struct wlr_scene_tree *buffer_tree = wlr_scene_tree_create(saved_tree);
+ if (!buffer_tree) {
+ return;
+ }
+ wlr_scene_node_set_position(&buffer_tree->node, sx, sy);
+ struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_create(buffer_tree, buffer->buffer);
if (!scene_buffer) {
+ wlr_scene_node_destroy(&buffer_tree->node);
return;
}
- wlr_scene_node_set_position(&scene_buffer->node, sx, sy);
+ wlr_scene_node_set_position(&scene_buffer->node, 0, 0);
wlr_scene_buffer_set_dest_size(scene_buffer, buffer->dst_width, buffer->dst_height);
wlr_scene_buffer_set_source_box(scene_buffer, &buffer->src_box);
wlr_scene_buffer_set_transform(scene_buffer, buffer->transform);
@@ -692,6 +698,16 @@ void river_scene_rect_set_size_if_changed(struct wlr_scene_rect *rect, int width
}
}
+int river_scene_buffer_get_width(struct wlr_scene_buffer *scene_buffer) {
+ if (scene_buffer->buffer) {
+ return scene_buffer->buffer->width;
+ }
+ return scene_buffer->dst_width;
+}
-
-
+int river_scene_buffer_get_height(struct wlr_scene_buffer *scene_buffer) {
+ if (scene_buffer->buffer) {
+ return scene_buffer->buffer->height;
+ }
+ return scene_buffer->dst_height;
+}
diff --git a/wrapper.h b/wrapper.h
index 19e6311..715b85f 100644
--- a/wrapper.h
+++ b/wrapper.h
@@ -262,6 +262,8 @@ void river_scene_node_enable_blur(struct wlr_scene_node *node, bool enabled);
void river_scene_node_set_opacity(struct wlr_scene_node *node, float opacity);
void river_scene_buffer_set_dest_size_if_changed(struct wlr_scene_buffer *scene_buffer, int width, int height);
+int river_scene_buffer_get_width(struct wlr_scene_buffer *scene_buffer);
+int river_scene_buffer_get_height(struct wlr_scene_buffer *scene_buffer);
void river_scene_node_set_position_if_changed(struct wlr_scene_node *node, int x, int y);