Add ds_tbm_server 59/278159/1
authorSeunghun Lee <shiin.lee@samsung.com>
Mon, 28 Mar 2022 11:03:20 +0000 (20:03 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Mon, 18 Jul 2022 05:58:21 +0000 (14:58 +0900)
ds_tbm_server initializes wayland_tbm to allow wl_client to use
tbm_surface as a wl_buffer.

Change-Id: I5fcf1f37bd9f410f7d400ac3a918c159dbb07fbc

include/libds-tizen/tbm_server.h [new file with mode: 0644]
src/examples/meson.build
src/examples/tbm-server-helper.h [deleted file]
src/examples/tinyds-tdm.c
src/libds-tizen/meson.build
src/libds-tizen/pixel_format.c [new file with mode: 0644]
src/libds-tizen/pixel_format.h [new file with mode: 0644]
src/libds-tizen/tbm_server.c [moved from src/examples/tbm-server-helper.c with 66% similarity]
src/libds-tizen/tbm_server.h [new file with mode: 0644]

diff --git a/include/libds-tizen/tbm_server.h b/include/libds-tizen/tbm_server.h
new file mode 100644 (file)
index 0000000..c48977e
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef LIBDS_TIZEN_TBM_SERVER_H
+#define LIBDS_TIZEN_TBM_SERVER_H
+
+#include <wayland-server.h>
+#include <tbm_surface.h>
+
+struct ds_tbm_server;
+
+struct ds_tbm_client_buffer;
+
+struct ds_tbm_server *
+ds_tbm_server_create(struct wl_display *display);
+
+void
+ds_tbm_server_add_destroy_listener(struct ds_tbm_server *tbm,
+        struct wl_listener *listener);
+
+struct ds_tbm_client_buffer *
+ds_tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer);
+
+tbm_surface_h
+ds_tbm_client_buffer_get_tbm_surface(struct ds_tbm_client_buffer *buffer);
+
+#endif
index c60b610..ddb0792 100644 (file)
@@ -35,19 +35,15 @@ if get_option('tizen')
 
   tinyds_tdm_files = [
     'tinyds-tdm.c',
-    'tinyds-tdm-renderer.c',
-    'tbm-server-helper.c',
     'pixman-helper.c',
     'pixman-tbm-helper.c',
+    'tinyds-tdm-renderer.c',
   ]
   executable('tinyds-tdm',
     tinyds_tdm_files,
     dependencies: [
       common_deps,
       dependency('pixman-1', required: true),
-      dependency('libdrm', required: true),
-      dependency('libtbm', required: true),
-      dependency('wayland-tbm-server', required: true),
       dependency('threads', required: true),
     ],
     install_dir: libds_bindir,
diff --git a/src/examples/tbm-server-helper.h b/src/examples/tbm-server-helper.h
deleted file mode 100644 (file)
index 609f370..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef EXAMPLES_TBM_SERVER_H
-#define EXAMPLES_TBM_SERVER_H 
-
-#include <stdbool.h>
-#include <wayland-server.h>
-#include <wayland-tbm-server.h>
-#include <tbm_surface.h>
-#include <libds/interfaces/buffer.h>
-
-struct tbm_server
-{
-    struct wayland_tbm_server *wl_tbm;
-
-    struct wl_listener display_destroy;
-};
-
-struct tbm_client_buffer
-{
-    struct ds_buffer base;
-
-    tbm_surface_h surface;
-    struct wl_resource *resource;
-
-    struct wl_listener buffer_release;
-    struct wl_listener resource_destroy;
-
-    uint32_t format;
-    size_t stride;
-};
-
-bool
-tbm_server_init_display(struct tbm_server *tbm_server,
-        struct wl_display *display);
-
-struct tbm_client_buffer *
-tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer);
-
-tbm_surface_h
-tbm_client_buffer_get_tbm_surface(struct tbm_client_buffer *buffer);
-
-#endif
index 6ec1156..c14cb9e 100644 (file)
@@ -15,6 +15,7 @@
 #include <libds/xdg_shell.h>
 #include <libds-tizen/allocator/tbm.h>
 #include <libds-tizen/backend/tdm.h>
+#include <libds-tizen/tbm_server.h>
 
 #define USE_TDM_BUFFER_QUEUE
 
@@ -25,7 +26,6 @@
 #include <libds/swapchain.h>
 #endif
 
-#include "tbm-server-helper.h"
 #include "pixman-helper.h"
 
 #define TINYDS_UNUSED   __attribute__((unused))
@@ -55,7 +55,7 @@ struct tinyds_output
 
 struct tinyds_server
 {
-    struct tbm_server tbm_server;
+    struct ds_tbm_server *tbm_server;
 
     struct wl_display *display;
 
@@ -127,9 +127,6 @@ main(void)
     res = init_server(server, display);
     assert(res);
 
-    res = tbm_server_init_display(&server->tbm_server, display);
-    assert(res);
-
     socket = wl_display_add_socket_auto(display);
     assert(socket);
 
@@ -314,6 +311,12 @@ init_server(struct tinyds_server *server, struct wl_display *display)
         return false;
     }
 
+    server->tbm_server = ds_tbm_server_create(display);
+    if (!server->tbm_server) {
+        ds_backend_destroy(server->backend);
+        return false;
+    }
+
     server->xdg_shell = ds_xdg_shell_create(display);
     if (!server->xdg_shell) {
         ds_backend_destroy(server->backend);
@@ -426,7 +429,7 @@ output_draw_with_renderer(struct tinyds_output *output)
 
     wl_list_for_each(view, &output->server->views, link) {
         struct ds_buffer *ds_buffer;
-        struct tbm_client_buffer *buffer;
+        struct ds_tbm_client_buffer *tbm_buffer;
         tbm_surface_h surface;
 
         if (!view->mapped)
@@ -434,12 +437,12 @@ output_draw_with_renderer(struct tinyds_output *output)
 
         ds_buffer = ds_surface_get_buffer(
                 ds_xdg_surface_get_surface(view->xdg_surface));
-        assert(buffer);
+        assert(ds_buffer);
 
-        buffer = tbm_client_buffer_from_buffer(ds_buffer);
-        assert(buffer);
+        tbm_buffer = ds_tbm_client_buffer_from_buffer(ds_buffer);
+        assert(tbm_buffer);
 
-        surface = tbm_client_buffer_get_tbm_surface(buffer);
+        surface = ds_tbm_client_buffer_get_tbm_surface(tbm_buffer);
 
         renderer_add_texture(&output->renderer, surface, view->x, view->y);
 
index e9ca734..4f76b68 100644 (file)
@@ -1,7 +1,13 @@
-libds_tizen_files = []
+libds_tizen_files = [
+  'pixel_format.c',
+  'tbm_server.c',
+]
 
 libds_tizen_deps = [
   dep_libds,
+  dependency('libdrm', required: true),
+  dependency('libtbm', required: true),
+  dependency('wayland-tbm-server', required: true),
 ]
 
 subdir('allocator')
diff --git a/src/libds-tizen/pixel_format.c b/src/libds-tizen/pixel_format.c
new file mode 100644 (file)
index 0000000..021652e
--- /dev/null
@@ -0,0 +1,61 @@
+#include <inttypes.h>
+#include <drm_fourcc.h>
+#include <tbm_type.h>
+
+#include "libds/log.h"
+#include "pixel_format.h"
+
+#ifdef ARRAY_LENGTH
+#undef ARRAY_LENGTH
+#endif
+
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
+
+struct ds_tbm_format
+{
+    uint32_t drm_format;
+    uint32_t tbm_format;
+};
+
+static const struct ds_tbm_format formats[] =
+{
+    {
+        .drm_format = DRM_FORMAT_ARGB8888,
+        .tbm_format = TBM_FORMAT_ARGB8888,
+    },
+    {
+        .drm_format = DRM_FORMAT_XRGB8888,
+        .tbm_format = TBM_FORMAT_XRGB8888,
+    },
+    /* TODO more format */
+};
+
+uint32_t
+convert_drm_format_to_tbm(uint32_t fmt)
+{
+    size_t i;
+
+    for (i = 0; i < ARRAY_LENGTH(formats); i++) {
+        if (formats[i].drm_format == fmt)
+            return formats[i].tbm_format;
+    }
+
+    ds_err("DRM format 0x%"PRIX32" has no TBM equivalent", fmt);
+
+    return 0;
+}
+
+uint32_t
+convert_tbm_format_to_drm(uint32_t fmt)
+{
+    size_t i;
+
+    for (i = 0; i < ARRAY_LENGTH(formats); i++) {
+        if (formats[i].tbm_format == fmt)
+            return formats[i].drm_format;
+    }
+
+    ds_err("TBM format 0x%"PRIX32" has no DRM equivalent", fmt);
+
+    return 0;
+}
diff --git a/src/libds-tizen/pixel_format.h b/src/libds-tizen/pixel_format.h
new file mode 100644 (file)
index 0000000..a63d096
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef DS_TIZEN_PIXEL_FORMAT_H
+#define DS_TIZEN_PIXEL_FORMAT_H
+
+#include <stdint.h>
+
+uint32_t convert_drm_format_to_tbm(uint32_t fmt);
+
+uint32_t convert_tbm_format_to_drm(uint32_t fmt);
+
+#endif
similarity index 66%
rename from src/examples/tbm-server-helper.c
rename to src/libds-tizen/tbm_server.c
index 320ee4f..ecb46db 100644 (file)
-#include "tbm-server-helper.h"
-
 #include <assert.h>
 #include <stdbool.h>
 #include <stdlib.h>
-#include <drm_fourcc.h>
+
 #include <tbm_bufmgr.h>
-#include <libds/log.h>
+
+#include "libds/log.h"
+#include "pixel_format.h"
+#include "tbm_server.h"
 
 static const struct ds_buffer_resource_interface tbm_buffer_resource_iface;
 static const struct ds_buffer_interface tbm_client_buffer_iface;
 
 static void tbm_server_handle_display_destroy(struct wl_listener *listener,
         void *data);
-static struct tbm_client_buffer *
-tbm_client_buffer_create(struct wl_resource *resource);
 
-bool
-tbm_server_init_display(struct tbm_server *tbm, struct wl_display *display)
+WL_EXPORT struct ds_tbm_server *
+ds_tbm_server_create(struct wl_display *display)
 {
+    struct ds_tbm_server *tbm;
     tbm_bufmgr bufmgr;
 
+    tbm = calloc(1, sizeof *tbm);
+    if (!tbm)
+        return NULL;
+
+    wl_signal_init(&tbm->events.destroy);
+
     tbm->wl_tbm = wayland_tbm_server_init(display, NULL, -1, 0);
     if (!tbm->wl_tbm) {
-        return false;
+        goto err_wl_tbm;
     }
 
     bufmgr = wayland_tbm_server_get_bufmgr(tbm->wl_tbm);
     if (!bufmgr) {
-        wayland_tbm_server_deinit(tbm->wl_tbm);
-        return false;
+        goto err_bind;
     }
 
     if (!tbm_bufmgr_bind_native_display(bufmgr, (void *)display)) {
-        wayland_tbm_server_deinit(tbm->wl_tbm);
-        return false;
+        goto err_bind;
     }
 
-    ds_buffer_register_resource_interface(&tbm_buffer_resource_iface);
-
     tbm->display_destroy.notify = tbm_server_handle_display_destroy;
     wl_display_add_destroy_listener(display, &tbm->display_destroy);
 
-    return true;
+    ds_buffer_register_resource_interface(&tbm_buffer_resource_iface);
+
+    return tbm;
+
+err_bind:
+    wayland_tbm_server_deinit(tbm->wl_tbm);
+err_wl_tbm:
+    free(tbm);
+
+    return NULL;
 }
 
-struct tbm_client_buffer *
-tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer)
+WL_EXPORT void
+ds_tbm_server_add_destroy_listener(struct ds_tbm_server *tbm,
+        struct wl_listener *listener)
 {
-    assert(ds_buffer->iface == &tbm_client_buffer_iface);
-    return (struct tbm_client_buffer *)ds_buffer;
+    wl_signal_add(&tbm->events.destroy, listener);
+}
+
+WL_EXPORT struct ds_tbm_client_buffer *
+ds_tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer)
+{
+    if (ds_buffer->iface != &tbm_client_buffer_iface)
+        return NULL;
+    return (struct ds_tbm_client_buffer *)ds_buffer;
 }
 
-tbm_surface_h
-tbm_client_buffer_get_tbm_surface(struct tbm_client_buffer *buffer)
+WL_EXPORT tbm_surface_h
+ds_tbm_client_buffer_get_tbm_surface(struct ds_tbm_client_buffer *buffer)
 {
+    if (buffer->base.iface != &tbm_client_buffer_iface)
+        return NULL;
     return buffer->surface;
 }
 
 static void
 tbm_server_handle_display_destroy(struct wl_listener *listener, void *data)
 {
-    struct tbm_server *tbm;
+    struct ds_tbm_server *tbm;
 
     tbm = wl_container_of(listener, tbm, display_destroy);
+
+    wl_signal_emit(&tbm->events.destroy, tbm);
+
     wayland_tbm_server_deinit(tbm->wl_tbm);
+    free(tbm);
 }
 
-static bool
-tbm_buffer_resource_iface_is_instance(struct wl_resource *resource)
+static void
+tbm_client_buffer_handle_release(struct wl_listener *listener, void *data)
 {
-    return !!wayland_tbm_server_get_surface(NULL, resource);
+    struct ds_tbm_client_buffer *buffer;
+
+    buffer = wl_container_of(listener, buffer, buffer_release);
+    if (buffer->resource)
+        wl_buffer_send_release(buffer->resource);
 }
 
 static void
 tbm_client_buffer_handle_resource_destroy(struct wl_listener *listener,
         void *data)
 {
-    struct tbm_client_buffer *buffer;
+    struct ds_tbm_client_buffer *buffer;
 
     buffer = wl_container_of(listener, buffer, resource_destroy);
 
@@ -88,44 +117,17 @@ tbm_client_buffer_handle_resource_destroy(struct wl_listener *listener,
     ds_buffer_drop(&buffer->base);
 }
 
-static struct tbm_client_buffer *
-tbm_client_buffer_get_or_create(struct wl_resource *resource)
-{
-    struct tbm_client_buffer *buffer;
-    struct wl_listener *resource_destroy_listener;
-
-    resource_destroy_listener = wl_resource_get_destroy_listener(resource,
-            tbm_client_buffer_handle_resource_destroy);;
-    if (resource_destroy_listener) {
-        buffer = wl_container_of(resource_destroy_listener,
-                buffer, resource_destroy);
-        return buffer;
-    }
-
-    return tbm_client_buffer_create(resource);
-}
-
-static struct ds_buffer *
-tbm_buffer_resource_iface_from_resource(struct wl_resource *resource)
+static struct ds_tbm_client_buffer *
+tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer)
 {
-    struct tbm_client_buffer *buffer;
-
-    buffer = tbm_client_buffer_get_or_create(resource);
-    assert(buffer);
-
-    return &buffer->base;
+    assert(ds_buffer->iface == &tbm_client_buffer_iface);
+    return (struct ds_tbm_client_buffer *)ds_buffer;
 }
 
-static const struct ds_buffer_resource_interface tbm_buffer_resource_iface = {
-    .name = "tbm",
-    .is_instance = tbm_buffer_resource_iface_is_instance,
-    .from_resource = tbm_buffer_resource_iface_from_resource,
-};
-
 static void
-tbm_client_buffer_destroy(struct ds_buffer *ds_buffer)
+tbm_client_buffer_iface_destroy(struct ds_buffer *ds_buffer)
 {
-    struct tbm_client_buffer *buffer;
+    struct ds_tbm_client_buffer *buffer;
 
     buffer = tbm_client_buffer_from_buffer(ds_buffer);
 
@@ -137,11 +139,11 @@ tbm_client_buffer_destroy(struct ds_buffer *ds_buffer)
 }
 
 static bool
-tbm_client_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer,
+tbm_client_buffer_iface_begin_data_ptr_access(struct ds_buffer *ds_buffer,
         enum ds_buffer_data_ptr_access_flag flags, void **data,
         uint32_t *format, size_t *stride)
 {
-    struct tbm_client_buffer *buffer;
+    struct ds_tbm_client_buffer *buffer;
     tbm_surface_info_s info;
     tbm_bo_access_option op = TBM_OPTION_NONE;
     int err;
@@ -160,7 +162,7 @@ tbm_client_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer,
         return false;
     }
 
-    *format = DRM_FORMAT_XRGB8888; // FIXME
+    *format = convert_tbm_format_to_drm(buffer->format);
     *stride = info.planes[0].stride;
     *data = info.planes[0].ptr;
 
@@ -168,9 +170,9 @@ tbm_client_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer,
 }
 
 static void
-tbm_client_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer)
+tbm_client_buffer_iface_end_ptr_access(struct ds_buffer *ds_buffer)
 {
-    struct tbm_client_buffer *buffer;
+    struct ds_tbm_client_buffer *buffer;
 
     buffer = tbm_client_buffer_from_buffer(ds_buffer);
 
@@ -178,36 +180,31 @@ tbm_client_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer)
 }
 
 static const struct ds_buffer_interface tbm_client_buffer_iface = {
-    .destroy = tbm_client_buffer_destroy,
-    .begin_data_ptr_access = tbm_client_buffer_begin_data_ptr_access,
-    .end_data_ptr_access = tbm_client_buffer_end_data_ptr_access,
+    .destroy = tbm_client_buffer_iface_destroy,
+    .begin_data_ptr_access = tbm_client_buffer_iface_begin_data_ptr_access,
+    .end_data_ptr_access = tbm_client_buffer_iface_end_ptr_access,
 };
 
-static void
-tbm_client_buffer_handle_release(struct wl_listener *listener, void *data)
-{
-    struct tbm_client_buffer *buffer;
-
-    buffer = wl_container_of(listener, buffer, buffer_release);
-    if (buffer->resource)
-        wl_buffer_send_release(buffer->resource);
-}
-
-static struct tbm_client_buffer *
+static struct ds_tbm_client_buffer *
 tbm_client_buffer_create(struct wl_resource *resource)
 {
-    struct tbm_client_buffer *buffer;
+    struct ds_tbm_client_buffer *buffer;
     tbm_surface_h surface;
     int32_t width, height;
 
     surface = wayland_tbm_server_get_surface(NULL, resource);
-    assert(surface);
+    if (!surface) {
+        ds_err("Could not get tbm_surface from wl_resource@%d",
+                wl_resource_get_id(resource));
+        return NULL;
+    }
 
     width = tbm_surface_get_width(surface);
     height = tbm_surface_get_height(surface);
 
     buffer = calloc(1, sizeof *buffer);
-    assert(buffer);
+    if (!buffer)
+        return NULL;
 
     ds_buffer_init(&buffer->base, &tbm_client_buffer_iface, width, height);
 
@@ -226,3 +223,46 @@ tbm_client_buffer_create(struct wl_resource *resource)
 
     return buffer;
 }
+
+static struct ds_tbm_client_buffer *
+tbm_client_buffer_get_or_create(struct wl_resource *resource)
+{
+    struct ds_tbm_client_buffer *buffer;
+    struct wl_listener *resource_destroy_listener;
+
+    resource_destroy_listener = wl_resource_get_destroy_listener(resource,
+            tbm_client_buffer_handle_resource_destroy);;
+    if (resource_destroy_listener) {
+        buffer = wl_container_of(resource_destroy_listener,
+                buffer, resource_destroy);
+        return buffer;
+    }
+
+    return tbm_client_buffer_create(resource);
+}
+
+static bool
+tbm_buffer_resource_iface_is_instance(struct wl_resource *resource)
+{
+    return !!wayland_tbm_server_get_surface(NULL, resource);
+}
+
+static struct ds_buffer *
+tbm_buffer_resource_iface_from_resource(struct wl_resource *resource)
+{
+    struct ds_tbm_client_buffer *buffer;
+
+    buffer = tbm_client_buffer_get_or_create(resource);
+    if (!buffer) {
+        ds_err("Could not get or create ds_tbm_client_buffer");
+        return NULL;
+    }
+
+    return &buffer->base;
+}
+
+static const struct ds_buffer_resource_interface tbm_buffer_resource_iface = {
+    .name = "tbm",
+    .is_instance = tbm_buffer_resource_iface_is_instance,
+    .from_resource = tbm_buffer_resource_iface_from_resource,
+};
diff --git a/src/libds-tizen/tbm_server.h b/src/libds-tizen/tbm_server.h
new file mode 100644 (file)
index 0000000..be56746
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef DS_TIZEN_TBM_SERVER_H
+#define DS_TIZEN_TBM_SERVER_H
+
+#include <wayland-server.h>
+#include <wayland-tbm-server.h>
+#include <tbm_surface.h>
+#include "libds/interfaces/buffer.h"
+
+struct ds_tbm_server
+{
+    struct wayland_tbm_server *wl_tbm;
+
+    struct wl_listener display_destroy;
+
+    struct {
+        struct wl_signal destroy;
+    } events;
+};
+
+struct ds_tbm_client_buffer
+{
+    struct ds_buffer base;
+
+    tbm_surface_h surface;
+    struct wl_resource *resource;
+
+    struct wl_listener buffer_release;
+    struct wl_listener resource_destroy;
+
+    uint32_t format;
+    size_t stride;
+};
+
+#endif