mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	scene: switch to wlr_damage_ring
This commit is contained in:
		
							parent
							
								
									e0accb2d50
								
							
						
					
					
						commit
						97f0347780
					
				
					 2 changed files with 57 additions and 30 deletions
				
			
		| 
						 | 
					@ -22,6 +22,7 @@
 | 
				
			||||||
#include <pixman.h>
 | 
					#include <pixman.h>
 | 
				
			||||||
#include <wayland-server-core.h>
 | 
					#include <wayland-server-core.h>
 | 
				
			||||||
#include <wlr/types/wlr_compositor.h>
 | 
					#include <wlr/types/wlr_compositor.h>
 | 
				
			||||||
 | 
					#include <wlr/types/wlr_damage_ring.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_output;
 | 
					struct wlr_output;
 | 
				
			||||||
struct wlr_output_layout;
 | 
					struct wlr_output_layout;
 | 
				
			||||||
| 
						 | 
					@ -160,7 +161,7 @@ struct wlr_scene_output {
 | 
				
			||||||
	struct wlr_scene *scene;
 | 
						struct wlr_scene *scene;
 | 
				
			||||||
	struct wlr_addon addon;
 | 
						struct wlr_addon addon;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_output_damage *damage;
 | 
						struct wlr_damage_ring damage_ring;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int x, y;
 | 
						int x, y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -175,6 +176,7 @@ struct wlr_scene_output {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_listener output_commit;
 | 
						struct wl_listener output_commit;
 | 
				
			||||||
	struct wl_listener output_mode;
 | 
						struct wl_listener output_mode;
 | 
				
			||||||
 | 
						struct wl_listener output_needs_frame;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** A layer shell scene helper */
 | 
					/** A layer shell scene helper */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,8 +5,8 @@
 | 
				
			||||||
#include <wlr/backend.h>
 | 
					#include <wlr/backend.h>
 | 
				
			||||||
#include <wlr/render/wlr_renderer.h>
 | 
					#include <wlr/render/wlr_renderer.h>
 | 
				
			||||||
#include <wlr/types/wlr_compositor.h>
 | 
					#include <wlr/types/wlr_compositor.h>
 | 
				
			||||||
 | 
					#include <wlr/types/wlr_damage_ring.h>
 | 
				
			||||||
#include <wlr/types/wlr_matrix.h>
 | 
					#include <wlr/types/wlr_matrix.h>
 | 
				
			||||||
#include <wlr/types/wlr_output_damage.h>
 | 
					 | 
				
			||||||
#include <wlr/types/wlr_presentation_time.h>
 | 
					#include <wlr/types/wlr_presentation_time.h>
 | 
				
			||||||
#include <wlr/types/wlr_scene.h>
 | 
					#include <wlr/types/wlr_scene.h>
 | 
				
			||||||
#include <wlr/util/log.h>
 | 
					#include <wlr/util/log.h>
 | 
				
			||||||
| 
						 | 
					@ -422,8 +422,11 @@ void wlr_scene_buffer_set_buffer_with_damage(struct wlr_scene_buffer *scene_buff
 | 
				
			||||||
		wlr_region_scale_xy(&output_damage, &trans_damage,
 | 
							wlr_region_scale_xy(&output_damage, &trans_damage,
 | 
				
			||||||
			output_scale * scale_x, output_scale * scale_y);
 | 
								output_scale * scale_x, output_scale * scale_y);
 | 
				
			||||||
		pixman_region32_translate(&output_damage,
 | 
							pixman_region32_translate(&output_damage,
 | 
				
			||||||
			(lx - scene_output->x) * output_scale, (ly - scene_output->y) * output_scale);
 | 
								(lx - scene_output->x) * output_scale,
 | 
				
			||||||
		wlr_output_damage_add(scene_output->damage, &output_damage);
 | 
								(ly - scene_output->y) * output_scale);
 | 
				
			||||||
 | 
							if (wlr_damage_ring_add(&scene_output->damage_ring, &output_damage)) {
 | 
				
			||||||
 | 
								wlr_output_schedule_frame(scene_output->output);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		pixman_region32_fini(&output_damage);
 | 
							pixman_region32_fini(&output_damage);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -572,7 +575,9 @@ static void _scene_node_damage_whole(struct wlr_scene_node *node,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		scale_box(&box, scene_output->output->scale);
 | 
							scale_box(&box, scene_output->output->scale);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		wlr_output_damage_add_box(scene_output->damage, &box);
 | 
							if (wlr_damage_ring_add_box(&scene_output->damage_ring, &box)) {
 | 
				
			||||||
 | 
								wlr_output_schedule_frame(scene_output->output);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -969,6 +974,15 @@ static const struct wlr_addon_interface output_addon_impl = {
 | 
				
			||||||
	.destroy = scene_output_handle_destroy,
 | 
						.destroy = scene_output_handle_destroy,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void scene_output_update_geometry(struct wlr_scene_output *scene_output) {
 | 
				
			||||||
 | 
						int width, height;
 | 
				
			||||||
 | 
						wlr_output_transformed_resolution(scene_output->output, &width, &height);
 | 
				
			||||||
 | 
						wlr_damage_ring_set_bounds(&scene_output->damage_ring, width, height);
 | 
				
			||||||
 | 
						wlr_output_schedule_frame(scene_output->output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						scene_node_update_outputs(&scene_output->scene->tree.node, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void scene_output_handle_commit(struct wl_listener *listener, void *data) {
 | 
					static void scene_output_handle_commit(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct wlr_scene_output *scene_output = wl_container_of(listener,
 | 
						struct wlr_scene_output *scene_output = wl_container_of(listener,
 | 
				
			||||||
		scene_output, output_commit);
 | 
							scene_output, output_commit);
 | 
				
			||||||
| 
						 | 
					@ -977,14 +991,20 @@ static void scene_output_handle_commit(struct wl_listener *listener, void *data)
 | 
				
			||||||
	if (event->committed & (WLR_OUTPUT_STATE_MODE |
 | 
						if (event->committed & (WLR_OUTPUT_STATE_MODE |
 | 
				
			||||||
			WLR_OUTPUT_STATE_TRANSFORM |
 | 
								WLR_OUTPUT_STATE_TRANSFORM |
 | 
				
			||||||
			WLR_OUTPUT_STATE_SCALE)) {
 | 
								WLR_OUTPUT_STATE_SCALE)) {
 | 
				
			||||||
		scene_node_update_outputs(&scene_output->scene->tree.node, NULL);
 | 
							scene_output_update_geometry(scene_output);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void scene_output_handle_mode(struct wl_listener *listener, void *data) {
 | 
					static void scene_output_handle_mode(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct wlr_scene_output *scene_output = wl_container_of(listener,
 | 
						struct wlr_scene_output *scene_output = wl_container_of(listener,
 | 
				
			||||||
		scene_output, output_mode);
 | 
							scene_output, output_mode);
 | 
				
			||||||
	scene_node_update_outputs(&scene_output->scene->tree.node, NULL);
 | 
						scene_output_update_geometry(scene_output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void scene_output_handle_needs_frame(struct wl_listener *listener, void *data) {
 | 
				
			||||||
 | 
						struct wlr_scene_output *scene_output = wl_container_of(listener,
 | 
				
			||||||
 | 
							scene_output, output_needs_frame);
 | 
				
			||||||
 | 
						wlr_output_schedule_frame(scene_output->output);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene,
 | 
					struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene,
 | 
				
			||||||
| 
						 | 
					@ -994,16 +1014,12 @@ struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene,
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	scene_output->damage = wlr_output_damage_create(output);
 | 
					 | 
				
			||||||
	if (scene_output->damage == NULL) {
 | 
					 | 
				
			||||||
		free(scene_output);
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	scene_output->output = output;
 | 
						scene_output->output = output;
 | 
				
			||||||
	scene_output->scene = scene;
 | 
						scene_output->scene = scene;
 | 
				
			||||||
	wlr_addon_init(&scene_output->addon, &output->addons, scene, &output_addon_impl);
 | 
						wlr_addon_init(&scene_output->addon, &output->addons, scene, &output_addon_impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_damage_ring_init(&scene_output->damage_ring);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int prev_output_index = -1;
 | 
						int prev_output_index = -1;
 | 
				
			||||||
	struct wl_list *prev_output_link = &scene->outputs;
 | 
						struct wl_list *prev_output_link = &scene->outputs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1029,8 +1045,10 @@ struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene,
 | 
				
			||||||
	scene_output->output_mode.notify = scene_output_handle_mode;
 | 
						scene_output->output_mode.notify = scene_output_handle_mode;
 | 
				
			||||||
	wl_signal_add(&output->events.mode, &scene_output->output_mode);
 | 
						wl_signal_add(&output->events.mode, &scene_output->output_mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_output_damage_add_whole(scene_output->damage);
 | 
						scene_output->output_needs_frame.notify = scene_output_handle_needs_frame;
 | 
				
			||||||
	scene_node_update_outputs(&scene->tree.node, NULL);
 | 
						wl_signal_add(&output->events.needs_frame, &scene_output->output_needs_frame);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						scene_output_update_geometry(scene_output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return scene_output;
 | 
						return scene_output;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1045,9 +1063,11 @@ void wlr_scene_output_destroy(struct wlr_scene_output *scene_output) {
 | 
				
			||||||
	scene_node_update_outputs(&scene_output->scene->tree.node, scene_output);
 | 
						scene_node_update_outputs(&scene_output->scene->tree.node, scene_output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_addon_finish(&scene_output->addon);
 | 
						wlr_addon_finish(&scene_output->addon);
 | 
				
			||||||
 | 
						wlr_damage_ring_finish(&scene_output->damage_ring);
 | 
				
			||||||
	wl_list_remove(&scene_output->link);
 | 
						wl_list_remove(&scene_output->link);
 | 
				
			||||||
	wl_list_remove(&scene_output->output_commit.link);
 | 
						wl_list_remove(&scene_output->output_commit.link);
 | 
				
			||||||
	wl_list_remove(&scene_output->output_mode.link);
 | 
						wl_list_remove(&scene_output->output_mode.link);
 | 
				
			||||||
 | 
						wl_list_remove(&scene_output->output_needs_frame.link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(scene_output);
 | 
						free(scene_output);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1072,9 +1092,8 @@ void wlr_scene_output_set_position(struct wlr_scene_output *scene_output,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	scene_output->x = lx;
 | 
						scene_output->x = lx;
 | 
				
			||||||
	scene_output->y = ly;
 | 
						scene_output->y = ly;
 | 
				
			||||||
	wlr_output_damage_add_whole(scene_output->damage);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	scene_node_update_outputs(&scene_output->scene->tree.node, NULL);
 | 
						scene_output_update_geometry(scene_output);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct check_scanout_data {
 | 
					struct check_scanout_data {
 | 
				
			||||||
| 
						 | 
					@ -1174,7 +1193,7 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
 | 
				
			||||||
		wlr_log(WLR_DEBUG, "Direct scan-out %s",
 | 
							wlr_log(WLR_DEBUG, "Direct scan-out %s",
 | 
				
			||||||
			scanout ? "enabled" : "disabled");
 | 
								scanout ? "enabled" : "disabled");
 | 
				
			||||||
		// When exiting direct scan-out, damage everything
 | 
							// When exiting direct scan-out, damage everything
 | 
				
			||||||
		wlr_output_damage_add_whole(scene_output->damage);
 | 
							wlr_damage_ring_add_whole(&scene_output->damage_ring);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	scene_output->prev_scanout = scanout;
 | 
						scene_output->prev_scanout = scanout;
 | 
				
			||||||
	if (scanout) {
 | 
						if (scanout) {
 | 
				
			||||||
| 
						 | 
					@ -1182,7 +1201,7 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (debug_damage == WLR_SCENE_DEBUG_DAMAGE_RERENDER) {
 | 
						if (debug_damage == WLR_SCENE_DEBUG_DAMAGE_RERENDER) {
 | 
				
			||||||
		wlr_output_damage_add_whole(scene_output->damage);
 | 
							wlr_damage_ring_add_whole(&scene_output->damage_ring);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct timespec now;
 | 
						struct timespec now;
 | 
				
			||||||
| 
						 | 
					@ -1191,13 +1210,13 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
 | 
				
			||||||
		clock_gettime(CLOCK_MONOTONIC, &now);
 | 
							clock_gettime(CLOCK_MONOTONIC, &now);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// add the current frame's damage if there is damage
 | 
							// add the current frame's damage if there is damage
 | 
				
			||||||
		if (pixman_region32_not_empty(&scene_output->damage->current)) {
 | 
							if (pixman_region32_not_empty(&scene_output->damage_ring.current)) {
 | 
				
			||||||
			struct highlight_region *current_damage =
 | 
								struct highlight_region *current_damage =
 | 
				
			||||||
				calloc(1, sizeof(*current_damage));
 | 
									calloc(1, sizeof(*current_damage));
 | 
				
			||||||
			if (current_damage) {
 | 
								if (current_damage) {
 | 
				
			||||||
				pixman_region32_init(¤t_damage->region);
 | 
									pixman_region32_init(¤t_damage->region);
 | 
				
			||||||
				pixman_region32_copy(¤t_damage->region,
 | 
									pixman_region32_copy(¤t_damage->region,
 | 
				
			||||||
					&scene_output->damage->current);
 | 
										&scene_output->damage_ring.current);
 | 
				
			||||||
				memcpy(¤t_damage->when, &now, sizeof(now));
 | 
									memcpy(¤t_damage->when, &now, sizeof(now));
 | 
				
			||||||
				wl_list_insert(regions, ¤t_damage->link);
 | 
									wl_list_insert(regions, ¤t_damage->link);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -1220,20 +1239,21 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		wlr_output_damage_add(scene_output->damage, &acc_damage);
 | 
							wlr_damage_ring_add(&scene_output->damage_ring, &acc_damage);
 | 
				
			||||||
		pixman_region32_fini(&acc_damage);
 | 
							pixman_region32_fini(&acc_damage);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool needs_frame;
 | 
						int buffer_age;
 | 
				
			||||||
	pixman_region32_t damage;
 | 
						if (!wlr_output_attach_render(output, &buffer_age)) {
 | 
				
			||||||
	pixman_region32_init(&damage);
 | 
					 | 
				
			||||||
	if (!wlr_output_damage_attach_render(scene_output->damage,
 | 
					 | 
				
			||||||
			&needs_frame, &damage)) {
 | 
					 | 
				
			||||||
		pixman_region32_fini(&damage);
 | 
					 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!needs_frame) {
 | 
						pixman_region32_t damage;
 | 
				
			||||||
 | 
						pixman_region32_init(&damage);
 | 
				
			||||||
 | 
						wlr_damage_ring_get_buffer_damage(&scene_output->damage_ring,
 | 
				
			||||||
 | 
							buffer_age, &damage);
 | 
				
			||||||
 | 
						if (!output->needs_frame && !pixman_region32_not_empty(
 | 
				
			||||||
 | 
								&scene_output->damage_ring.current)) {
 | 
				
			||||||
		pixman_region32_fini(&damage);
 | 
							pixman_region32_fini(&damage);
 | 
				
			||||||
		wlr_output_rollback(output);
 | 
							wlr_output_rollback(output);
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
| 
						 | 
					@ -1294,13 +1314,18 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pixman_region32_t frame_damage;
 | 
						pixman_region32_t frame_damage;
 | 
				
			||||||
	pixman_region32_init(&frame_damage);
 | 
						pixman_region32_init(&frame_damage);
 | 
				
			||||||
	wlr_region_transform(&frame_damage, &scene_output->damage->current,
 | 
						wlr_region_transform(&frame_damage,
 | 
				
			||||||
 | 
							&scene_output->damage_ring.current,
 | 
				
			||||||
		transform, tr_width, tr_height);
 | 
							transform, tr_width, tr_height);
 | 
				
			||||||
	wlr_output_set_damage(output, &frame_damage);
 | 
						wlr_output_set_damage(output, &frame_damage);
 | 
				
			||||||
	pixman_region32_fini(&frame_damage);
 | 
						pixman_region32_fini(&frame_damage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool success = wlr_output_commit(output);
 | 
						bool success = wlr_output_commit(output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (success) {
 | 
				
			||||||
 | 
							wlr_damage_ring_rotate(&scene_output->damage_ring);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (debug_damage == WLR_SCENE_DEBUG_DAMAGE_HIGHLIGHT &&
 | 
						if (debug_damage == WLR_SCENE_DEBUG_DAMAGE_HIGHLIGHT &&
 | 
				
			||||||
			!wl_list_empty(&scene_output->scene->damage_highlight_regions)) {
 | 
								!wl_list_empty(&scene_output->scene->damage_highlight_regions)) {
 | 
				
			||||||
		wlr_output_schedule_frame(scene_output->output);
 | 
							wlr_output_schedule_frame(scene_output->output);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue