diff --git a/include/wlr/types/wlr_scene.h b/include/wlr/types/wlr_scene.h index 3af839aba..17acf3388 100644 --- a/include/wlr/types/wlr_scene.h +++ b/include/wlr/types/wlr_scene.h @@ -204,6 +204,8 @@ struct wlr_scene_output { // private state + pixman_region32_t pending_commit_damage; + uint8_t index; bool prev_scanout; diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index 097d47c39..75ea6bccd 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -1274,6 +1274,14 @@ static void scene_output_handle_commit(struct wl_listener *listener, void *data) WLR_OUTPUT_STATE_ENABLED)) { scene_output_update_geometry(scene_output); } + + // if the output has been committed with a certain damage, we know that region + // will be acknowledged by the backend so we don't need to keep track of it + // anymore + if (state->committed & WLR_OUTPUT_STATE_DAMAGE) { + pixman_region32_subtract(&scene_output->pending_commit_damage, + &scene_output->pending_commit_damage, &state->damage); + } } static void scene_output_handle_damage(struct wl_listener *listener, void *data) { @@ -1303,6 +1311,7 @@ struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene, wlr_addon_init(&scene_output->addon, &output->addons, scene, &output_addon_impl); wlr_damage_ring_init(&scene_output->damage_ring); + pixman_region32_init(&scene_output->pending_commit_damage); wl_list_init(&scene_output->damage_highlight_regions); int prev_output_index = -1; @@ -1361,6 +1370,7 @@ void wlr_scene_output_destroy(struct wlr_scene_output *scene_output) { wlr_addon_finish(&scene_output->addon); wlr_damage_ring_finish(&scene_output->damage_ring); + pixman_region32_fini(&scene_output->pending_commit_damage); wl_list_remove(&scene_output->link); wl_list_remove(&scene_output->output_commit.link); wl_list_remove(&scene_output->output_damage.link); @@ -1464,9 +1474,15 @@ static bool construct_render_list_iterator(struct wlr_scene_node *node, static void output_state_apply_damage(const struct render_data *data, struct wlr_output_state *state) { + struct wlr_scene_output *output = data->output; + pixman_region32_union(&output->pending_commit_damage, + &output->pending_commit_damage, &output->damage_ring.current); + pixman_region32_intersect_rect(&output->pending_commit_damage, + &output->pending_commit_damage, 0, 0, data->trans_width, data->trans_height); + pixman_region32_t frame_damage; pixman_region32_init(&frame_damage); - pixman_region32_copy(&frame_damage, &data->output->damage_ring.current); + pixman_region32_copy(&frame_damage, &output->pending_commit_damage); transform_output_damage(&frame_damage, data); wlr_output_state_set_damage(state, &frame_damage); pixman_region32_fini(&frame_damage); @@ -1599,7 +1615,7 @@ static bool scene_entry_try_direct_scanout(struct render_list_entry *entry, bool wlr_scene_output_commit(struct wlr_scene_output *scene_output, const struct wlr_scene_output_state_options *options) { if (!scene_output->output->needs_frame && !pixman_region32_not_empty( - &scene_output->damage_ring.current)) { + &scene_output->pending_commit_damage)) { return true; }