From 92e20a74e5459771f50057a8249f96d86e286d5e Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 24 Feb 2022 17:36:08 +0900 Subject: [PATCH] Flesh out ds_buffer Change-Id: I9a5aa9a9c7897e22733645eebe25a6c696a3c9cb --- include/libds/buffer.h | 11 ++++++++++ src/libds/buffer.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/include/libds/buffer.h b/include/libds/buffer.h index c91cba7..b3d38fa 100644 --- a/include/libds/buffer.h +++ b/include/libds/buffer.h @@ -33,6 +33,13 @@ struct ds_shm_attributes off_t offset; }; +struct ds_buffer_resource_interface +{ + const char *name; + bool (*is_instance)(struct wl_resource *resource); + struct ds_buffer *(*from_resource)(struct wl_resource *resource); +}; + struct ds_buffer * ds_buffer_from_resource(struct wl_resource *resource); @@ -67,6 +74,10 @@ ds_buffer_begin_data_ptr_access(struct ds_buffer *buffer, void ds_buffer_end_data_ptr_access(struct ds_buffer *buffer); +void +ds_buffer_register_resource_interface( + const struct ds_buffer_resource_interface *iface); + #ifdef __cplusplus } #endif diff --git a/src/libds/buffer.c b/src/libds/buffer.c index 70de23f..167d3a7 100644 --- a/src/libds/buffer.c +++ b/src/libds/buffer.c @@ -6,8 +6,12 @@ #include "libds/log.h" #include "libds/interfaces/buffer.h" +static struct wl_array buffer_resource_interfaces = {0}; + static void buffer_consider_destroy(struct ds_buffer *buffer); static bool ds_resource_is_buffer(struct wl_resource *resource); +static const struct ds_buffer_resource_interface * +get_buffer_resource_iface(struct wl_resource *resource); WL_EXPORT void ds_buffer_init(struct ds_buffer *buffer, const struct ds_buffer_interface *iface, @@ -25,6 +29,7 @@ WL_EXPORT struct ds_buffer * ds_buffer_from_resource(struct wl_resource *resource) { struct ds_buffer *buffer; + const struct ds_buffer_resource_interface *iface; assert(resource && ds_resource_is_buffer(resource)); @@ -39,8 +44,19 @@ ds_buffer_from_resource(struct wl_resource *resource) buffer = ds_buffer_lock(&shm_client_buffer->base); } else { - // TODO; - buffer = NULL; + iface = get_buffer_resource_iface(resource); + if (!iface) { + ds_err("Unknown buffer type"); + return NULL; + } + + buffer = iface->from_resource(resource); + if (!buffer) { + ds_err("Failed to create %s buffer", iface->name); + return NULL; + } + + buffer = ds_buffer_lock(buffer); } return buffer; @@ -129,6 +145,28 @@ ds_buffer_get_size(struct ds_buffer *buffer, int *out_width, int *out_height) *out_height = buffer->height; } +WL_EXPORT void +ds_buffer_register_resource_interface( + const struct ds_buffer_resource_interface *iface) +{ + const struct ds_buffer_resource_interface **iface_ptr; + + assert(iface); + assert(iface->is_instance); + assert(iface->from_resource); + + wl_array_for_each(iface_ptr, &buffer_resource_interfaces) { + if (*iface_ptr == iface) { + ds_dbg("ds_buffer_resource_interface %s has already " + "been registered", iface->name); + return; + } + } + + iface_ptr = wl_array_add(&buffer_resource_interfaces, sizeof(iface)); + *iface_ptr = iface; +} + static void buffer_consider_destroy(struct ds_buffer *buffer) { @@ -147,3 +185,17 @@ ds_resource_is_buffer(struct wl_resource *resource) return strcmp(wl_resource_get_class(resource), wl_buffer_interface.name) == 0; } + +static const struct ds_buffer_resource_interface * +get_buffer_resource_iface(struct wl_resource *resource) +{ + struct ds_buffer_resource_interface **iface_ptr; + + wl_array_for_each(iface_ptr, &buffer_resource_interfaces) { + if ((*iface_ptr)->is_instance(resource)) { + return *iface_ptr; + } + } + + return NULL; +} -- 2.7.4