Flesh out ds_buffer 33/278133/1
authorSeunghun Lee <shiin.lee@samsung.com>
Thu, 24 Feb 2022 08:36:08 +0000 (17:36 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Mon, 18 Jul 2022 05:58:06 +0000 (14:58 +0900)
Change-Id: I3c8bb8706b3a1bfdb05eeb31eb9715fd96933ed5

include/libds/buffer.h
src/libds/buffer.c

index c91cba7..b3d38fa 100644 (file)
@@ -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
index 70de23f..167d3a7 100644 (file)
@@ -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;
+}