diff options
| -rw-r--r-- | include/wlr/types/wlr_linux_dmabuf_v1.h | 7 | ||||
| -rw-r--r-- | types/wlr_linux_dmabuf_v1.c | 53 | 
2 files changed, 53 insertions, 7 deletions
| diff --git a/include/wlr/types/wlr_linux_dmabuf_v1.h b/include/wlr/types/wlr_linux_dmabuf_v1.h index 17e897c3..a2db7fea 100644 --- a/include/wlr/types/wlr_linux_dmabuf_v1.h +++ b/include/wlr/types/wlr_linux_dmabuf_v1.h @@ -11,11 +11,16 @@  #include <stdint.h>  #include <wayland-server-core.h> +#include <wlr/types/wlr_buffer.h>  #include <wlr/render/dmabuf.h>  struct wlr_dmabuf_v1_buffer { -	struct wl_resource *resource; +	struct wlr_buffer base; + +	struct wl_resource *resource; // can be NULL if the client destroyed it  	struct wlr_dmabuf_attributes attributes; + +	struct wl_listener release;  };  /** diff --git a/types/wlr_linux_dmabuf_v1.c b/types/wlr_linux_dmabuf_v1.c index c7d4510e..7b08b350 100644 --- a/types/wlr_linux_dmabuf_v1.c +++ b/types/wlr_linux_dmabuf_v1.c @@ -18,13 +18,13 @@ static void buffer_handle_destroy(struct wl_client *client,  	wl_resource_destroy(resource);  } -static const struct wl_buffer_interface buffer_impl = { +static const struct wl_buffer_interface wl_buffer_impl = {  	.destroy = buffer_handle_destroy,  };  bool wlr_dmabuf_v1_resource_is_buffer(struct wl_resource *resource) {  	if (!wl_resource_instance_of(resource, &wl_buffer_interface, -			&buffer_impl)) { +			&wl_buffer_impl)) {  		return false;  	}  	return wl_resource_get_user_data(resource) != NULL; @@ -33,15 +33,50 @@ bool wlr_dmabuf_v1_resource_is_buffer(struct wl_resource *resource) {  struct wlr_dmabuf_v1_buffer *wlr_dmabuf_v1_buffer_from_buffer_resource(  		struct wl_resource *resource) {  	assert(wl_resource_instance_of(resource, &wl_buffer_interface, -		&buffer_impl)); +		&wl_buffer_impl));  	return wl_resource_get_user_data(resource);  } -static void linux_dmabuf_buffer_destroy(struct wlr_dmabuf_v1_buffer *buffer) { +static const struct wlr_buffer_impl buffer_impl; + +static struct wlr_dmabuf_v1_buffer *dmabuf_v1_buffer_from_buffer( +		struct wlr_buffer *buffer) { +	assert(buffer->impl == &buffer_impl); +	return (struct wlr_dmabuf_v1_buffer *)buffer; +} + +static void buffer_destroy(struct wlr_buffer *wlr_buffer) { +	struct wlr_dmabuf_v1_buffer *buffer = +		dmabuf_v1_buffer_from_buffer(wlr_buffer); +	if (buffer->resource != NULL) { +		wl_resource_set_user_data(buffer->resource, NULL); +	}  	wlr_dmabuf_attributes_finish(&buffer->attributes); +	wl_list_remove(&buffer->release.link);  	free(buffer);  } +static bool buffer_get_dmabuf(struct wlr_buffer *wlr_buffer, +		struct wlr_dmabuf_attributes *attribs) { +	struct wlr_dmabuf_v1_buffer *buffer = +		dmabuf_v1_buffer_from_buffer(wlr_buffer); +	memcpy(attribs, &buffer->attributes, sizeof(buffer->attributes)); +	return true; +} + +static const struct wlr_buffer_impl buffer_impl = { +	.destroy = buffer_destroy, +	.get_dmabuf = buffer_get_dmabuf, +}; + +static void buffer_handle_release(struct wl_listener *listener, void *data) { +	struct wlr_dmabuf_v1_buffer *buffer = +		wl_container_of(listener, buffer, release); +	if (buffer->resource != NULL) { +		wl_buffer_send_release(buffer->resource); +	} +} +  static const struct zwp_linux_buffer_params_v1_interface buffer_params_impl;  static struct wlr_linux_buffer_params_v1 *params_from_resource( @@ -110,7 +145,8 @@ static void params_add(struct wl_client *client,  static void buffer_handle_resource_destroy(struct wl_resource *buffer_resource) {  	struct wlr_dmabuf_v1_buffer *buffer =  		wlr_dmabuf_v1_buffer_from_buffer_resource(buffer_resource); -	linux_dmabuf_buffer_destroy(buffer); +	buffer->resource = NULL; +	wlr_buffer_drop(&buffer->base);  }  static bool check_import_dmabuf(struct wlr_linux_dmabuf_v1 *linux_dmabuf, @@ -247,19 +283,24 @@ static void params_create_common(struct wl_resource *params_resource,  		wl_resource_post_no_memory(params_resource);  		goto err_failed;  	} +	wlr_buffer_init(&buffer->base, &buffer_impl, attribs.width, attribs.height);  	struct wl_client *client = wl_resource_get_client(params_resource);  	buffer->resource = wl_resource_create(client, &wl_buffer_interface,  		1, buffer_id);  	if (!buffer->resource) {  		wl_resource_post_no_memory(params_resource); +		free(buffer);  		goto err_failed;  	}  	wl_resource_set_implementation(buffer->resource, -		&buffer_impl, buffer, buffer_handle_resource_destroy); +		&wl_buffer_impl, buffer, buffer_handle_resource_destroy);  	buffer->attributes = attribs; +	buffer->release.notify = buffer_handle_release; +	wl_signal_add(&buffer->base.events.release, &buffer->release); +  	/* send 'created' event when the request is not for an immediate  	 * import, that is buffer_id is zero */  	if (buffer_id == 0) { | 
