opt: opitmize subtree surface scale in overview

This commit is contained in:
DreamMaoMao 2026-05-21 21:28:38 +08:00
parent 096ef0bf41
commit 406a16033b
3 changed files with 71 additions and 15 deletions

View file

@ -243,11 +243,31 @@ void scene_buffer_apply_overview_effect(struct wlr_scene_buffer *buffer,
int32_t sx, int32_t sy, void *data) {
BufferData *buffer_data = (BufferData *)data;
if (buffer_data->width > 0 && buffer_data->height > 0) {
wlr_scene_buffer_set_dest_size(buffer, buffer_data->width,
buffer_data->height);
if (buffer_data->width_scale >= 1.0 || buffer_data->height_scale >= 1.0)
return;
int32_t surface_width = 0;
int32_t surface_height = 0;
bool is_subsurface = false;
struct wlr_scene_tree *parent_tree = buffer->node.parent;
if (parent_tree->node.data != NULL) {
SnapshotMetadata *meta = (SnapshotMetadata *)parent_tree->node.data;
surface_width = meta->orig_width;
surface_height = meta->orig_height;
is_subsurface = meta->is_subsurface;
}
surface_height = surface_height * buffer_data->height_scale;
surface_width = surface_width * buffer_data->width_scale;
if (buffer_data->width > 0 && buffer_data->height > 0) {
wlr_scene_buffer_set_dest_size(buffer, surface_width, surface_height);
}
if (is_subsurface)
return;
wlr_scene_buffer_set_corner_radius(buffer, config.border_radius,
buffer_data->corner_location);
}

View file

@ -28,6 +28,12 @@ struct dvec2 calculate_animation_curve_at(double t, int32_t type) {
return point;
}
void handle_snapshot_meta_destroy(struct wl_listener *listener, void *data) {
SnapshotMetadata *meta = wl_container_of(listener, meta, destroy);
wl_list_remove(&meta->destroy.link); // 安全移除监听器
free(meta);
}
void init_baked_points(void) {
baked_points_move = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_move));
baked_points_open = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_open));
@ -154,12 +160,43 @@ static bool scene_node_snapshot(struct wlr_scene_node *node, int32_t lx,
struct wlr_scene_buffer *scene_buffer =
wlr_scene_buffer_from_node(node);
struct wlr_scene_buffer *snapshot_buffer =
wlr_scene_buffer_create(snapshot_tree, NULL);
if (snapshot_buffer == NULL) {
// 创建中间包装树节点
struct wlr_scene_tree *wrapper = wlr_scene_tree_create(snapshot_tree);
if (wrapper == NULL) {
return false;
}
snapshot_node = &snapshot_buffer->node;
snapshot_node = &wrapper->node; // 坐标位移应用在外层包装盒上
// 收集表面状态并保存为元数据
SnapshotMetadata *meta = calloc(1, sizeof(SnapshotMetadata));
if (meta == NULL) {
wlr_scene_node_destroy(&wrapper->node);
return false;
}
meta->orig_width = scene_buffer->dst_width;
meta->orig_height = scene_buffer->dst_height;
struct wlr_scene_surface *scene_surface =
wlr_scene_surface_try_from_buffer(scene_buffer);
if (scene_surface != NULL) {
meta->is_subsurface =
!!wlr_subsurface_try_from_wlr_surface(scene_surface->surface);
}
// 绑定销毁回调监听,随包装节点销毁而释放内存
meta->destroy.notify = handle_snapshot_meta_destroy;
wl_signal_add(&wrapper->node.events.destroy, &meta->destroy);
wrapper->node.data = meta;
// 将真正的 buffer 挂靠在 wrapper 下面相对坐标0,0
struct wlr_scene_buffer *snapshot_buffer =
wlr_scene_buffer_create(wrapper, NULL);
if (snapshot_buffer == NULL) {
wlr_scene_node_destroy(&wrapper->node);
return false;
}
// 保留原生的 data 指针(如 Client*),防止事件派发/焦点获取失效
snapshot_buffer->node.data = scene_buffer->node.data;
wlr_scene_buffer_set_dest_size(snapshot_buffer, scene_buffer->dst_width,
@ -179,16 +216,8 @@ static bool scene_node_snapshot(struct wlr_scene_node *node, int32_t lx,
scene_buffer->corner_radius,
scene_buffer->corners);
// wlr_scene_buffer_set_backdrop_blur_optimized(
// snapshot_buffer, scene_buffer->backdrop_blur_optimized);
// wlr_scene_buffer_set_backdrop_blur_ignore_transparent(
// snapshot_buffer, scene_buffer->backdrop_blur_ignore_transparent);
wlr_scene_buffer_set_backdrop_blur(snapshot_buffer, false);
snapshot_buffer->node.data = scene_buffer->node.data;
struct wlr_scene_surface *scene_surface =
wlr_scene_surface_try_from_buffer(scene_buffer);
if (scene_surface != NULL && scene_surface->surface->buffer != NULL) {
wlr_scene_buffer_set_buffer(snapshot_buffer,
&scene_surface->surface->buffer->base);

View file

@ -606,6 +606,13 @@ struct TagScrollerState {
int count;
};
typedef struct {
int32_t orig_width;
int32_t orig_height;
bool is_subsurface;
struct wl_listener destroy;
} SnapshotMetadata;
/* function declarations */
static void applybounds(
Client *c,