mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	backend/wayland: re-use wl_buffers
Instead of re-importing a buffer each time we submit a new frame, re-use the wl_buffer objects if possible.
This commit is contained in:
		
							parent
							
								
									de896caceb
								
							
						
					
					
						commit
						defcd9b025
					
				
					 3 changed files with 46 additions and 4 deletions
				
			
		| 
						 | 
					@ -210,6 +210,11 @@ static void backend_destroy(struct wlr_backend *backend) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_drm_format_set_finish(&wl->linux_dmabuf_v1_formats);
 | 
						wlr_drm_format_set_finish(&wl->linux_dmabuf_v1_formats);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_wl_buffer *buffer, *tmp_buffer;
 | 
				
			||||||
 | 
						wl_list_for_each_safe(buffer, tmp_buffer, &wl->buffers, link) {
 | 
				
			||||||
 | 
							destroy_wl_buffer(buffer);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	destroy_wl_seats(wl);
 | 
						destroy_wl_seats(wl);
 | 
				
			||||||
	if (wl->zxdg_decoration_manager_v1) {
 | 
						if (wl->zxdg_decoration_manager_v1) {
 | 
				
			||||||
		zxdg_decoration_manager_v1_destroy(wl->zxdg_decoration_manager_v1);
 | 
							zxdg_decoration_manager_v1_destroy(wl->zxdg_decoration_manager_v1);
 | 
				
			||||||
| 
						 | 
					@ -270,6 +275,7 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display,
 | 
				
			||||||
	wl_list_init(&wl->devices);
 | 
						wl_list_init(&wl->devices);
 | 
				
			||||||
	wl_list_init(&wl->outputs);
 | 
						wl_list_init(&wl->outputs);
 | 
				
			||||||
	wl_list_init(&wl->seats);
 | 
						wl_list_init(&wl->seats);
 | 
				
			||||||
 | 
						wl_list_init(&wl->buffers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl->remote_display = wl_display_connect(remote);
 | 
						wl->remote_display = wl_display_connect(remote);
 | 
				
			||||||
	if (!wl->remote_display) {
 | 
						if (!wl->remote_display) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -133,24 +133,33 @@ static bool output_attach_render(struct wlr_output *wlr_output,
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void destroy_wl_buffer(struct wlr_wl_buffer *buffer) {
 | 
					void destroy_wl_buffer(struct wlr_wl_buffer *buffer) {
 | 
				
			||||||
	if (buffer == NULL) {
 | 
						if (buffer == NULL) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						wl_list_remove(&buffer->buffer_destroy.link);
 | 
				
			||||||
 | 
						wl_list_remove(&buffer->link);
 | 
				
			||||||
	wl_buffer_destroy(buffer->wl_buffer);
 | 
						wl_buffer_destroy(buffer->wl_buffer);
 | 
				
			||||||
	wlr_buffer_unlock(buffer->buffer);
 | 
					 | 
				
			||||||
	free(buffer);
 | 
						free(buffer);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void buffer_handle_release(void *data, struct wl_buffer *wl_buffer) {
 | 
					static void buffer_handle_release(void *data, struct wl_buffer *wl_buffer) {
 | 
				
			||||||
	struct wlr_wl_buffer *buffer = data;
 | 
						struct wlr_wl_buffer *buffer = data;
 | 
				
			||||||
	destroy_wl_buffer(buffer);
 | 
						buffer->released = true;
 | 
				
			||||||
 | 
						wlr_buffer_unlock(buffer->buffer); // might free buffer
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct wl_buffer_listener buffer_listener = {
 | 
					static const struct wl_buffer_listener buffer_listener = {
 | 
				
			||||||
	.release = buffer_handle_release,
 | 
						.release = buffer_handle_release,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void buffer_handle_buffer_destroy(struct wl_listener *listener,
 | 
				
			||||||
 | 
							void *data) {
 | 
				
			||||||
 | 
						struct wlr_wl_buffer *buffer =
 | 
				
			||||||
 | 
							wl_container_of(listener, buffer, buffer_destroy);
 | 
				
			||||||
 | 
						destroy_wl_buffer(buffer);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool test_buffer(struct wlr_wl_backend *wl,
 | 
					static bool test_buffer(struct wlr_wl_backend *wl,
 | 
				
			||||||
		struct wlr_buffer *wlr_buffer) {
 | 
							struct wlr_buffer *wlr_buffer) {
 | 
				
			||||||
	struct wlr_dmabuf_attributes attribs;
 | 
						struct wlr_dmabuf_attributes attribs;
 | 
				
			||||||
| 
						 | 
					@ -207,12 +216,33 @@ static struct wlr_wl_buffer *create_wl_buffer(struct wlr_wl_backend *wl,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	buffer->wl_buffer = wl_buffer;
 | 
						buffer->wl_buffer = wl_buffer;
 | 
				
			||||||
	buffer->buffer = wlr_buffer_lock(wlr_buffer);
 | 
						buffer->buffer = wlr_buffer_lock(wlr_buffer);
 | 
				
			||||||
 | 
						wl_list_insert(&wl->buffers, &buffer->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_buffer_add_listener(wl_buffer, &buffer_listener, buffer);
 | 
						wl_buffer_add_listener(wl_buffer, &buffer_listener, buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer->buffer_destroy.notify = buffer_handle_buffer_destroy;
 | 
				
			||||||
 | 
						wl_signal_add(&wlr_buffer->events.destroy, &buffer->buffer_destroy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return buffer;
 | 
						return buffer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct wlr_wl_buffer *get_or_create_wl_buffer(struct wlr_wl_backend *wl,
 | 
				
			||||||
 | 
							struct wlr_buffer *wlr_buffer) {
 | 
				
			||||||
 | 
						struct wlr_wl_buffer *buffer;
 | 
				
			||||||
 | 
						wl_list_for_each(buffer, &wl->buffers, link) {
 | 
				
			||||||
 | 
							// We can only re-use a wlr_wl_buffer if the parent compositor has
 | 
				
			||||||
 | 
							// released it, because wl_buffer.release is per-wl_buffer, not per
 | 
				
			||||||
 | 
							// wl_surface.commit.
 | 
				
			||||||
 | 
							if (buffer->buffer == wlr_buffer && buffer->released) {
 | 
				
			||||||
 | 
								buffer->released = false;
 | 
				
			||||||
 | 
								wlr_buffer_lock(buffer->buffer);
 | 
				
			||||||
 | 
								return buffer;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return create_wl_buffer(wl, wlr_buffer);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool output_test(struct wlr_output *wlr_output) {
 | 
					static bool output_test(struct wlr_output *wlr_output) {
 | 
				
			||||||
	struct wlr_wl_output *output =
 | 
						struct wlr_wl_output *output =
 | 
				
			||||||
		get_wl_output_from_output(wlr_output);
 | 
							get_wl_output_from_output(wlr_output);
 | 
				
			||||||
| 
						 | 
					@ -287,7 +317,7 @@ static bool output_commit(struct wlr_output *wlr_output) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		struct wlr_wl_buffer *buffer =
 | 
							struct wlr_wl_buffer *buffer =
 | 
				
			||||||
			create_wl_buffer(output->backend, wlr_buffer);
 | 
								get_or_create_wl_buffer(output->backend, wlr_buffer);
 | 
				
			||||||
		if (buffer == NULL) {
 | 
							if (buffer == NULL) {
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,9 +25,11 @@ struct wlr_wl_backend {
 | 
				
			||||||
	struct wlr_renderer *renderer;
 | 
						struct wlr_renderer *renderer;
 | 
				
			||||||
	struct wlr_drm_format *format;
 | 
						struct wlr_drm_format *format;
 | 
				
			||||||
	struct wlr_allocator *allocator;
 | 
						struct wlr_allocator *allocator;
 | 
				
			||||||
 | 
						struct wl_list buffers; // wlr_wl_buffer.link
 | 
				
			||||||
	size_t requested_outputs;
 | 
						size_t requested_outputs;
 | 
				
			||||||
	size_t last_output_num;
 | 
						size_t last_output_num;
 | 
				
			||||||
	struct wl_listener local_display_destroy;
 | 
						struct wl_listener local_display_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* remote state */
 | 
						/* remote state */
 | 
				
			||||||
	struct wl_display *remote_display;
 | 
						struct wl_display *remote_display;
 | 
				
			||||||
	struct wl_event_source *remote_display_src;
 | 
						struct wl_event_source *remote_display_src;
 | 
				
			||||||
| 
						 | 
					@ -47,6 +49,9 @@ struct wlr_wl_backend {
 | 
				
			||||||
struct wlr_wl_buffer {
 | 
					struct wlr_wl_buffer {
 | 
				
			||||||
	struct wlr_buffer *buffer;
 | 
						struct wlr_buffer *buffer;
 | 
				
			||||||
	struct wl_buffer *wl_buffer;
 | 
						struct wl_buffer *wl_buffer;
 | 
				
			||||||
 | 
						bool released;
 | 
				
			||||||
 | 
						struct wl_list link; // wlr_wl_backend.buffers
 | 
				
			||||||
 | 
						struct wl_listener buffer_destroy;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_wl_presentation_feedback {
 | 
					struct wlr_wl_presentation_feedback {
 | 
				
			||||||
| 
						 | 
					@ -130,6 +135,7 @@ struct wlr_wl_input_device *create_wl_input_device(
 | 
				
			||||||
	struct wlr_wl_seat *seat, enum wlr_input_device_type type);
 | 
						struct wlr_wl_seat *seat, enum wlr_input_device_type type);
 | 
				
			||||||
bool create_wl_seat(struct wl_seat *wl_seat, struct wlr_wl_backend *wl);
 | 
					bool create_wl_seat(struct wl_seat *wl_seat, struct wlr_wl_backend *wl);
 | 
				
			||||||
void destroy_wl_seats(struct wlr_wl_backend *wl);
 | 
					void destroy_wl_seats(struct wlr_wl_backend *wl);
 | 
				
			||||||
 | 
					void destroy_wl_buffer(struct wlr_wl_buffer *buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const struct wl_seat_listener seat_listener;
 | 
					extern const struct wl_seat_listener seat_listener;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue