Add directories for tizen features 55/278155/1
authorSeunghun Lee <shiin.lee@samsung.com>
Wed, 16 Mar 2022 02:43:49 +0000 (11:43 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Mon, 18 Jul 2022 05:58:19 +0000 (14:58 +0900)
Change-Id: Ie629354a2c689293b678cc9cc4d22227a5068a94

28 files changed:
include/libds-tizen/allocator/tbm.h [new file with mode: 0644]
include/libds-tizen/backend/tdm.h [new file with mode: 0644]
include/libds/allocator/tbm.h [deleted file]
include/libds/backend/tdm.h [deleted file]
include/meson.build
meson.build
meson_options.txt
packaging/libds.spec
src/examples/meson.build
src/examples/tdm-backend.c
src/examples/tinyds-tdm.c
src/libds-tizen/allocator/meson.build [new file with mode: 0644]
src/libds-tizen/allocator/tbm.c [new file with mode: 0644]
src/libds-tizen/backend/meson.build [new file with mode: 0644]
src/libds-tizen/backend/tdm/backend.c [new file with mode: 0644]
src/libds-tizen/backend/tdm/meson.build [new file with mode: 0644]
src/libds-tizen/backend/tdm/output.c [new file with mode: 0644]
src/libds-tizen/backend/tdm/tdm.h [new file with mode: 0644]
src/libds-tizen/meson.build [new file with mode: 0644]
src/libds/allocator/meson.build
src/libds/allocator/tbm.c [deleted file]
src/libds/backend/meson.build
src/libds/backend/tdm/backend.c [deleted file]
src/libds/backend/tdm/meson.build [deleted file]
src/libds/backend/tdm/output.c [deleted file]
src/libds/backend/tdm/tdm.h [deleted file]
src/libds/meson.build
src/meson.build

diff --git a/include/libds-tizen/allocator/tbm.h b/include/libds-tizen/allocator/tbm.h
new file mode 100644 (file)
index 0000000..3febb10
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef LIBDS_TIZEN_ALLOCATOR_TBM_H
+#define LIBDS_TIZEN_ALLOCATOR_TBM_H
+
+#include <libds/allocator.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ds_allocator *
+ds_tbm_allocator_create(void);
+
+WL_EXPORT void *
+ds_tbm_buffer_get_surface(struct ds_buffer *ds_buffer);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libds-tizen/backend/tdm.h b/include/libds-tizen/backend/tdm.h
new file mode 100644 (file)
index 0000000..d2785b2
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef LIBDS_TIZEN_BACKEND_TDM_H
+#define LIBDS_TIZEN_BACKEND_TDM_H
+
+#include <libds/backend.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ds_backend *
+ds_tdm_backend_create(struct wl_display *display);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libds/allocator/tbm.h b/include/libds/allocator/tbm.h
deleted file mode 100644 (file)
index c02aee3..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef LIBDS_ALLOCATOR_TBM_H
-#define LIBDS_ALLOCATOR_TBM_H
-
-#include <libds/allocator.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_allocator *
-ds_tbm_allocator_create(void);
-
-WL_EXPORT void *
-ds_tbm_buffer_get_surface(struct ds_buffer *ds_buffer);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/include/libds/backend/tdm.h b/include/libds/backend/tdm.h
deleted file mode 100644 (file)
index e697413..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef LIBDS_BACKEND_TDM_H
-#define LIBDS_BACKEND_TDM_H
-
-#include <libds/backend.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_backend *
-ds_tdm_backend_create(struct wl_display *display);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
index f273424348e496145c3af936738a5d9b399d5732..0975c5d365158d00776cde67aecfd11b013ddd3c 100644 (file)
@@ -1,13 +1,9 @@
-exclude_files = []
-if not features.get('tdm-backend')
-  exclude_files += 'backend/tdm.h'
-endif
-
-if not features.get('tbm-allocator')
-  exclude_files += 'allocator/tbm.h'
-endif
-
 install_subdir('libds',
   install_dir: get_option('includedir'),
-  exclude_files: exclude_files,
 )
+
+if get_option('tizen')
+  install_subdir('libds-tizen',
+    install_dir: get_option('includedir'),
+  )
+endif
index 0e4e5c0d29613f8175f6a2b9ae5319dbce89f6f7..d3d2df04410cc3c9cda07cc31f34486dc2be2ce8 100644 (file)
@@ -25,14 +25,7 @@ cdata.set('LIBDS_VERSION_MAJOR', libds_version_major)
 cdata.set('LIBDS_VERSION_MINOR', libds_version_minor)
 cdata.set('LIBDS_VERSION_PATCH', libds_version_patch)
 
-features = {
-  'tdm-backend': false,
-  'tbm-allocator': false,
-}
-
 subdir('src')
 subdir('include')
 
 configure_file(output: 'config.h', install: false, configuration: cdata)
-
-summary(features, bool_yn: true)
index 02af9b012349d2217f8e1e4dc824c06a09b15bd7..6ef6c8e45ec048d92a0bb853e6c42df407609960 100644 (file)
@@ -1 +1 @@
-option('backends', type: 'array', choices: ['auto', 'tdm'], value: ['auto'], description: 'Select built-in backends')
+option('tizen', type: 'boolean', value: false, description: 'Build Tizen features')
index bd38de777a011229afb0fcca1de705eb1ba8ce30..879a87dfd939abb15c460cde765e6d129810cd20 100644 (file)
@@ -30,6 +30,12 @@ Requires:   %{name} = %{version}-%{release}
 %description devel
 Development package of Wayland Compositor Library
 
+%package tizen-devel
+Summary: Wayland Compositor development package on Tizen
+
+%description tizen-devel
+Wayland Compositor development library for Tizen platform
+
 %prep
 %setup -q
 cp %{SOURCE1001} .
@@ -39,7 +45,8 @@ meson setup \
     --prefix /usr \
     --libdir %{_libdir} \
     --bindir %{_bindir} \
-    builddir
+    builddir \
+    -Dtizen=true
 ninja -C builddir all
 
 %install
@@ -56,7 +63,19 @@ ninja -C builddir install
 %manifest %{name}.manifest
 %defattr(-,root,root,-)
 %license LICENSE
-%{_includedir}/*
+%{_includedir}/libds/*
 %{_libdir}/pkgconfig/libds.pc
 %{_libdir}/libds.so
-%{_bindir}/*
+%{_bindir}/wl-backend
+%{_bindir}/tinyds
+
+%files tizen-devel
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%license LICENSE
+%{_includedir}/libds-tizen/*
+%{_libdir}/pkgconfig/libds-tizen.pc
+%{_libdir}/libds-tizen.so
+%{_bindir}/tdm-backend
+%{_bindir}/tinyds-tdm
+%{_bindir}/ds-simple-tbm
index 193b4a5b8993b12e78b5fd671c85961903038b38..f95bd505056279df64dd9550eaeea5da5c56648e 100644 (file)
@@ -23,7 +23,9 @@ executable('tinyds',
   install : true
 )
 
-if features.get('tdm-backend')
+if get_option('tizen')
+  common_deps += dep_libds_tizen
+
   executable('tdm-backend',
     'tdm-backend.c',
     dependencies: common_deps,
index ee39f06b2aec635c34b2ed0f5630ad7aaf5f24a9..ba3fecb2d04dc343fa16e39f60bc8acf0b504463 100644 (file)
@@ -8,10 +8,10 @@
 #include <libds/log.h>
 #include <libds/backend.h>
 #include <libds/output.h>
-#include <libds/allocator/tbm.h>
-#include <libds/backend/tdm.h>
 #include <libds/swapchain.h>
 #include <libds/compositor.h>
+#include <libds-tizen/allocator/tbm.h>
+#include <libds-tizen/backend/tdm.h>
 
 #define WIDTH   1280
 #define HEIGHT  720
index 2c91a66363c4c96ad340ca8b2064103937e07606..143d53efd101b3c9dba88077e93f9b0455c637e4 100644 (file)
 #include <libds/log.h>
 #include <libds/backend.h>
 #include <libds/output.h>
-#include <libds/allocator/tbm.h>
-#include <libds/backend/tdm.h>
 #include <libds/swapchain.h>
 #include <libds/compositor.h>
 #include <libds/xdg_shell.h>
+#include <libds-tizen/allocator/tbm.h>
+#include <libds-tizen/backend/tdm.h>
 
 #define TINYDS_UNUSED   __attribute__((unused))
 
diff --git a/src/libds-tizen/allocator/meson.build b/src/libds-tizen/allocator/meson.build
new file mode 100644 (file)
index 0000000..fe869bd
--- /dev/null
@@ -0,0 +1,2 @@
+libds_tizen_files += files('tbm.c')
+libds_tizen_deps += dependency('libtbm', required: true)
diff --git a/src/libds-tizen/allocator/tbm.c b/src/libds-tizen/allocator/tbm.c
new file mode 100644 (file)
index 0000000..dc3be42
--- /dev/null
@@ -0,0 +1,177 @@
+#include <assert.h>
+#include <stdlib.h>
+
+#include <drm_fourcc.h>
+#include <wayland-server.h>
+#include <tbm_bufmgr.h>
+#include <tbm_surface.h>
+
+#include "libds/interfaces/allocator.h"
+#include "libds/interfaces/buffer.h"
+#include "libds/log.h"
+
+struct ds_tbm_allocator
+{
+    struct ds_allocator base;
+    tbm_bufmgr bufmgr;
+};
+
+struct ds_tbm_buffer
+{
+    struct ds_buffer base;
+    tbm_surface_h surface;
+};
+
+static const struct ds_allocator_interface tbm_allocator_iface;
+static struct ds_tbm_buffer *tbm_buffer_from_buffer(struct ds_buffer *buffer);
+
+WL_EXPORT struct ds_allocator *
+ds_tbm_allocator_create(void)
+{
+    struct ds_tbm_allocator *alloc;
+
+    alloc = calloc(1, sizeof *alloc);
+    if (!alloc)
+        return NULL;
+
+    alloc->bufmgr = tbm_bufmgr_init(-1);
+    if (!alloc->bufmgr) {
+        ds_err("Could not initialize tbm_bufmgr");
+        free(alloc);
+        return NULL;
+    }
+
+    ds_allocator_init(&alloc->base, &tbm_allocator_iface,
+            DS_BUFFER_CAP_DATA_PTR);
+
+    ds_inf("TBM allocator(%p) created", alloc);
+
+    return &alloc->base;
+}
+
+WL_EXPORT void *
+ds_tbm_buffer_get_surface(struct ds_buffer *ds_buffer)
+{
+    struct ds_tbm_buffer *buffer;
+
+    buffer = tbm_buffer_from_buffer(ds_buffer);
+    if (!buffer)
+        return NULL;
+
+    return buffer->surface;
+}
+
+static struct ds_tbm_allocator *
+tbm_allocator_from_allocator(struct ds_allocator *ds_allocator)
+{
+    assert(ds_allocator->iface == &tbm_allocator_iface);
+    return (struct ds_tbm_allocator *)ds_allocator;
+}
+
+static const struct ds_buffer_interface tbm_buffer_iface;
+
+static struct ds_tbm_buffer *
+tbm_buffer_from_buffer(struct ds_buffer *buffer)
+{
+    assert(buffer->iface == &tbm_buffer_iface);
+    return (struct ds_tbm_buffer *)buffer;
+}
+
+static void
+tbm_buffer_destroy(struct ds_buffer *ds_buffer)
+{
+    struct ds_tbm_buffer *buffer;
+
+    buffer = tbm_buffer_from_buffer(ds_buffer);
+
+    ds_dbg("Destroy tbm buffer(%p)", buffer);
+
+    tbm_surface_destroy(buffer->surface);
+    free(buffer);
+}
+
+static bool
+tbm_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, uint32_t flags,
+        void **data, uint32_t *format, size_t *stride)
+{
+    struct ds_tbm_buffer *buffer;
+    tbm_surface_info_s info;
+    int tbm_access_flags = 0;
+    int ret;
+
+    buffer = tbm_buffer_from_buffer(ds_buffer);
+
+    if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ)
+        tbm_access_flags |= TBM_OPTION_READ;
+    else if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE)
+        tbm_access_flags |= TBM_OPTION_WRITE;
+
+    ret = tbm_surface_map(buffer->surface, tbm_access_flags, &info);
+    if (ret != TBM_SURFACE_ERROR_NONE) {
+        ds_err("Could not map tbm_surface of buffer(%p)", buffer);
+        return false;
+    }
+    
+    *data = info.planes[0].ptr;
+    *format = info.format;
+    *stride = info.planes[0].stride;
+
+    return true;
+}
+
+static void
+tbm_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer)
+{
+    struct ds_tbm_buffer *buffer;
+
+    buffer = tbm_buffer_from_buffer(ds_buffer);
+
+    tbm_surface_unmap(buffer->surface);
+}
+
+static const struct ds_buffer_interface tbm_buffer_iface =
+{
+    .destroy = tbm_buffer_destroy,
+    .begin_data_ptr_access = tbm_buffer_begin_data_ptr_access,
+    .end_data_ptr_access = tbm_buffer_end_data_ptr_access,
+};
+
+static void
+tbm_allocator_destroy(struct ds_allocator *ds_allocator)
+{
+    struct ds_tbm_allocator *alloc;
+
+    alloc = tbm_allocator_from_allocator(ds_allocator);
+
+    ds_inf("Destroy TBM allocator(%p)", alloc);
+
+    tbm_bufmgr_deinit(alloc->bufmgr);
+    free(alloc);
+}
+
+static struct ds_buffer *
+tbm_allocator_create_buffer(struct ds_allocator *ds_allocator,
+        int width, int height, uint32_t format)
+{
+    static int num_buffers = 0;
+    struct ds_tbm_buffer *buffer;
+
+    buffer = calloc(1, sizeof *buffer);
+    if (!buffer)
+        return NULL;
+
+    ds_buffer_init(&buffer->base, &tbm_buffer_iface, width, height);
+
+    buffer->surface = tbm_surface_create(width, height, TBM_FORMAT_XRGB8888);
+
+    ds_dbg("tbm buffer(%p) created: size(%dx%d) number of buffers: %d",
+            buffer, width, height, ++num_buffers);
+
+    return &buffer->base;
+}
+
+static const struct ds_allocator_interface tbm_allocator_iface =
+{
+    .destroy = tbm_allocator_destroy,
+    .create_buffer = tbm_allocator_create_buffer,
+};
diff --git a/src/libds-tizen/backend/meson.build b/src/libds-tizen/backend/meson.build
new file mode 100644 (file)
index 0000000..8a05e13
--- /dev/null
@@ -0,0 +1 @@
+subdir('tdm')
diff --git a/src/libds-tizen/backend/tdm/backend.c b/src/libds-tizen/backend/tdm/backend.c
new file mode 100644 (file)
index 0000000..e756ac1
--- /dev/null
@@ -0,0 +1,176 @@
+#include <assert.h>
+#include <stdlib.h>
+
+#include "libds/log.h"
+
+#include "tdm.h"
+
+static const struct ds_backend_interface tdm_backend_iface;
+
+static void tdm_backend_handle_display_destroy(struct wl_listener *listener,
+        void *data);
+static void tdm_backend_destroy(struct ds_tdm_backend *tdm);
+static int tdm_backend_handle_tdm_event(int fd, uint32_t mask, void *data);
+
+WL_EXPORT struct ds_backend *
+ds_tdm_backend_create(struct wl_display *display)
+{
+    struct ds_tdm_backend *tdm;
+    struct wl_event_loop *loop;
+    tdm_error err;
+
+    ds_inf("Initializing TDM backend");
+
+    tdm = calloc(1, sizeof *tdm);
+    if (!tdm)
+        return NULL;
+
+    ds_backend_init(&tdm->base, &tdm_backend_iface);
+
+    tdm->wl_display = display;
+    tdm->clock = CLOCK_MONOTONIC;   // FIXME
+
+    wl_list_init(&tdm->outputs);
+    wl_list_init(&tdm->buffers);
+
+    tdm->tdm_display = tdm_display_init(&err);
+    if (err != TDM_ERROR_NONE) {
+        ds_err("Could not initialize tdm_display");
+        goto err_display;
+    }
+
+    err = tdm_display_get_fd(tdm->tdm_display, &tdm->fd);
+    if (err != TDM_ERROR_NONE || tdm->fd < 0) {
+        ds_err("Could not get fd from tdm_display: err(%d)", err);
+        goto err_fd;
+    }
+
+    loop = wl_display_get_event_loop(display);
+    tdm->tdm_event = wl_event_loop_add_fd(loop, tdm->fd, WL_EVENT_READABLE,
+            tdm_backend_handle_tdm_event, tdm);
+    if (!tdm->tdm_event) {
+        ds_err("could not add fd event handler for tdm event");
+        goto err_event;
+    }
+
+    tdm->display_destroy.notify = tdm_backend_handle_display_destroy;
+    wl_display_add_destroy_listener(display, &tdm->display_destroy);
+
+    return &tdm->base;
+
+err_event:
+    close(tdm->fd);
+err_fd:
+    tdm_display_deinit(tdm->tdm_display);
+err_display:
+    free(tdm);
+
+    return NULL;
+}
+
+struct ds_tdm_backend *
+tdm_backend_from_backend(struct ds_backend *backend)
+{
+    assert(backend->iface == &tdm_backend_iface);
+    return (struct ds_tdm_backend *)backend;
+}
+
+static void
+tdm_backend_destroy(struct ds_tdm_backend *tdm)
+{
+    struct ds_tdm_output *output, *tmp_output;
+    struct ds_tdm_buffer *buffer, *tmp_buffer;
+
+    wl_list_for_each_safe(output, tmp_output, &tdm->outputs, link)
+        ds_output_destroy(&output->base);
+
+    wl_list_for_each_safe(buffer, tmp_buffer, &tdm->buffers, link)
+        destroy_tdm_buffer(buffer);
+
+    wl_list_remove(&tdm->display_destroy.link);
+    wl_event_source_remove(tdm->tdm_event);
+    close(tdm->fd);
+    tdm_display_deinit(tdm->tdm_display);
+    ds_backend_finish(&tdm->base);
+    free(tdm);
+}
+
+static bool
+tdm_backend_scan_outputs(struct ds_tdm_backend *tdm)
+{
+    struct ds_tdm_output *output;
+    tdm_output *tdm_output;
+    tdm_error err;
+    int num_outputs, i;
+
+    err = tdm_display_get_output_count(tdm->tdm_display, &num_outputs);
+    if (err != TDM_ERROR_NONE) {
+        ds_err("Could not get number of outputs: err(%d)", err);
+        return false;
+    }
+
+    for (i = 0; i < num_outputs; i++) {
+        tdm_output = tdm_display_get_output(tdm->tdm_display, i, &err);
+        if (err != TDM_ERROR_NONE || !tdm_output) {
+            ds_err("Could not get output from tdm_display: index(%d) err(%d)",
+                    i, err);
+            continue;
+        }
+
+        output = create_tdm_output(tdm, tdm_output);
+        if (!output) {
+            ds_err("Could not create output: index(%d)", i);
+            continue;
+        }
+
+        wl_list_insert(&tdm->outputs, &output->link);
+
+        wl_signal_emit(&tdm->base.events.new_output, &output->base);
+    }
+
+    return true;
+}
+
+static bool
+tdm_backend_iface_start(struct ds_backend *backend)
+{
+    struct ds_tdm_backend *tdm;
+
+    tdm = tdm_backend_from_backend(backend);
+    return tdm_backend_scan_outputs(tdm);
+}
+
+static void
+tdm_backend_iface_destroy(struct ds_backend *backend)
+{
+    struct ds_tdm_backend *tdm;
+
+    tdm = tdm_backend_from_backend(backend);
+    tdm_backend_destroy(tdm);
+}
+
+static const struct ds_backend_interface tdm_backend_iface =
+{
+    .start = tdm_backend_iface_start,
+    .destroy = tdm_backend_iface_destroy,
+    .get_drm_fd = NULL,
+};
+
+static void
+tdm_backend_handle_display_destroy(struct wl_listener *listener, void *data)
+{
+    struct ds_tdm_backend *tdm;
+
+    tdm = wl_container_of(listener, tdm, display_destroy);
+    tdm_backend_destroy(tdm);
+}
+
+static int
+tdm_backend_handle_tdm_event(int fd, uint32_t mask, void *data)
+{
+    struct ds_tdm_backend *tdm = data;
+
+    tdm_display_handle_events(tdm->tdm_display);
+
+    return 0;
+}
diff --git a/src/libds-tizen/backend/tdm/meson.build b/src/libds-tizen/backend/tdm/meson.build
new file mode 100644 (file)
index 0000000..39ffceb
--- /dev/null
@@ -0,0 +1,12 @@
+libds_tizen_files += files(
+  'backend.c',
+  'output.c',
+)
+
+libtdm = dependency('libtdm', required: true)
+libtbm = dependency('libtbm', required: true)
+
+libds_tizen_deps += [
+  libtdm,
+  libtbm
+]
diff --git a/src/libds-tizen/backend/tdm/output.c b/src/libds-tizen/backend/tdm/output.c
new file mode 100644 (file)
index 0000000..f6b6250
--- /dev/null
@@ -0,0 +1,368 @@
+#include <assert.h>
+#include <stdlib.h>
+
+#include <tbm_surface.h>
+
+#include "libds/log.h"
+#include "libds-tizen/allocator/tbm.h"
+
+#include "tdm.h"
+
+static const struct ds_output_interface tdm_output_iface;
+static bool output_init_modes(struct ds_tdm_output *output);
+static void output_destroy(struct ds_tdm_output *output);
+static void output_init_hwc(struct ds_tdm_output *output);
+static bool output_update_mode(struct ds_tdm_output *output);
+static bool output_set_pending_fb(struct ds_tdm_output *output,
+        struct ds_buffer *ds_buffer);
+static bool output_hwc_commit(struct ds_tdm_output *output);
+
+struct ds_tdm_output *
+create_tdm_output(struct ds_tdm_backend *tdm, tdm_output *tdm_output)
+{
+    struct ds_tdm_output *output;
+    tdm_output_conn_status conn;
+    tdm_error err;
+
+    output = calloc(1, sizeof *output);
+    if (!output)
+        return NULL;
+
+    ds_output_init(&output->base, &tdm->base, &tdm_output_iface,
+            tdm->wl_display);
+
+    output->backend = tdm;
+    output->tdm.output = tdm_output;
+
+    err = tdm_output_get_conn_status(tdm_output, &conn);
+    if (err != TDM_ERROR_NONE) {
+        ds_err("Could not get connection status of tdm output(%p): err(%d)",
+                tdm_output, err);
+        goto err_status;
+    }
+
+    if (conn == TDM_OUTPUT_CONN_STATUS_CONNECTED) {
+        output->status = DS_TDM_OUTPUT_CONNECTED;
+
+        if (!output_init_modes(output)) {
+            ds_err("Could not initialize modes of tdm output(%p)",
+                    tdm_output);
+            goto err_status;
+        }
+    }
+    else if (conn == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) {
+        output->status = DS_TDM_OUTPUT_DISCONNECTED;
+    }
+
+    if (tdm_output_get_hwc(output->tdm.output, NULL) != NULL)
+        output_init_hwc(output);
+
+    ds_inf("TDM output(%p) created: hwc(%p)", output, output->tdm.hwc);
+
+    return output;
+
+err_status:
+    free(output);
+
+    return NULL;
+}
+
+static struct ds_tdm_output *
+tdm_output_from_output(struct ds_output *ds_output)
+{
+    assert(ds_output->iface == &tdm_output_iface);
+    return (struct ds_tdm_output *)ds_output;
+}
+
+static void
+output_iface_destroy(struct ds_output *ds_output)
+{
+    struct ds_tdm_output *output;
+
+    output = tdm_output_from_output(ds_output);
+    output_destroy(output);
+}
+
+void
+destroy_tdm_buffer(struct ds_tdm_buffer *buffer)
+{
+    if (buffer == NULL)
+        return;
+
+    wl_list_remove(&buffer->buffer_destroy.link);
+    wl_list_remove(&buffer->link);
+    free(buffer);
+}
+
+static void
+buffer_handle_buffer_destroy(struct wl_listener *listener, void *data)
+{
+    struct ds_tdm_buffer *buffer;
+
+    buffer = wl_container_of(listener, buffer, buffer_destroy);
+    destroy_tdm_buffer(buffer);
+}
+
+static struct ds_tdm_buffer *
+create_tdm_buffer(struct ds_tdm_backend *backend, struct ds_buffer *ds_buffer)
+{
+    struct ds_tdm_buffer *buffer;
+    tbm_surface_h surface;
+
+    surface = ds_tbm_buffer_get_surface(ds_buffer);
+    if (!surface) {
+        ds_err("Could not get tbm_surface_h");
+        return NULL;
+    }
+
+    buffer = calloc(1, sizeof *buffer);
+    if (!buffer)
+        return NULL;
+
+    buffer->surface = surface;
+    buffer->buffer = ds_buffer_lock(ds_buffer);
+    wl_list_insert(&backend->buffers, &buffer->link);
+
+    buffer->buffer_destroy.notify = buffer_handle_buffer_destroy;
+    ds_buffer_add_destroy_listener(ds_buffer, &buffer->buffer_destroy);
+
+    return buffer;
+}
+
+static struct ds_tdm_buffer *
+get_or_create_tdm_buffer(struct ds_tdm_backend *backend,
+        struct ds_buffer *ds_buffer)
+{
+    struct ds_tdm_buffer *buffer;
+
+    wl_list_for_each(buffer, &backend->buffers, link) {
+        if (buffer->buffer == ds_buffer && buffer->released) {
+            buffer->released = false;
+            ds_buffer_lock(buffer->buffer);
+            return buffer;
+        }
+    }
+
+    return create_tdm_buffer(backend, ds_buffer);
+}
+
+static void
+tdm_buffer_release(struct ds_tdm_buffer *buffer)
+{
+    buffer->released = true;
+    ds_buffer_unlock(buffer->buffer);
+}
+
+static void
+output_update_front_buffer(struct ds_tdm_output *output)
+{
+    if (output->front_buffer)
+        tdm_buffer_release(output->front_buffer);
+    output->front_buffer = output->back_buffer;
+    output->back_buffer = NULL;
+}
+
+static void
+output_attach_back_buffer(struct ds_tdm_output *output,
+        struct ds_tdm_buffer *buffer)
+{
+    if (output->back_buffer)
+        tdm_buffer_release(output->back_buffer);
+    output->back_buffer = buffer;
+}
+
+static bool
+output_iface_commit(struct ds_output *ds_output)
+{
+    struct ds_tdm_output *output;
+
+    output = tdm_output_from_output(ds_output);
+
+    if (ds_output->pending.committed & DS_OUTPUT_STATE_MODE) {
+        if (!output_update_mode(output)) {
+            ds_err("Could not update TDM mode");
+            return false;
+        }
+    }
+
+    if (ds_output->pending.committed & DS_OUTPUT_STATE_BUFFER) {
+        if (!output_set_pending_fb(output, ds_output->pending.buffer))
+            ds_err("Could not update buffer");
+    }
+
+    if (!output_hwc_commit(output)) {
+        ds_err("Could not commit tdm output");
+        if (output->back_buffer) {
+            tdm_buffer_release(output->back_buffer);
+        }
+    }
+
+    return true;
+}
+
+static const struct ds_output_interface tdm_output_iface =
+{
+    .destroy = output_iface_destroy,
+    .commit = output_iface_commit,
+};
+
+static void
+output_destroy(struct ds_tdm_output *output)
+{
+    struct ds_tdm_output_mode *mode, *mode_tmp;
+
+    wl_list_for_each_safe(mode, mode_tmp, &output->base.modes, base.link) {
+        wl_list_remove(&mode->base.link);
+        free(mode);
+    }
+
+    if (output->back_buffer)
+        ds_buffer_unlock(output->back_buffer->buffer);
+
+    if (output->front_buffer)
+        ds_buffer_unlock(output->front_buffer->buffer);
+
+    free(output);
+}
+
+static bool
+output_init_modes(struct ds_tdm_output *output)
+{
+    struct ds_tdm_output_mode *mode;
+    const tdm_output_mode *tdm_modes, *tdm_mode;
+    tdm_error err;
+    int num_modes, i;
+
+    err = tdm_output_get_available_modes(output->tdm.output, &tdm_modes,
+            &num_modes);
+    if (err != TDM_ERROR_NONE) {
+        ds_err("Could not get available modes: output(%p)", output);
+        return false;
+    }
+
+    ds_dbg("Detected modes:");
+
+    for (i = 0; i < num_modes; i++) {
+        tdm_mode = &tdm_modes[i];
+
+        mode = calloc(1, sizeof *mode);
+        if (!mode) {
+            ds_err("Could not allocate memory");
+            continue;
+        }
+
+        mode->tdm_mode = tdm_mode;
+        mode->base.width = tdm_mode->hdisplay;
+        mode->base.height = tdm_mode->vdisplay;
+        mode->base.refresh = (int32_t)tdm_mode->vrefresh; // FIXME
+
+        if (tdm_mode->type & TDM_OUTPUT_MODE_TYPE_PREFERRED)
+            mode->base.preferred = true;
+
+        ds_dbg("  %dx%d@%d %s", mode->base.width, mode->base.height,
+                mode->base.refresh,
+                mode->base.preferred ? "(preferred)" : "");
+
+        if (tdm_mode->type & TDM_OUTPUT_MODE_TYPE_DEFAULT)
+            wl_list_insert(&output->base.modes, &mode->base.link);
+        else
+            wl_list_insert(output->base.modes.prev, &mode->base.link);
+    }
+
+    return true;
+}
+
+static void
+output_init_hwc(struct ds_tdm_output *output)
+{
+    tdm_error err;
+
+    output->tdm.hwc = tdm_output_get_hwc(output->tdm.output, &err);
+    if (err != TDM_ERROR_NONE || !output->tdm.hwc) {
+        ds_err("Could not get tdm_hwc: output(%p)", output);
+        return;
+    }
+}
+
+static bool
+output_update_mode(struct ds_tdm_output *output)
+{
+    const struct ds_tdm_output_mode *mode;
+    tdm_error err;
+
+    mode = (struct ds_tdm_output_mode *)output->base.pending.mode;
+
+    ds_inf("TDM output(%p) set mode %dx%d %d mHz", output,
+            mode->base.width, mode->base.height, mode->base.refresh);
+
+    err = tdm_output_set_mode(output->tdm.output, mode->tdm_mode);
+    if (err != TDM_ERROR_NONE)
+        return false;
+
+    return true;
+}
+
+static bool
+output_set_pending_fb(struct ds_tdm_output *output,
+        struct ds_buffer *ds_buffer)
+{
+    struct ds_tdm_buffer *buffer;
+    tdm_region fb_damage;
+    tdm_error err;
+
+    buffer = get_or_create_tdm_buffer(output->backend, ds_buffer);
+    if (!buffer)
+        return false;
+
+    memset(&fb_damage, 0, sizeof(fb_damage));
+    err = tdm_hwc_set_client_target_buffer(output->tdm.hwc,
+            buffer->surface, fb_damage);
+    if (err != TDM_ERROR_NONE) {
+        ds_err("Could not set hwc client target buffer");
+        ds_buffer_unlock(buffer->buffer);
+        return false;
+    }
+
+    output_attach_back_buffer(output, buffer);
+
+    return true;
+}
+
+static void
+output_hwc_commit_handler(tdm_hwc *hwc, unsigned int sequence,
+        unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+    struct ds_tdm_output *output = user_data;
+
+    output_update_front_buffer(output);
+
+    wl_signal_emit(&output->base.events.frame, &output->base);
+}
+
+static bool
+output_hwc_commit(struct ds_tdm_output *output)
+{
+    tdm_error err;
+    uint32_t num_changes;
+
+    err = tdm_hwc_validate(output->tdm.hwc, NULL, 0, &num_changes);
+    if (err != TDM_ERROR_NONE) {
+        ds_err("Could not hwc validate");
+        return false;
+    }
+
+    err = tdm_hwc_accept_validation(output->tdm.hwc);
+    if (err != TDM_ERROR_NONE) {
+        ds_err("Could not hwc accept validation");
+        return false;
+    }
+
+    err = tdm_hwc_commit(output->tdm.hwc, 0, output_hwc_commit_handler,
+            output);
+    if (err != TDM_ERROR_NONE) {
+        ds_err("Could not hwc commit");
+        return false;
+    }
+
+    return true;
+}
diff --git a/src/libds-tizen/backend/tdm/tdm.h b/src/libds-tizen/backend/tdm/tdm.h
new file mode 100644 (file)
index 0000000..275089c
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef DS_TIZEN_BACKEND_TDM_H
+#define DS_TIZEN_BACKEND_TDM_H
+
+#include <time.h>
+
+#include <tdm.h>
+
+#include "libds/interfaces/backend.h"
+#include "libds/interfaces/output.h"
+
+enum ds_tdm_output_status {
+    DS_TDM_OUTPUT_DISCONNECTED,
+    DS_TDM_OUTPUT_CONNECTED,
+};
+
+struct ds_tdm_output_mode {
+    struct ds_output_mode base;
+    const tdm_output_mode *tdm_mode;
+};
+
+struct ds_tdm_backend
+{
+    struct ds_backend base;
+
+    tdm_display *tdm_display;
+    struct wl_display *wl_display;
+    struct wl_event_source *tdm_event;
+
+    struct wl_list outputs; // ds_tdm_output.link
+    struct wl_list buffers; // ds_tdm_buffer.link
+
+    struct wl_listener display_destroy;
+
+    clockid_t clock;
+    int fd;
+};
+
+struct ds_tdm_output
+{
+    struct ds_output base;
+
+    struct ds_tdm_backend *backend;
+    struct ds_tdm_buffer *front_buffer, *back_buffer;
+
+    struct {
+        tdm_output *output;
+        tdm_hwc *hwc;
+    } tdm;
+
+    struct wl_list link;
+
+    enum ds_tdm_output_status status;
+};
+
+struct ds_tdm_buffer
+{
+    struct ds_buffer *buffer;
+    tbm_surface_h surface;
+    struct wl_list link; // ds_wl_backend.buffers
+    struct wl_listener buffer_destroy;
+
+    bool released;
+};
+
+struct ds_tdm_backend *tdm_backend_from_backend(struct ds_backend *backend);
+
+struct ds_tdm_output *create_tdm_output(struct ds_tdm_backend *tdm,
+        tdm_output *tdm_output);
+
+void destroy_tdm_buffer(struct ds_tdm_buffer *buffer);
+
+
+#endif
diff --git a/src/libds-tizen/meson.build b/src/libds-tizen/meson.build
new file mode 100644 (file)
index 0000000..e9ca734
--- /dev/null
@@ -0,0 +1,29 @@
+libds_tizen_files = []
+
+libds_tizen_deps = [
+  dep_libds,
+]
+
+subdir('allocator')
+subdir('backend')
+
+lib_libds_tizen = shared_library('ds-tizen', libds_tizen_files,
+  dependencies: libds_tizen_deps,
+  include_directories: [ common_inc, include_directories('.') ],
+  version: meson.project_version(),
+  install: true
+)
+
+dep_libds_tizen = declare_dependency(
+  link_with: lib_libds_tizen,
+  dependencies: libds_tizen_deps,
+  include_directories: [ common_inc, include_directories('.') ],
+)
+
+pkgconfig = import('pkgconfig')
+pkgconfig.generate(lib_libds_tizen,
+  version: meson.project_version(),
+  filebase: 'libds-tizen',
+  name: 'libds-tizen',
+  description: 'extension of libds for tizen platform',
+)
index 361f96e1ad2d3ba15a3782fbc5132ba86a2ece33..173c2193a5ff0a2ae766bfeee0a81156e98acc0d 100644 (file)
@@ -1,12 +1 @@
 libds_files += files('shm.c')
-
-libtbm = dependency(
-  'libtbm',
-  required: false,
-  not_found_message: 'Required for TBM allocator support.'
-)
-if libtbm.found()
-  libds_files += files('tbm.c')
-  libds_deps += libtbm
-  features += { 'tbm-allocator': true }
-endif
diff --git a/src/libds/allocator/tbm.c b/src/libds/allocator/tbm.c
deleted file mode 100644 (file)
index dc3be42..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-
-#include <drm_fourcc.h>
-#include <wayland-server.h>
-#include <tbm_bufmgr.h>
-#include <tbm_surface.h>
-
-#include "libds/interfaces/allocator.h"
-#include "libds/interfaces/buffer.h"
-#include "libds/log.h"
-
-struct ds_tbm_allocator
-{
-    struct ds_allocator base;
-    tbm_bufmgr bufmgr;
-};
-
-struct ds_tbm_buffer
-{
-    struct ds_buffer base;
-    tbm_surface_h surface;
-};
-
-static const struct ds_allocator_interface tbm_allocator_iface;
-static struct ds_tbm_buffer *tbm_buffer_from_buffer(struct ds_buffer *buffer);
-
-WL_EXPORT struct ds_allocator *
-ds_tbm_allocator_create(void)
-{
-    struct ds_tbm_allocator *alloc;
-
-    alloc = calloc(1, sizeof *alloc);
-    if (!alloc)
-        return NULL;
-
-    alloc->bufmgr = tbm_bufmgr_init(-1);
-    if (!alloc->bufmgr) {
-        ds_err("Could not initialize tbm_bufmgr");
-        free(alloc);
-        return NULL;
-    }
-
-    ds_allocator_init(&alloc->base, &tbm_allocator_iface,
-            DS_BUFFER_CAP_DATA_PTR);
-
-    ds_inf("TBM allocator(%p) created", alloc);
-
-    return &alloc->base;
-}
-
-WL_EXPORT void *
-ds_tbm_buffer_get_surface(struct ds_buffer *ds_buffer)
-{
-    struct ds_tbm_buffer *buffer;
-
-    buffer = tbm_buffer_from_buffer(ds_buffer);
-    if (!buffer)
-        return NULL;
-
-    return buffer->surface;
-}
-
-static struct ds_tbm_allocator *
-tbm_allocator_from_allocator(struct ds_allocator *ds_allocator)
-{
-    assert(ds_allocator->iface == &tbm_allocator_iface);
-    return (struct ds_tbm_allocator *)ds_allocator;
-}
-
-static const struct ds_buffer_interface tbm_buffer_iface;
-
-static struct ds_tbm_buffer *
-tbm_buffer_from_buffer(struct ds_buffer *buffer)
-{
-    assert(buffer->iface == &tbm_buffer_iface);
-    return (struct ds_tbm_buffer *)buffer;
-}
-
-static void
-tbm_buffer_destroy(struct ds_buffer *ds_buffer)
-{
-    struct ds_tbm_buffer *buffer;
-
-    buffer = tbm_buffer_from_buffer(ds_buffer);
-
-    ds_dbg("Destroy tbm buffer(%p)", buffer);
-
-    tbm_surface_destroy(buffer->surface);
-    free(buffer);
-}
-
-static bool
-tbm_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, uint32_t flags,
-        void **data, uint32_t *format, size_t *stride)
-{
-    struct ds_tbm_buffer *buffer;
-    tbm_surface_info_s info;
-    int tbm_access_flags = 0;
-    int ret;
-
-    buffer = tbm_buffer_from_buffer(ds_buffer);
-
-    if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ)
-        tbm_access_flags |= TBM_OPTION_READ;
-    else if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE)
-        tbm_access_flags |= TBM_OPTION_WRITE;
-
-    ret = tbm_surface_map(buffer->surface, tbm_access_flags, &info);
-    if (ret != TBM_SURFACE_ERROR_NONE) {
-        ds_err("Could not map tbm_surface of buffer(%p)", buffer);
-        return false;
-    }
-    
-    *data = info.planes[0].ptr;
-    *format = info.format;
-    *stride = info.planes[0].stride;
-
-    return true;
-}
-
-static void
-tbm_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer)
-{
-    struct ds_tbm_buffer *buffer;
-
-    buffer = tbm_buffer_from_buffer(ds_buffer);
-
-    tbm_surface_unmap(buffer->surface);
-}
-
-static const struct ds_buffer_interface tbm_buffer_iface =
-{
-    .destroy = tbm_buffer_destroy,
-    .begin_data_ptr_access = tbm_buffer_begin_data_ptr_access,
-    .end_data_ptr_access = tbm_buffer_end_data_ptr_access,
-};
-
-static void
-tbm_allocator_destroy(struct ds_allocator *ds_allocator)
-{
-    struct ds_tbm_allocator *alloc;
-
-    alloc = tbm_allocator_from_allocator(ds_allocator);
-
-    ds_inf("Destroy TBM allocator(%p)", alloc);
-
-    tbm_bufmgr_deinit(alloc->bufmgr);
-    free(alloc);
-}
-
-static struct ds_buffer *
-tbm_allocator_create_buffer(struct ds_allocator *ds_allocator,
-        int width, int height, uint32_t format)
-{
-    static int num_buffers = 0;
-    struct ds_tbm_buffer *buffer;
-
-    buffer = calloc(1, sizeof *buffer);
-    if (!buffer)
-        return NULL;
-
-    ds_buffer_init(&buffer->base, &tbm_buffer_iface, width, height);
-
-    buffer->surface = tbm_surface_create(width, height, TBM_FORMAT_XRGB8888);
-
-    ds_dbg("tbm buffer(%p) created: size(%dx%d) number of buffers: %d",
-            buffer, width, height, ++num_buffers);
-
-    return &buffer->base;
-}
-
-static const struct ds_allocator_interface tbm_allocator_iface =
-{
-    .destroy = tbm_allocator_destroy,
-    .create_buffer = tbm_allocator_create_buffer,
-};
index b1fff87b6ce0970b5eb99e7d18f1e347db1e79b3..895ffca8b2055542a60417bd7005b114cd463fa1 100644 (file)
@@ -1,15 +1 @@
-all_backends = ['tdm']
-backends = get_option('backends')
-if 'auto' in backends and get_option('auto_features').enabled()
-  backends = all_backends
-elif 'auto' in backends and get_option('auto_features').disabled()
-  backends = []
-endif
-
-foreach backend : all_backends
-  if backend in backends or 'auto' in backends
-    subdir(backend)
-  endif
-endforeach
-
 subdir('wayland')
diff --git a/src/libds/backend/tdm/backend.c b/src/libds/backend/tdm/backend.c
deleted file mode 100644 (file)
index e756ac1..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-
-#include "libds/log.h"
-
-#include "tdm.h"
-
-static const struct ds_backend_interface tdm_backend_iface;
-
-static void tdm_backend_handle_display_destroy(struct wl_listener *listener,
-        void *data);
-static void tdm_backend_destroy(struct ds_tdm_backend *tdm);
-static int tdm_backend_handle_tdm_event(int fd, uint32_t mask, void *data);
-
-WL_EXPORT struct ds_backend *
-ds_tdm_backend_create(struct wl_display *display)
-{
-    struct ds_tdm_backend *tdm;
-    struct wl_event_loop *loop;
-    tdm_error err;
-
-    ds_inf("Initializing TDM backend");
-
-    tdm = calloc(1, sizeof *tdm);
-    if (!tdm)
-        return NULL;
-
-    ds_backend_init(&tdm->base, &tdm_backend_iface);
-
-    tdm->wl_display = display;
-    tdm->clock = CLOCK_MONOTONIC;   // FIXME
-
-    wl_list_init(&tdm->outputs);
-    wl_list_init(&tdm->buffers);
-
-    tdm->tdm_display = tdm_display_init(&err);
-    if (err != TDM_ERROR_NONE) {
-        ds_err("Could not initialize tdm_display");
-        goto err_display;
-    }
-
-    err = tdm_display_get_fd(tdm->tdm_display, &tdm->fd);
-    if (err != TDM_ERROR_NONE || tdm->fd < 0) {
-        ds_err("Could not get fd from tdm_display: err(%d)", err);
-        goto err_fd;
-    }
-
-    loop = wl_display_get_event_loop(display);
-    tdm->tdm_event = wl_event_loop_add_fd(loop, tdm->fd, WL_EVENT_READABLE,
-            tdm_backend_handle_tdm_event, tdm);
-    if (!tdm->tdm_event) {
-        ds_err("could not add fd event handler for tdm event");
-        goto err_event;
-    }
-
-    tdm->display_destroy.notify = tdm_backend_handle_display_destroy;
-    wl_display_add_destroy_listener(display, &tdm->display_destroy);
-
-    return &tdm->base;
-
-err_event:
-    close(tdm->fd);
-err_fd:
-    tdm_display_deinit(tdm->tdm_display);
-err_display:
-    free(tdm);
-
-    return NULL;
-}
-
-struct ds_tdm_backend *
-tdm_backend_from_backend(struct ds_backend *backend)
-{
-    assert(backend->iface == &tdm_backend_iface);
-    return (struct ds_tdm_backend *)backend;
-}
-
-static void
-tdm_backend_destroy(struct ds_tdm_backend *tdm)
-{
-    struct ds_tdm_output *output, *tmp_output;
-    struct ds_tdm_buffer *buffer, *tmp_buffer;
-
-    wl_list_for_each_safe(output, tmp_output, &tdm->outputs, link)
-        ds_output_destroy(&output->base);
-
-    wl_list_for_each_safe(buffer, tmp_buffer, &tdm->buffers, link)
-        destroy_tdm_buffer(buffer);
-
-    wl_list_remove(&tdm->display_destroy.link);
-    wl_event_source_remove(tdm->tdm_event);
-    close(tdm->fd);
-    tdm_display_deinit(tdm->tdm_display);
-    ds_backend_finish(&tdm->base);
-    free(tdm);
-}
-
-static bool
-tdm_backend_scan_outputs(struct ds_tdm_backend *tdm)
-{
-    struct ds_tdm_output *output;
-    tdm_output *tdm_output;
-    tdm_error err;
-    int num_outputs, i;
-
-    err = tdm_display_get_output_count(tdm->tdm_display, &num_outputs);
-    if (err != TDM_ERROR_NONE) {
-        ds_err("Could not get number of outputs: err(%d)", err);
-        return false;
-    }
-
-    for (i = 0; i < num_outputs; i++) {
-        tdm_output = tdm_display_get_output(tdm->tdm_display, i, &err);
-        if (err != TDM_ERROR_NONE || !tdm_output) {
-            ds_err("Could not get output from tdm_display: index(%d) err(%d)",
-                    i, err);
-            continue;
-        }
-
-        output = create_tdm_output(tdm, tdm_output);
-        if (!output) {
-            ds_err("Could not create output: index(%d)", i);
-            continue;
-        }
-
-        wl_list_insert(&tdm->outputs, &output->link);
-
-        wl_signal_emit(&tdm->base.events.new_output, &output->base);
-    }
-
-    return true;
-}
-
-static bool
-tdm_backend_iface_start(struct ds_backend *backend)
-{
-    struct ds_tdm_backend *tdm;
-
-    tdm = tdm_backend_from_backend(backend);
-    return tdm_backend_scan_outputs(tdm);
-}
-
-static void
-tdm_backend_iface_destroy(struct ds_backend *backend)
-{
-    struct ds_tdm_backend *tdm;
-
-    tdm = tdm_backend_from_backend(backend);
-    tdm_backend_destroy(tdm);
-}
-
-static const struct ds_backend_interface tdm_backend_iface =
-{
-    .start = tdm_backend_iface_start,
-    .destroy = tdm_backend_iface_destroy,
-    .get_drm_fd = NULL,
-};
-
-static void
-tdm_backend_handle_display_destroy(struct wl_listener *listener, void *data)
-{
-    struct ds_tdm_backend *tdm;
-
-    tdm = wl_container_of(listener, tdm, display_destroy);
-    tdm_backend_destroy(tdm);
-}
-
-static int
-tdm_backend_handle_tdm_event(int fd, uint32_t mask, void *data)
-{
-    struct ds_tdm_backend *tdm = data;
-
-    tdm_display_handle_events(tdm->tdm_display);
-
-    return 0;
-}
diff --git a/src/libds/backend/tdm/meson.build b/src/libds/backend/tdm/meson.build
deleted file mode 100644 (file)
index 82eb165..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-msg = ['Required for TDM backend support.']
-if 'tdm' in backends
-  msg += 'Install "libtdm" and "libtbm", or disable the tdm backend'
-endif
-
-libtdm = dependency(
-  'libtdm',
-  required: 'tdm' in backends,
-  not_found_message: '\n'.join(msg)
-)
-
-libtbm = dependency(
-  'libtbm',
-  required: 'tdm' in backends,
-  not_found_message: '\n'.join(msg)
-)
-
-if not libtdm.found() or not libtbm.found()
-  subdir_done()
-endif
-
-libds_files += files(
-  'backend.c',
-  'output.c',
-)
-
-libds_deps += [
-  libtdm,
-  libtbm
-]
-
-features += { 'tdm-backend': true }
diff --git a/src/libds/backend/tdm/output.c b/src/libds/backend/tdm/output.c
deleted file mode 100644 (file)
index 5148853..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-
-#include <tbm_surface.h>
-
-#include "libds/log.h"
-#include "libds/allocator/tbm.h"
-
-#include "tdm.h"
-
-static const struct ds_output_interface tdm_output_iface;
-static bool output_init_modes(struct ds_tdm_output *output);
-static void output_destroy(struct ds_tdm_output *output);
-static void output_init_hwc(struct ds_tdm_output *output);
-static bool output_update_mode(struct ds_tdm_output *output);
-static bool output_set_pending_fb(struct ds_tdm_output *output,
-        struct ds_buffer *ds_buffer);
-static bool output_hwc_commit(struct ds_tdm_output *output);
-
-struct ds_tdm_output *
-create_tdm_output(struct ds_tdm_backend *tdm, tdm_output *tdm_output)
-{
-    struct ds_tdm_output *output;
-    tdm_output_conn_status conn;
-    tdm_error err;
-
-    output = calloc(1, sizeof *output);
-    if (!output)
-        return NULL;
-
-    ds_output_init(&output->base, &tdm->base, &tdm_output_iface,
-            tdm->wl_display);
-
-    output->backend = tdm;
-    output->tdm.output = tdm_output;
-
-    err = tdm_output_get_conn_status(tdm_output, &conn);
-    if (err != TDM_ERROR_NONE) {
-        ds_err("Could not get connection status of tdm output(%p): err(%d)",
-                tdm_output, err);
-        goto err_status;
-    }
-
-    if (conn == TDM_OUTPUT_CONN_STATUS_CONNECTED) {
-        output->status = DS_TDM_OUTPUT_CONNECTED;
-
-        if (!output_init_modes(output)) {
-            ds_err("Could not initialize modes of tdm output(%p)",
-                    tdm_output);
-            goto err_status;
-        }
-    }
-    else if (conn == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) {
-        output->status = DS_TDM_OUTPUT_DISCONNECTED;
-    }
-
-    if (tdm_output_get_hwc(output->tdm.output, NULL) != NULL)
-        output_init_hwc(output);
-
-    ds_inf("TDM output(%p) created: hwc(%p)", output, output->tdm.hwc);
-
-    return output;
-
-err_status:
-    free(output);
-
-    return NULL;
-}
-
-static struct ds_tdm_output *
-tdm_output_from_output(struct ds_output *ds_output)
-{
-    assert(ds_output->iface == &tdm_output_iface);
-    return (struct ds_tdm_output *)ds_output;
-}
-
-static void
-output_iface_destroy(struct ds_output *ds_output)
-{
-    struct ds_tdm_output *output;
-
-    output = tdm_output_from_output(ds_output);
-    output_destroy(output);
-}
-
-void
-destroy_tdm_buffer(struct ds_tdm_buffer *buffer)
-{
-    if (buffer == NULL)
-        return;
-
-    wl_list_remove(&buffer->buffer_destroy.link);
-    wl_list_remove(&buffer->link);
-    free(buffer);
-}
-
-static void
-buffer_handle_buffer_destroy(struct wl_listener *listener, void *data)
-{
-    struct ds_tdm_buffer *buffer;
-
-    buffer = wl_container_of(listener, buffer, buffer_destroy);
-    destroy_tdm_buffer(buffer);
-}
-
-static struct ds_tdm_buffer *
-create_tdm_buffer(struct ds_tdm_backend *backend, struct ds_buffer *ds_buffer)
-{
-    struct ds_tdm_buffer *buffer;
-    tbm_surface_h surface;
-
-    surface = ds_tbm_buffer_get_surface(ds_buffer);
-    if (!surface) {
-        ds_err("Could not get tbm_surface_h");
-        return NULL;
-    }
-
-    buffer = calloc(1, sizeof *buffer);
-    if (!buffer)
-        return NULL;
-
-    buffer->surface = surface;
-    buffer->buffer = ds_buffer_lock(ds_buffer);
-    wl_list_insert(&backend->buffers, &buffer->link);
-
-    buffer->buffer_destroy.notify = buffer_handle_buffer_destroy;
-    ds_buffer_add_destroy_listener(ds_buffer, &buffer->buffer_destroy);
-
-    return buffer;
-}
-
-static struct ds_tdm_buffer *
-get_or_create_tdm_buffer(struct ds_tdm_backend *backend,
-        struct ds_buffer *ds_buffer)
-{
-    struct ds_tdm_buffer *buffer;
-
-    wl_list_for_each(buffer, &backend->buffers, link) {
-        if (buffer->buffer == ds_buffer && buffer->released) {
-            buffer->released = false;
-            ds_buffer_lock(buffer->buffer);
-            return buffer;
-        }
-    }
-
-    return create_tdm_buffer(backend, ds_buffer);
-}
-
-static void
-tdm_buffer_release(struct ds_tdm_buffer *buffer)
-{
-    buffer->released = true;
-    ds_buffer_unlock(buffer->buffer);
-}
-
-static void
-output_update_front_buffer(struct ds_tdm_output *output)
-{
-    if (output->front_buffer)
-        tdm_buffer_release(output->front_buffer);
-    output->front_buffer = output->back_buffer;
-    output->back_buffer = NULL;
-}
-
-static void
-output_attach_back_buffer(struct ds_tdm_output *output,
-        struct ds_tdm_buffer *buffer)
-{
-    if (output->back_buffer)
-        tdm_buffer_release(output->back_buffer);
-    output->back_buffer = buffer;
-}
-
-static bool
-output_iface_commit(struct ds_output *ds_output)
-{
-    struct ds_tdm_output *output;
-
-    output = tdm_output_from_output(ds_output);
-
-    if (ds_output->pending.committed & DS_OUTPUT_STATE_MODE) {
-        if (!output_update_mode(output)) {
-            ds_err("Could not update TDM mode");
-            return false;
-        }
-    }
-
-    if (ds_output->pending.committed & DS_OUTPUT_STATE_BUFFER) {
-        if (!output_set_pending_fb(output, ds_output->pending.buffer))
-            ds_err("Could not update buffer");
-    }
-
-    if (!output_hwc_commit(output)) {
-        ds_err("Could not commit tdm output");
-        if (output->back_buffer) {
-            tdm_buffer_release(output->back_buffer);
-        }
-    }
-
-    return true;
-}
-
-static const struct ds_output_interface tdm_output_iface =
-{
-    .destroy = output_iface_destroy,
-    .commit = output_iface_commit,
-};
-
-static void
-output_destroy(struct ds_tdm_output *output)
-{
-    struct ds_tdm_output_mode *mode, *mode_tmp;
-
-    wl_list_for_each_safe(mode, mode_tmp, &output->base.modes, base.link) {
-        wl_list_remove(&mode->base.link);
-        free(mode);
-    }
-
-    if (output->back_buffer)
-        ds_buffer_unlock(output->back_buffer->buffer);
-
-    if (output->front_buffer)
-        ds_buffer_unlock(output->front_buffer->buffer);
-
-    free(output);
-}
-
-static bool
-output_init_modes(struct ds_tdm_output *output)
-{
-    struct ds_tdm_output_mode *mode;
-    const tdm_output_mode *tdm_modes, *tdm_mode;
-    tdm_error err;
-    int num_modes, i;
-
-    err = tdm_output_get_available_modes(output->tdm.output, &tdm_modes,
-            &num_modes);
-    if (err != TDM_ERROR_NONE) {
-        ds_err("Could not get available modes: output(%p)", output);
-        return false;
-    }
-
-    ds_dbg("Detected modes:");
-
-    for (i = 0; i < num_modes; i++) {
-        tdm_mode = &tdm_modes[i];
-
-        mode = calloc(1, sizeof *mode);
-        if (!mode) {
-            ds_err("Could not allocate memory");
-            continue;
-        }
-
-        mode->tdm_mode = tdm_mode;
-        mode->base.width = tdm_mode->hdisplay;
-        mode->base.height = tdm_mode->vdisplay;
-        mode->base.refresh = (int32_t)tdm_mode->vrefresh; // FIXME
-
-        if (tdm_mode->type & TDM_OUTPUT_MODE_TYPE_PREFERRED)
-            mode->base.preferred = true;
-
-        ds_dbg("  %dx%d@%d %s", mode->base.width, mode->base.height,
-                mode->base.refresh,
-                mode->base.preferred ? "(preferred)" : "");
-
-        if (tdm_mode->type & TDM_OUTPUT_MODE_TYPE_DEFAULT)
-            wl_list_insert(&output->base.modes, &mode->base.link);
-        else
-            wl_list_insert(output->base.modes.prev, &mode->base.link);
-    }
-
-    return true;
-}
-
-static void
-output_init_hwc(struct ds_tdm_output *output)
-{
-    tdm_error err;
-
-    output->tdm.hwc = tdm_output_get_hwc(output->tdm.output, &err);
-    if (err != TDM_ERROR_NONE || !output->tdm.hwc) {
-        ds_err("Could not get tdm_hwc: output(%p)", output);
-        return;
-    }
-}
-
-static bool
-output_update_mode(struct ds_tdm_output *output)
-{
-    const struct ds_tdm_output_mode *mode;
-    tdm_error err;
-
-    mode = (struct ds_tdm_output_mode *)output->base.pending.mode;
-
-    ds_inf("TDM output(%p) set mode %dx%d %d mHz", output,
-            mode->base.width, mode->base.height, mode->base.refresh);
-
-    err = tdm_output_set_mode(output->tdm.output, mode->tdm_mode);
-    if (err != TDM_ERROR_NONE)
-        return false;
-
-    return true;
-}
-
-static bool
-output_set_pending_fb(struct ds_tdm_output *output,
-        struct ds_buffer *ds_buffer)
-{
-    struct ds_tdm_buffer *buffer;
-    tdm_region fb_damage;
-    tdm_error err;
-
-    buffer = get_or_create_tdm_buffer(output->backend, ds_buffer);
-    if (!buffer)
-        return false;
-
-    memset(&fb_damage, 0, sizeof(fb_damage));
-    err = tdm_hwc_set_client_target_buffer(output->tdm.hwc,
-            buffer->surface, fb_damage);
-    if (err != TDM_ERROR_NONE) {
-        ds_err("Could not set hwc client target buffer");
-        ds_buffer_unlock(buffer->buffer);
-        return false;
-    }
-
-    output_attach_back_buffer(output, buffer);
-
-    return true;
-}
-
-static void
-output_hwc_commit_handler(tdm_hwc *hwc, unsigned int sequence,
-        unsigned int tv_sec, unsigned int tv_usec, void *user_data)
-{
-    struct ds_tdm_output *output = user_data;
-
-    output_update_front_buffer(output);
-
-    wl_signal_emit(&output->base.events.frame, &output->base);
-}
-
-static bool
-output_hwc_commit(struct ds_tdm_output *output)
-{
-    tdm_error err;
-    uint32_t num_changes;
-
-    err = tdm_hwc_validate(output->tdm.hwc, NULL, 0, &num_changes);
-    if (err != TDM_ERROR_NONE) {
-        ds_err("Could not hwc validate");
-        return false;
-    }
-
-    err = tdm_hwc_accept_validation(output->tdm.hwc);
-    if (err != TDM_ERROR_NONE) {
-        ds_err("Could not hwc accept validation");
-        return false;
-    }
-
-    err = tdm_hwc_commit(output->tdm.hwc, 0, output_hwc_commit_handler,
-            output);
-    if (err != TDM_ERROR_NONE) {
-        ds_err("Could not hwc commit");
-        return false;
-    }
-
-    return true;
-}
diff --git a/src/libds/backend/tdm/tdm.h b/src/libds/backend/tdm/tdm.h
deleted file mode 100644 (file)
index 1c80ef9..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef DS_BACKEND_TDM_H
-#define DS_BACKEND_TDM_H
-
-#include <time.h>
-
-#include <tdm.h>
-
-#include "libds/interfaces/backend.h"
-#include "libds/interfaces/output.h"
-
-enum ds_tdm_output_status {
-    DS_TDM_OUTPUT_DISCONNECTED,
-    DS_TDM_OUTPUT_CONNECTED,
-};
-
-struct ds_tdm_output_mode {
-    struct ds_output_mode base;
-    const tdm_output_mode *tdm_mode;
-};
-
-struct ds_tdm_backend
-{
-    struct ds_backend base;
-
-    tdm_display *tdm_display;
-    struct wl_display *wl_display;
-    struct wl_event_source *tdm_event;
-
-    struct wl_list outputs; // ds_tdm_output.link
-    struct wl_list buffers; // ds_tdm_buffer.link
-
-    struct wl_listener display_destroy;
-
-    clockid_t clock;
-    int fd;
-};
-
-struct ds_tdm_output
-{
-    struct ds_output base;
-
-    struct ds_tdm_backend *backend;
-    struct ds_tdm_buffer *front_buffer, *back_buffer;
-
-    struct {
-        tdm_output *output;
-        tdm_hwc *hwc;
-    } tdm;
-
-    struct wl_list link;
-
-    enum ds_tdm_output_status status;
-};
-
-struct ds_tdm_buffer
-{
-    struct ds_buffer *buffer;
-    tbm_surface_h surface;
-    struct wl_list link; // ds_wl_backend.buffers
-    struct wl_listener buffer_destroy;
-
-    bool released;
-};
-
-struct ds_tdm_backend *tdm_backend_from_backend(struct ds_backend *backend);
-
-struct ds_tdm_output *create_tdm_output(struct ds_tdm_backend *tdm,
-        tdm_output *tdm_output);
-
-void destroy_tdm_buffer(struct ds_tdm_buffer *buffer);
-
-
-#endif
index ed8c95f9c65ad1e946e95060a4cfaa5dfbac2f0f..50f796227a0fdcd29d6e07813e0d0d414f8c1cbc 100644 (file)
@@ -68,16 +68,10 @@ lib_libds = shared_library('ds', libds_files,
   install: true
 )
 
-ds_vars = {}
-foreach name, have : features
-  ds_vars += { 'have_' + name.underscorify(): have.to_string() }
-endforeach
-
 dep_libds = declare_dependency(
   link_with: lib_libds,
   dependencies: libds_deps,
   include_directories: [ common_inc, include_directories('.') ],
-  variables: ds_vars,
 )
 
 pkgconfig = import('pkgconfig')
@@ -86,5 +80,4 @@ pkgconfig.generate(lib_libds,
   filebase: meson.project_name(),
   name: meson.project_name(),
   description: 'Wayland compositor library',
-  variables: ds_vars,
 )
index 774c7ebb92409f981796fbc896814da6af681a74..d739bfe863e50f3a4a4cfa0b4be8179b777c003f 100644 (file)
@@ -11,6 +11,9 @@ wayland_scanner = find_program(
 )
 
 subdir('libds')
+if get_option('tizen')
+  subdir('libds-tizen')
+endif
 subdir('tests')
 subdir('examples')
 subdir('clients')