mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Introduce wlr_client_buffer
Split out the client/resource handling out of wlr_buffer by introducing
wlr_client_buffer. Make wlr_buffer an interface so that compositors can
create their own wlr_buffers (e.g. backed by GBM, like glider [1]).
[1]: c66847dd1c/include/gbm_allocator.h (L7)
			
			
This commit is contained in:
		
							parent
							
								
									8d2e8d8a06
								
							
						
					
					
						commit
						8afc1ed68c
					
				
					 4 changed files with 154 additions and 85 deletions
				
			
		| 
						 | 
					@ -13,14 +13,52 @@
 | 
				
			||||||
#include <wayland-server-core.h>
 | 
					#include <wayland-server-core.h>
 | 
				
			||||||
#include <wlr/render/dmabuf.h>
 | 
					#include <wlr/render/dmabuf.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_buffer_impl {
 | 
				
			||||||
 | 
						void (*destroy)(struct wlr_buffer *buffer);
 | 
				
			||||||
 | 
						bool (*get_dmabuf)(struct wlr_buffer *buffer,
 | 
				
			||||||
 | 
							struct wlr_dmabuf_attributes *attribs);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_buffer {
 | 
				
			||||||
 | 
						const struct wlr_buffer_impl *impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size_t n_refs;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_buffer_init(struct wlr_buffer *buffer,
 | 
				
			||||||
 | 
						const struct wlr_buffer_impl *impl);
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Reference the buffer.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct wlr_buffer *wlr_buffer_ref(struct wlr_buffer *buffer);
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Unreference the buffer. After this call, `buffer` may not be accessed
 | 
				
			||||||
 | 
					 * anymore.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void wlr_buffer_unref(struct wlr_buffer *buffer);
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Reads the DMA-BUF attributes of the buffer. If this buffer isn't a DMA-BUF,
 | 
				
			||||||
 | 
					 * returns false.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool wlr_buffer_get_dmabuf(struct wlr_buffer *buffer,
 | 
				
			||||||
 | 
						struct wlr_dmabuf_attributes *attribs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A client buffer.
 | 
					 * A client buffer.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct wlr_buffer {
 | 
					struct wlr_client_buffer {
 | 
				
			||||||
 | 
						struct wlr_buffer base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * The buffer resource, if any. Will be NULL if the client destroys it.
 | 
						 * The buffer resource, if any. Will be NULL if the client destroys it.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	struct wl_resource *resource;
 | 
						struct wl_resource *resource;
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Whether a release event has been sent to the resource.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						bool resource_released;
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * The buffer's texture, if any. A buffer will not have a texture if the
 | 
						 * The buffer's texture, if any. A buffer will not have a texture if the
 | 
				
			||||||
	 * client destroys the buffer before it has been released.
 | 
						 * client destroys the buffer before it has been released.
 | 
				
			||||||
| 
						 | 
					@ -41,23 +79,13 @@ bool wlr_resource_is_buffer(struct wl_resource *resource);
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Get the size of a wl_buffer resource.
 | 
					 * Get the size of a wl_buffer resource.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool wlr_buffer_get_resource_size(struct wl_resource *resource,
 | 
					bool wlr_resource_get_buffer_size(struct wl_resource *resource,
 | 
				
			||||||
	struct wlr_renderer *renderer, int *width, int *height);
 | 
						struct wlr_renderer *renderer, int *width, int *height);
 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Upload a buffer to the GPU and reference it.
 | 
					 * Upload a buffer to the GPU and reference it.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct wlr_buffer *wlr_buffer_create(struct wlr_renderer *renderer,
 | 
					struct wlr_client_buffer *wlr_client_buffer_create(
 | 
				
			||||||
	struct wl_resource *resource);
 | 
						struct wlr_renderer *renderer, struct wl_resource *resource);
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Reference the buffer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct wlr_buffer *wlr_buffer_ref(struct wlr_buffer *buffer);
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Unreference the buffer. After this call, `buffer` may not be accessed
 | 
					 | 
				
			||||||
 * anymore.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void wlr_buffer_unref(struct wlr_buffer *buffer);
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Try to update the buffer's content. On success, returns the updated buffer
 | 
					 * Try to update the buffer's content. On success, returns the updated buffer
 | 
				
			||||||
 * and destroys the provided `buffer`. On error, `buffer` is intact and NULL is
 | 
					 * and destroys the provided `buffer`. On error, `buffer` is intact and NULL is
 | 
				
			||||||
| 
						 | 
					@ -66,13 +94,8 @@ void wlr_buffer_unref(struct wlr_buffer *buffer);
 | 
				
			||||||
 * Fails if there's more than one reference to the buffer or if the texture
 | 
					 * Fails if there's more than one reference to the buffer or if the texture
 | 
				
			||||||
 * isn't mutable.
 | 
					 * isn't mutable.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct wlr_buffer *wlr_buffer_apply_damage(struct wlr_buffer *buffer,
 | 
					struct wlr_client_buffer *wlr_client_buffer_apply_damage(
 | 
				
			||||||
	struct wl_resource *resource, pixman_region32_t *damage);
 | 
						struct wlr_client_buffer *buffer, struct wl_resource *resource,
 | 
				
			||||||
/**
 | 
						pixman_region32_t *damage);
 | 
				
			||||||
 * Reads the DMA-BUF attributes of the buffer. If this buffer isn't a DMA-BUF,
 | 
					 | 
				
			||||||
 * returns false.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
bool wlr_buffer_get_dmabuf(struct wlr_buffer *buffer,
 | 
					 | 
				
			||||||
		struct wlr_dmabuf_attributes *attribs);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,7 +59,7 @@ struct wlr_surface {
 | 
				
			||||||
	 * have a buffer if it has never committed one, has committed a null buffer,
 | 
						 * have a buffer if it has never committed one, has committed a null buffer,
 | 
				
			||||||
	 * or something went wrong with uploading the buffer.
 | 
						 * or something went wrong with uploading the buffer.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	struct wlr_buffer *buffer;
 | 
						struct wlr_client_buffer *buffer;
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * The buffer position, in surface-local units.
 | 
						 * The buffer position, in surface-local units.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,11 +5,46 @@
 | 
				
			||||||
#include <wlr/types/wlr_linux_dmabuf_v1.h>
 | 
					#include <wlr/types/wlr_linux_dmabuf_v1.h>
 | 
				
			||||||
#include <wlr/util/log.h>
 | 
					#include <wlr/util/log.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_buffer_init(struct wlr_buffer *buffer,
 | 
				
			||||||
 | 
							const struct wlr_buffer_impl *impl) {
 | 
				
			||||||
 | 
						assert(impl->destroy);
 | 
				
			||||||
 | 
						buffer->impl = impl;
 | 
				
			||||||
 | 
						buffer->n_refs = 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_buffer *wlr_buffer_ref(struct wlr_buffer *buffer) {
 | 
				
			||||||
 | 
						buffer->n_refs++;
 | 
				
			||||||
 | 
						return buffer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_buffer_unref(struct wlr_buffer *buffer) {
 | 
				
			||||||
 | 
						if (buffer == NULL) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(buffer->n_refs > 0);
 | 
				
			||||||
 | 
						buffer->n_refs--;
 | 
				
			||||||
 | 
						if (buffer->n_refs > 0) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer->impl->destroy(buffer);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool wlr_buffer_get_dmabuf(struct wlr_buffer *buffer,
 | 
				
			||||||
 | 
							struct wlr_dmabuf_attributes *attribs) {
 | 
				
			||||||
 | 
						if (!buffer->impl->get_dmabuf) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return buffer->impl->get_dmabuf(buffer, attribs);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool wlr_resource_is_buffer(struct wl_resource *resource) {
 | 
					bool wlr_resource_is_buffer(struct wl_resource *resource) {
 | 
				
			||||||
	return strcmp(wl_resource_get_class(resource), wl_buffer_interface.name) == 0;
 | 
						return strcmp(wl_resource_get_class(resource), wl_buffer_interface.name) == 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool wlr_buffer_get_resource_size(struct wl_resource *resource,
 | 
					bool wlr_resource_get_buffer_size(struct wl_resource *resource,
 | 
				
			||||||
		struct wlr_renderer *renderer, int *width, int *height) {
 | 
							struct wlr_renderer *renderer, int *width, int *height) {
 | 
				
			||||||
	assert(wlr_resource_is_buffer(resource));
 | 
						assert(wlr_resource_is_buffer(resource));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,10 +69,54 @@ bool wlr_buffer_get_resource_size(struct wl_resource *resource,
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct wlr_buffer_impl client_buffer_impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void buffer_resource_handle_destroy(struct wl_listener *listener,
 | 
					static struct wlr_client_buffer *client_buffer_from_buffer(
 | 
				
			||||||
 | 
							struct wlr_buffer *buffer) {
 | 
				
			||||||
 | 
						assert(buffer->impl == &client_buffer_impl);
 | 
				
			||||||
 | 
						return (struct wlr_client_buffer *) buffer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void client_buffer_destroy(struct wlr_buffer *_buffer) {
 | 
				
			||||||
 | 
						struct wlr_client_buffer *buffer = client_buffer_from_buffer(_buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!buffer->resource_released && buffer->resource != NULL) {
 | 
				
			||||||
 | 
							wl_buffer_send_release(buffer->resource);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_list_remove(&buffer->resource_destroy.link);
 | 
				
			||||||
 | 
						wlr_texture_destroy(buffer->texture);
 | 
				
			||||||
 | 
						free(buffer);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool client_buffer_get_dmabuf(struct wlr_buffer *_buffer,
 | 
				
			||||||
 | 
							struct wlr_dmabuf_attributes *attribs) {
 | 
				
			||||||
 | 
						struct wlr_client_buffer *buffer = client_buffer_from_buffer(_buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (buffer->resource == NULL) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_resource *buffer_resource = buffer->resource;
 | 
				
			||||||
 | 
						if (!wlr_dmabuf_v1_resource_is_buffer(buffer_resource)) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_dmabuf_v1_buffer *dmabuf_buffer =
 | 
				
			||||||
 | 
							wlr_dmabuf_v1_buffer_from_buffer_resource(buffer_resource);
 | 
				
			||||||
 | 
						memcpy(attribs, &dmabuf_buffer->attributes,
 | 
				
			||||||
 | 
							sizeof(struct wlr_dmabuf_attributes));
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct wlr_buffer_impl client_buffer_impl = {
 | 
				
			||||||
 | 
						.destroy = client_buffer_destroy,
 | 
				
			||||||
 | 
						.get_dmabuf = client_buffer_get_dmabuf,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void client_buffer_resource_handle_destroy(struct wl_listener *listener,
 | 
				
			||||||
		void *data) {
 | 
							void *data) {
 | 
				
			||||||
	struct wlr_buffer *buffer =
 | 
						struct wlr_client_buffer *buffer =
 | 
				
			||||||
		wl_container_of(listener, buffer, resource_destroy);
 | 
							wl_container_of(listener, buffer, resource_destroy);
 | 
				
			||||||
	wl_list_remove(&buffer->resource_destroy.link);
 | 
						wl_list_remove(&buffer->resource_destroy.link);
 | 
				
			||||||
	wl_list_init(&buffer->resource_destroy.link);
 | 
						wl_list_init(&buffer->resource_destroy.link);
 | 
				
			||||||
| 
						 | 
					@ -51,8 +130,8 @@ static void buffer_resource_handle_destroy(struct wl_listener *listener,
 | 
				
			||||||
	// which case we'll read garbage. We decide to accept this risk.
 | 
						// which case we'll read garbage. We decide to accept this risk.
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_buffer *wlr_buffer_create(struct wlr_renderer *renderer,
 | 
					struct wlr_client_buffer *wlr_client_buffer_create(
 | 
				
			||||||
		struct wl_resource *resource) {
 | 
							struct wlr_renderer *renderer, struct wl_resource *resource) {
 | 
				
			||||||
	assert(wlr_resource_is_buffer(resource));
 | 
						assert(wlr_resource_is_buffer(resource));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_texture *texture = NULL;
 | 
						struct wlr_texture *texture = NULL;
 | 
				
			||||||
| 
						 | 
					@ -100,50 +179,27 @@ struct wlr_buffer *wlr_buffer_create(struct wlr_renderer *renderer,
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_buffer *buffer = calloc(1, sizeof(struct wlr_buffer));
 | 
						struct wlr_client_buffer *buffer =
 | 
				
			||||||
 | 
							calloc(1, sizeof(struct wlr_client_buffer));
 | 
				
			||||||
	if (buffer == NULL) {
 | 
						if (buffer == NULL) {
 | 
				
			||||||
		wlr_texture_destroy(texture);
 | 
							wlr_texture_destroy(texture);
 | 
				
			||||||
		wl_resource_post_no_memory(resource);
 | 
							wl_resource_post_no_memory(resource);
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						wlr_buffer_init(&buffer->base, &client_buffer_impl);
 | 
				
			||||||
	buffer->resource = resource;
 | 
						buffer->resource = resource;
 | 
				
			||||||
	buffer->texture = texture;
 | 
						buffer->texture = texture;
 | 
				
			||||||
	buffer->released = released;
 | 
						buffer->resource_released = released;
 | 
				
			||||||
	buffer->n_refs = 1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_resource_add_destroy_listener(resource, &buffer->resource_destroy);
 | 
						wl_resource_add_destroy_listener(resource, &buffer->resource_destroy);
 | 
				
			||||||
	buffer->resource_destroy.notify = buffer_resource_handle_destroy;
 | 
						buffer->resource_destroy.notify = client_buffer_resource_handle_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return buffer;
 | 
						return buffer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_buffer *wlr_buffer_ref(struct wlr_buffer *buffer) {
 | 
					struct wlr_client_buffer *wlr_client_buffer_apply_damage(
 | 
				
			||||||
	buffer->n_refs++;
 | 
							struct wlr_client_buffer *buffer, struct wl_resource *resource,
 | 
				
			||||||
	return buffer;
 | 
							pixman_region32_t *damage) {
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void wlr_buffer_unref(struct wlr_buffer *buffer) {
 | 
					 | 
				
			||||||
	if (buffer == NULL) {
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	assert(buffer->n_refs > 0);
 | 
					 | 
				
			||||||
	buffer->n_refs--;
 | 
					 | 
				
			||||||
	if (buffer->n_refs > 0) {
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!buffer->released && buffer->resource != NULL) {
 | 
					 | 
				
			||||||
		wl_buffer_send_release(buffer->resource);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wl_list_remove(&buffer->resource_destroy.link);
 | 
					 | 
				
			||||||
	wlr_texture_destroy(buffer->texture);
 | 
					 | 
				
			||||||
	free(buffer);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct wlr_buffer *wlr_buffer_apply_damage(struct wlr_buffer *buffer,
 | 
					 | 
				
			||||||
		struct wl_resource *resource, pixman_region32_t *damage) {
 | 
					 | 
				
			||||||
	assert(wlr_resource_is_buffer(resource));
 | 
						assert(wlr_resource_is_buffer(resource));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (buffer->n_refs > 1) {
 | 
						if (buffer->n_refs > 1) {
 | 
				
			||||||
| 
						 | 
					@ -199,27 +255,9 @@ struct wlr_buffer *wlr_buffer_apply_damage(struct wlr_buffer *buffer,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_remove(&buffer->resource_destroy.link);
 | 
						wl_list_remove(&buffer->resource_destroy.link);
 | 
				
			||||||
	wl_resource_add_destroy_listener(resource, &buffer->resource_destroy);
 | 
						wl_resource_add_destroy_listener(resource, &buffer->resource_destroy);
 | 
				
			||||||
	buffer->resource_destroy.notify = buffer_resource_handle_destroy;
 | 
						buffer->resource_destroy.notify = client_buffer_resource_handle_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buffer->resource = resource;
 | 
						buffer->resource = resource;
 | 
				
			||||||
	buffer->released = true;
 | 
						buffer->released = true;
 | 
				
			||||||
	return buffer;
 | 
						return buffer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
bool wlr_buffer_get_dmabuf(struct wlr_buffer *buffer,
 | 
					 | 
				
			||||||
		struct wlr_dmabuf_attributes *attribs) {
 | 
					 | 
				
			||||||
	if (buffer->resource == NULL) {
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct wl_resource *buffer_resource = buffer->resource;
 | 
					 | 
				
			||||||
	if (!wlr_dmabuf_v1_resource_is_buffer(buffer_resource)) {
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct wlr_dmabuf_v1_buffer *dmabuf_buffer =
 | 
					 | 
				
			||||||
		wlr_dmabuf_v1_buffer_from_buffer_resource(buffer_resource);
 | 
					 | 
				
			||||||
	memcpy(attribs, &dmabuf_buffer->attributes,
 | 
					 | 
				
			||||||
		sizeof(struct wlr_dmabuf_attributes));
 | 
					 | 
				
			||||||
	return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,7 +142,7 @@ static void surface_state_finalize(struct wlr_surface *surface,
 | 
				
			||||||
		struct wlr_surface_state *state) {
 | 
							struct wlr_surface_state *state) {
 | 
				
			||||||
	if ((state->committed & WLR_SURFACE_STATE_BUFFER)) {
 | 
						if ((state->committed & WLR_SURFACE_STATE_BUFFER)) {
 | 
				
			||||||
		if (state->buffer_resource != NULL) {
 | 
							if (state->buffer_resource != NULL) {
 | 
				
			||||||
			wlr_buffer_get_resource_size(state->buffer_resource,
 | 
								wlr_resource_get_buffer_size(state->buffer_resource,
 | 
				
			||||||
				surface->renderer, &state->buffer_width, &state->buffer_height);
 | 
									surface->renderer, &state->buffer_width, &state->buffer_height);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			state->buffer_width = state->buffer_height = 0;
 | 
								state->buffer_width = state->buffer_height = 0;
 | 
				
			||||||
| 
						 | 
					@ -282,27 +282,33 @@ static void surface_apply_damage(struct wlr_surface *surface) {
 | 
				
			||||||
	struct wl_resource *resource = surface->current.buffer_resource;
 | 
						struct wl_resource *resource = surface->current.buffer_resource;
 | 
				
			||||||
	if (resource == NULL) {
 | 
						if (resource == NULL) {
 | 
				
			||||||
		// NULL commit
 | 
							// NULL commit
 | 
				
			||||||
		wlr_buffer_unref(surface->buffer);
 | 
							if (surface->buffer != NULL) {
 | 
				
			||||||
 | 
								wlr_buffer_unref(&surface->buffer->base);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		surface->buffer = NULL;
 | 
							surface->buffer = NULL;
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (surface->buffer != NULL && surface->buffer->released) {
 | 
						if (surface->buffer != NULL && surface->buffer->released) {
 | 
				
			||||||
		struct wlr_buffer *updated_buffer = wlr_buffer_apply_damage(
 | 
							struct wlr_client_buffer *updated_buffer =
 | 
				
			||||||
			surface->buffer, resource, &surface->buffer_damage);
 | 
								wlr_client_buffer_apply_damage(surface->buffer, resource,
 | 
				
			||||||
 | 
								&surface->buffer_damage);
 | 
				
			||||||
		if (updated_buffer != NULL) {
 | 
							if (updated_buffer != NULL) {
 | 
				
			||||||
			surface->buffer = updated_buffer;
 | 
								surface->buffer = updated_buffer;
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_buffer *buffer = wlr_buffer_create(surface->renderer, resource);
 | 
						struct wlr_client_buffer *buffer =
 | 
				
			||||||
 | 
							wlr_client_buffer_create(surface->renderer, resource);
 | 
				
			||||||
	if (buffer == NULL) {
 | 
						if (buffer == NULL) {
 | 
				
			||||||
		wlr_log(WLR_ERROR, "Failed to upload buffer");
 | 
							wlr_log(WLR_ERROR, "Failed to upload buffer");
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_buffer_unref(surface->buffer);
 | 
						if (surface->buffer != NULL) {
 | 
				
			||||||
 | 
							wlr_buffer_unref(&surface->buffer->base);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	surface->buffer = buffer;
 | 
						surface->buffer = buffer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -573,7 +579,9 @@ static void surface_handle_resource_destroy(struct wl_resource *resource) {
 | 
				
			||||||
	pixman_region32_fini(&surface->buffer_damage);
 | 
						pixman_region32_fini(&surface->buffer_damage);
 | 
				
			||||||
	pixman_region32_fini(&surface->opaque_region);
 | 
						pixman_region32_fini(&surface->opaque_region);
 | 
				
			||||||
	pixman_region32_fini(&surface->input_region);
 | 
						pixman_region32_fini(&surface->input_region);
 | 
				
			||||||
	wlr_buffer_unref(surface->buffer);
 | 
						if (surface->buffer != NULL) {
 | 
				
			||||||
 | 
							wlr_buffer_unref(&surface->buffer->base);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	free(surface);
 | 
						free(surface);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue