--- /dev/null
+#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
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,
+++ /dev/null
-#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>
-
-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)
-{
- tbm_bufmgr bufmgr;
-
- tbm->wl_tbm = wayland_tbm_server_init(display, NULL, -1, 0);
- if (!tbm->wl_tbm) {
- return false;
- }
-
- bufmgr = wayland_tbm_server_get_bufmgr(tbm->wl_tbm);
- if (!bufmgr) {
- wayland_tbm_server_deinit(tbm->wl_tbm);
- return false;
- }
-
- if (!tbm_bufmgr_bind_native_display(bufmgr, (void *)display)) {
- wayland_tbm_server_deinit(tbm->wl_tbm);
- return false;
- }
-
- 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;
-}
-
-struct tbm_client_buffer *
-tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer)
-{
- assert(ds_buffer->iface == &tbm_client_buffer_iface);
- return (struct tbm_client_buffer *)ds_buffer;
-}
-
-tbm_surface_h
-tbm_client_buffer_get_tbm_surface(struct tbm_client_buffer *buffer)
-{
- return buffer->surface;
-}
-
-static void
-tbm_server_handle_display_destroy(struct wl_listener *listener, void *data)
-{
- struct tbm_server *tbm;
-
- tbm = wl_container_of(listener, tbm, display_destroy);
- wayland_tbm_server_deinit(tbm->wl_tbm);
-}
-
-static bool
-tbm_buffer_resource_iface_is_instance(struct wl_resource *resource)
-{
- return !!wayland_tbm_server_get_surface(NULL, resource);
-}
-
-static void
-tbm_client_buffer_handle_resource_destroy(struct wl_listener *listener,
- void *data)
-{
- struct tbm_client_buffer *buffer;
-
- buffer = wl_container_of(listener, buffer, resource_destroy);
-
- buffer->resource = NULL;
- buffer->surface = NULL;
- wl_list_remove(&buffer->resource_destroy.link);
- wl_list_init(&buffer->resource_destroy.link);
-
- 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)
-{
- struct tbm_client_buffer *buffer;
-
- buffer = tbm_client_buffer_get_or_create(resource);
- assert(buffer);
-
- 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,
-};
-
-static void
-tbm_client_buffer_destroy(struct ds_buffer *ds_buffer)
-{
- struct tbm_client_buffer *buffer;
-
- buffer = tbm_client_buffer_from_buffer(ds_buffer);
-
- ds_inf("Destroy TBM client buffer(%p)", buffer);
-
- wl_list_remove(&buffer->resource_destroy.link);
- wl_list_remove(&buffer->buffer_release.link);
- free(buffer);
-}
-
-static bool
-tbm_client_buffer_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;
- tbm_surface_info_s info;
- tbm_bo_access_option op = TBM_OPTION_NONE;
- int err;
-
- buffer = tbm_client_buffer_from_buffer(ds_buffer);
-
- if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ)
- op |= TBM_OPTION_READ;
-
- if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE)
- op |= TBM_OPTION_WRITE;
-
- err = tbm_surface_map(buffer->surface, op, &info);
- if (err != TBM_SURFACE_ERROR_NONE) {
- ds_err("Failed tbm_surface_map()");
- return false;
- }
-
- *format = DRM_FORMAT_XRGB8888; // FIXME
- *stride = info.planes[0].stride;
- *data = info.planes[0].ptr;
-
- return true;
-}
-
-static void
-tbm_client_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer)
-{
- struct tbm_client_buffer *buffer;
-
- buffer = tbm_client_buffer_from_buffer(ds_buffer);
-
- tbm_surface_unmap(buffer->surface);
-}
-
-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,
-};
-
-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 *
-tbm_client_buffer_create(struct wl_resource *resource)
-{
- struct tbm_client_buffer *buffer;
- tbm_surface_h surface;
- int32_t width, height;
-
- surface = wayland_tbm_server_get_surface(NULL, resource);
- assert(surface);
-
- width = tbm_surface_get_width(surface);
- height = tbm_surface_get_height(surface);
-
- buffer = calloc(1, sizeof *buffer);
- assert(buffer);
-
- ds_buffer_init(&buffer->base, &tbm_client_buffer_iface, width, height);
-
- buffer->resource = resource;
- buffer->surface = surface;
- buffer->format = tbm_surface_get_format(surface);
-
- buffer->buffer_release.notify = tbm_client_buffer_handle_release;
- ds_buffer_add_release_listener(&buffer->base, &buffer->buffer_release);
-
- buffer->resource_destroy.notify =
- tbm_client_buffer_handle_resource_destroy;
- wl_resource_add_destroy_listener(resource, &buffer->resource_destroy);
-
- ds_inf("TBM client buffer(%p) created", buffer);
-
- return buffer;
-}
+++ /dev/null
-#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
#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
#include <libds/swapchain.h>
#endif
-#include "tbm-server-helper.h"
#include "pixman-helper.h"
#define TINYDS_UNUSED __attribute__((unused))
struct tinyds_server
{
- struct tbm_server tbm_server;
+ struct ds_tbm_server *tbm_server;
struct wl_display *display;
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);
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);
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)
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);
-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')
--- /dev/null
+#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;
+}
--- /dev/null
+#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
--- /dev/null
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <tbm_bufmgr.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);
+
+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) {
+ goto err_wl_tbm;
+ }
+
+ bufmgr = wayland_tbm_server_get_bufmgr(tbm->wl_tbm);
+ if (!bufmgr) {
+ goto err_bind;
+ }
+
+ if (!tbm_bufmgr_bind_native_display(bufmgr, (void *)display)) {
+ goto err_bind;
+ }
+
+ tbm->display_destroy.notify = tbm_server_handle_display_destroy;
+ wl_display_add_destroy_listener(display, &tbm->display_destroy);
+
+ 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;
+}
+
+WL_EXPORT void
+ds_tbm_server_add_destroy_listener(struct ds_tbm_server *tbm,
+ struct wl_listener *listener)
+{
+ 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;
+}
+
+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 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 void
+tbm_client_buffer_handle_release(struct wl_listener *listener, void *data)
+{
+ 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 ds_tbm_client_buffer *buffer;
+
+ buffer = wl_container_of(listener, buffer, resource_destroy);
+
+ buffer->resource = NULL;
+ buffer->surface = NULL;
+ wl_list_remove(&buffer->resource_destroy.link);
+ wl_list_init(&buffer->resource_destroy.link);
+
+ ds_buffer_drop(&buffer->base);
+}
+
+static struct ds_tbm_client_buffer *
+tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer)
+{
+ assert(ds_buffer->iface == &tbm_client_buffer_iface);
+ return (struct ds_tbm_client_buffer *)ds_buffer;
+}
+
+static void
+tbm_client_buffer_iface_destroy(struct ds_buffer *ds_buffer)
+{
+ struct ds_tbm_client_buffer *buffer;
+
+ buffer = tbm_client_buffer_from_buffer(ds_buffer);
+
+ ds_inf("Destroy TBM client buffer(%p)", buffer);
+
+ wl_list_remove(&buffer->resource_destroy.link);
+ wl_list_remove(&buffer->buffer_release.link);
+ free(buffer);
+}
+
+static bool
+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 ds_tbm_client_buffer *buffer;
+ tbm_surface_info_s info;
+ tbm_bo_access_option op = TBM_OPTION_NONE;
+ int err;
+
+ buffer = tbm_client_buffer_from_buffer(ds_buffer);
+
+ if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ)
+ op |= TBM_OPTION_READ;
+
+ if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE)
+ op |= TBM_OPTION_WRITE;
+
+ err = tbm_surface_map(buffer->surface, op, &info);
+ if (err != TBM_SURFACE_ERROR_NONE) {
+ ds_err("Failed tbm_surface_map()");
+ return false;
+ }
+
+ *format = convert_tbm_format_to_drm(buffer->format);
+ *stride = info.planes[0].stride;
+ *data = info.planes[0].ptr;
+
+ return true;
+}
+
+static void
+tbm_client_buffer_iface_end_ptr_access(struct ds_buffer *ds_buffer)
+{
+ struct ds_tbm_client_buffer *buffer;
+
+ buffer = tbm_client_buffer_from_buffer(ds_buffer);
+
+ tbm_surface_unmap(buffer->surface);
+}
+
+static const struct ds_buffer_interface tbm_client_buffer_iface = {
+ .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 struct ds_tbm_client_buffer *
+tbm_client_buffer_create(struct wl_resource *resource)
+{
+ struct ds_tbm_client_buffer *buffer;
+ tbm_surface_h surface;
+ int32_t width, height;
+
+ surface = wayland_tbm_server_get_surface(NULL, resource);
+ 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);
+ if (!buffer)
+ return NULL;
+
+ ds_buffer_init(&buffer->base, &tbm_client_buffer_iface, width, height);
+
+ buffer->resource = resource;
+ buffer->surface = surface;
+ buffer->format = tbm_surface_get_format(surface);
+
+ buffer->buffer_release.notify = tbm_client_buffer_handle_release;
+ ds_buffer_add_release_listener(&buffer->base, &buffer->buffer_release);
+
+ buffer->resource_destroy.notify =
+ tbm_client_buffer_handle_resource_destroy;
+ wl_resource_add_destroy_listener(resource, &buffer->resource_destroy);
+
+ ds_inf("TBM client buffer(%p) created", buffer);
+
+ 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,
+};
--- /dev/null
+#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