move source files to src/libtdm-exynos/ 47/252847/1
authorSooChan Lim <sc1.lim@samsung.com>
Wed, 3 Feb 2021 00:36:37 +0000 (09:36 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Wed, 3 Feb 2021 00:36:37 +0000 (09:36 +0900)
Change-Id: I98c9bb0b4752bb892aba9a9c70d67961abf6d311

49 files changed:
configure.ac
src/Makefile.am
src/libtdm-exynos/Makefile.am [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos.c [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos.h [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_capture.c [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_capture.h [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_capture_legacy.c [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_capture_legacy.h [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_display.c [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_display.h [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_format.c [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_format.h [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_hwc.c [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_hwc.h [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_hwc_window.c [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_hwc_window.h [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_layer.c [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_layer.h [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_output.c [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_output.h [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_pp.c [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_pp.h [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_pp_legacy.c [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_pp_legacy.h [new file with mode: 0644]
src/libtdm-exynos/tdm_exynos_types.h [new file with mode: 0644]
src/tdm_exynos.c [deleted file]
src/tdm_exynos.h [deleted file]
src/tdm_exynos_capture.c [deleted file]
src/tdm_exynos_capture.h [deleted file]
src/tdm_exynos_capture_legacy.c [deleted file]
src/tdm_exynos_capture_legacy.h [deleted file]
src/tdm_exynos_display.c [deleted file]
src/tdm_exynos_display.h [deleted file]
src/tdm_exynos_format.c [deleted file]
src/tdm_exynos_format.h [deleted file]
src/tdm_exynos_hwc.c [deleted file]
src/tdm_exynos_hwc.h [deleted file]
src/tdm_exynos_hwc_window.c [deleted file]
src/tdm_exynos_hwc_window.h [deleted file]
src/tdm_exynos_layer.c [deleted file]
src/tdm_exynos_layer.h [deleted file]
src/tdm_exynos_output.c [deleted file]
src/tdm_exynos_output.h [deleted file]
src/tdm_exynos_pp.c [deleted file]
src/tdm_exynos_pp.h [deleted file]
src/tdm_exynos_pp_legacy.c [deleted file]
src/tdm_exynos_pp_legacy.h [deleted file]
src/tdm_exynos_types.h [deleted file]

index 047439bd6b0122c40aaf24b97359d96a4c8cdd16..b6c610f54947e7308f66166946997c1c89b76f2e 100644 (file)
@@ -51,6 +51,7 @@ AC_SUBST(TDM_MODULE_PATH)
 # For enumerating devices in test case
 AC_OUTPUT([
        Makefile
+       src/libtdm-exynos/Makefile
        src/Makefile])
 
 echo ""
index 4199097a0003801cb4c82010e347e78b0359a9a4..00c6f31bb049c9dbdf63f51451bbae23fd74d49d 100644 (file)
@@ -1,21 +1 @@
-AM_CFLAGS = \
-       $(TDM_EXYNOS_CFLAGS) \
-       -I$(top_srcdir)/src
-
-libtdm_exynos_la_LTLIBRARIES = libtdm-exynos.la
-libtdm_exynos_ladir = $(TDM_MODULE_PATH)
-libtdm_exynos_la_LDFLAGS = -module -avoid-version
-libtdm_exynos_la_LIBADD = $(TDM_EXYNOS_LIBS) -ldl
-
-libtdm_exynos_la_SOURCES = \
-       tdm_exynos_format.c \
-       tdm_exynos_display.c \
-       tdm_exynos_output.c \
-       tdm_exynos_layer.c \
-       tdm_exynos_hwc_window.c \
-       tdm_exynos_hwc.c \
-       tdm_exynos_pp.c \
-       tdm_exynos_capture.c \
-       tdm_exynos_pp_legacy.c \
-       tdm_exynos_capture_legacy.c \
-       tdm_exynos.c
+SUBDIRS = libtdm-exynos 
diff --git a/src/libtdm-exynos/Makefile.am b/src/libtdm-exynos/Makefile.am
new file mode 100644 (file)
index 0000000..4199097
--- /dev/null
@@ -0,0 +1,21 @@
+AM_CFLAGS = \
+       $(TDM_EXYNOS_CFLAGS) \
+       -I$(top_srcdir)/src
+
+libtdm_exynos_la_LTLIBRARIES = libtdm-exynos.la
+libtdm_exynos_ladir = $(TDM_MODULE_PATH)
+libtdm_exynos_la_LDFLAGS = -module -avoid-version
+libtdm_exynos_la_LIBADD = $(TDM_EXYNOS_LIBS) -ldl
+
+libtdm_exynos_la_SOURCES = \
+       tdm_exynos_format.c \
+       tdm_exynos_display.c \
+       tdm_exynos_output.c \
+       tdm_exynos_layer.c \
+       tdm_exynos_hwc_window.c \
+       tdm_exynos_hwc.c \
+       tdm_exynos_pp.c \
+       tdm_exynos_capture.c \
+       tdm_exynos_pp_legacy.c \
+       tdm_exynos_capture_legacy.c \
+       tdm_exynos.c
diff --git a/src/libtdm-exynos/tdm_exynos.c b/src/libtdm-exynos/tdm_exynos.c
new file mode 100644 (file)
index 0000000..67f87ac
--- /dev/null
@@ -0,0 +1,546 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if HAVE_UDEV
+#include <libudev.h>
+#endif
+
+#include "tdm_exynos.h"
+#include <tdm_helper.h>
+#include <tbm_drm_helper.h>
+
+#define EXYNOS_DRM_NAME "exynos"
+
+static tdm_exynos_data *exynos_data;
+unsigned int exynos_screen_prerotation_hint;
+
+#ifdef HAVE_UDEV
+static tdm_error
+_tdm_exynos_udev_fd_handler(int fd, tdm_event_loop_mask mask, void *user_data)
+{
+       tdm_exynos_data *edata = (tdm_exynos_data*)user_data;
+       struct udev_device *dev;
+       const char *hotplug;
+       struct stat s;
+       dev_t udev_devnum;
+       int ret;
+
+       dev = udev_monitor_receive_device(edata->uevent_monitor);
+       if (!dev) {
+               TDM_ERR("couldn't receive device");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       udev_devnum = udev_device_get_devnum(dev);
+
+       ret = fstat(edata->drm_fd, &s);
+       if (ret == -1) {
+               TDM_ERR("fstat failed");
+               udev_device_unref(dev);
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       hotplug = udev_device_get_property_value(dev, "HOTPLUG");
+
+       if (memcmp(&s.st_rdev, &udev_devnum, sizeof(dev_t)) == 0 &&
+                          hotplug && atoi(hotplug) == 1) {
+               TDM_INFO("HotPlug");
+               tdm_exynos_display_update_output_status(edata);
+       }
+
+       udev_device_unref(dev);
+
+       return TDM_ERROR_NONE;
+}
+
+static void
+_tdm_exynos_udev_init(tdm_exynos_data *edata)
+{
+       struct udev *u = NULL;
+       struct udev_monitor *mon = NULL;
+
+       u = udev_new();
+       if (!u) {
+               TDM_ERR("couldn't create udev");
+               goto failed;
+       }
+
+       mon = udev_monitor_new_from_netlink(u, "udev");
+       if (!mon) {
+               TDM_ERR("couldn't create udev monitor");
+               goto failed;
+       }
+
+       if (udev_monitor_filter_add_match_subsystem_devtype(mon, "drm", "drm_minor") > 0 ||
+           udev_monitor_enable_receiving(mon) < 0) {
+               TDM_ERR("add match subsystem failed");
+               goto failed;
+       }
+
+       edata->uevent_source =
+               tdm_event_loop_add_fd_handler(edata->dpy, udev_monitor_get_fd(mon),
+                                                                         TDM_EVENT_LOOP_READABLE,
+                                                                         _tdm_exynos_udev_fd_handler,
+                                                                         edata, NULL);
+       if (!edata->uevent_source) {
+               TDM_ERR("couldn't create udev event source");
+               goto failed;
+       }
+
+       edata->uevent_monitor = mon;
+
+       TDM_INFO("hotplug monitor created");
+
+       return;
+failed:
+       if (mon)
+               udev_monitor_unref(mon);
+       if (u)
+               udev_unref(u);
+}
+
+static void
+_tdm_exynos_udev_deinit(tdm_exynos_data *edata)
+{
+       if (edata->uevent_source) {
+               tdm_event_loop_source_remove(edata->uevent_source);
+               edata->uevent_source = NULL;
+       }
+
+       if (edata->uevent_monitor) {
+               struct udev *u = udev_monitor_get_udev(edata->uevent_monitor);
+               udev_monitor_unref(edata->uevent_monitor);
+               udev_unref(u);
+               edata->uevent_monitor = NULL;
+               TDM_INFO("hotplug monitor destroyed");
+       }
+}
+#endif
+
+static int
+_tdm_exynos_open_drm(void)
+{
+       int fd = -1;
+
+       fd = drmOpen(EXYNOS_DRM_NAME, NULL);
+       if (fd < 0)
+               TDM_ERR("Cannot open '%s' drm", EXYNOS_DRM_NAME);
+
+#ifdef HAVE_UDEV
+       if (fd < 0) {
+               struct udev *udev;
+               struct udev_enumerate *e;
+               struct udev_list_entry *entry;
+               struct udev_device *device, *drm_device, *device_parent;
+               const char *filename;
+
+               TDM_WRN("Cannot open drm device.. search by udev");
+               udev = udev_new();
+               if (!udev) {
+                       TDM_ERR("fail to initialize udev context\n");
+                       goto close_l;
+               }
+
+               /* Will try to find sys path /exynos-drm/drm/card0 */
+               e = udev_enumerate_new(udev);
+               udev_enumerate_add_match_subsystem(e, "drm");
+               udev_enumerate_add_match_sysname(e, "card[0-9]*");
+               udev_enumerate_scan_devices(e);
+
+               drm_device = NULL;
+               udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
+                       device = udev_device_new_from_syspath(udev_enumerate_get_udev(e),
+                                                                                                 udev_list_entry_get_name(entry));
+                       device_parent = udev_device_get_parent(device);
+                       /* Not need unref device_parent. device_parent and device have same refcnt */
+                       if (device_parent) {
+                               if (strcmp(udev_device_get_sysname(device_parent), "exynos-drm") == 0) {
+                                       drm_device = device;
+                                       TDM_DBG("Found drm device: '%s' (%s)\n",
+                                                       udev_device_get_syspath(drm_device),
+                                                       udev_device_get_sysname(device_parent));
+                                       break;
+                               }
+                       }
+                       udev_device_unref(device);
+               }
+
+               if (drm_device == NULL) {
+                       TDM_ERR("fail to find drm device\n");
+                       udev_enumerate_unref(e);
+                       udev_unref(udev);
+                       goto close_l;
+               }
+
+               filename = udev_device_get_devnode(drm_device);
+
+               fd = open(filename, O_RDWR | O_CLOEXEC);
+               if (fd < 0)
+                       TDM_ERR("Cannot open drm device(%s)\n", filename);
+               udev_device_unref(drm_device);
+               udev_enumerate_unref(e);
+               udev_unref(udev);
+       }
+close_l:
+#endif
+       return fd;
+}
+
+static int
+_tdm_exynos_drm_user_handler_legacy(struct drm_event *event)
+{
+       struct drm_exynos_ipp_event *ipp;
+
+       if (event->type != DRM_EXYNOS_IPP_EVENT)
+               return -1;
+
+       TDM_DBG("got ipp event");
+
+       ipp = (struct drm_exynos_ipp_event *)event;
+
+       if (tdm_exynos_capture_legacy_find_prop_id(ipp->prop_id))
+               tdm_exynos_capture_legacy_stream_pp_handler(ipp->prop_id, ipp->buf_id, ipp->tv_sec, ipp->tv_usec,
+                                                                                        (void *)(unsigned long)ipp->user_data);
+       else
+               tdm_exynos_pp_legacy_handler(ipp->prop_id, ipp->buf_id, ipp->tv_sec, ipp->tv_usec,
+                                                         (void *)(unsigned long)ipp->user_data);
+
+       return 0;
+}
+
+static int
+_tdm_exynos_drm_user_handler(struct drm_event *event)
+{
+       struct drm_exynos_ipp2_event *ipp;
+
+       if (event->type != DRM_EXYNOS_IPP2_EVENT)
+               return -1;
+
+       ipp = (struct drm_exynos_ipp2_event *)event;
+
+       tdm_exynos_pp_handler(ipp->tv_sec, ipp->tv_usec, (void *)(unsigned long)ipp->user_data);
+
+       return 0;
+}
+
+void
+tdm_exynos_deinit(tdm_backend_data *bdata)
+{
+       if (exynos_data != bdata)
+               return;
+
+       TDM_INFO("deinit");
+
+#ifdef HAVE_UDEV
+       _tdm_exynos_udev_deinit(exynos_data);
+#endif
+
+       if (exynos_data->use_ippv2)
+               drmRemoveUserHandler(exynos_data->drm_fd, _tdm_exynos_drm_user_handler);
+       else
+               drmRemoveUserHandler(exynos_data->drm_fd, _tdm_exynos_drm_user_handler_legacy);
+
+       tdm_exynos_display_destroy_output_list(exynos_data);
+
+       if (exynos_data->plane_res)
+               drmModeFreePlaneResources(exynos_data->plane_res);
+       if (exynos_data->mode_res)
+               drmModeFreeResources(exynos_data->mode_res);
+       if (exynos_data->drm_fd >= 0)
+               close(exynos_data->drm_fd);
+
+       free(exynos_data);
+       exynos_data = NULL;
+}
+
+tdm_backend_data *
+tdm_exynos_init(tdm_display *dpy, tdm_error *error)
+{
+       tdm_func_display exynos_func_display;
+       tdm_func_output exynos_func_output;
+       tdm_func_layer exynos_func_layer;
+       tdm_func_hwc exynos_func_hwc;
+       tdm_func_hwc_window exynos_func_hwc_window;
+       tdm_func_pp exynos_func_pp;
+       tdm_func_capture exynos_func_capture;
+       tdm_error ret;
+       const char *value;
+       drmVersionPtr drm_version;
+
+       value = (const char*)getenv("SCREEN_PREROTATION_HINT");
+       if (value) {
+               char *end;
+               exynos_screen_prerotation_hint = strtol(value, &end, 10);
+               TDM_INFO("SCREEN_PREROTATION_HINT = %d", exynos_screen_prerotation_hint);
+       }
+
+       if (!dpy) {
+               TDM_ERR("display is null");
+               if (error)
+                       *error = TDM_ERROR_INVALID_PARAMETER;
+               return NULL;
+       }
+
+       if (exynos_data) {
+               TDM_ERR("failed: init twice");
+               if (error)
+                       *error = TDM_ERROR_BAD_REQUEST;
+               return NULL;
+       }
+
+       exynos_data = calloc(1, sizeof(tdm_exynos_data));
+       if (!exynos_data) {
+               TDM_ERR("alloc failed");
+               if (error)
+                       *error = TDM_ERROR_OUT_OF_MEMORY;
+               return NULL;
+       }
+
+       exynos_data->dpy = dpy;
+
+       /* The drm master fd can be opened by a tbm backend module in
+        * tbm_bufmgr_init() time. In this case, we just get it from tbm.
+        */
+       exynos_data->drm_fd = tbm_drm_helper_get_master_fd();
+       if (exynos_data->drm_fd < 0) {
+               exynos_data->drm_fd = _tdm_exynos_open_drm();
+
+               if (exynos_data->drm_fd < 0) {
+                       ret = TDM_ERROR_OPERATION_FAILED;
+                       goto failed;
+               }
+
+               tbm_drm_helper_set_tbm_master_fd(exynos_data->drm_fd);
+       }
+
+       TDM_INFO("master fd(%d)", exynos_data->drm_fd);
+
+#ifdef HAVE_UDEV
+       _tdm_exynos_udev_init(exynos_data);
+#endif
+
+       drm_version = drmGetVersion(exynos_data->drm_fd);
+       if (!drm_version) {
+               TDM_ERR("no drm version: %m");
+               ret = TDM_ERROR_OPERATION_FAILED;
+               goto failed;
+       } else {
+               TDM_INFO("drm version: %d.%d.%d",
+                                drm_version->version_major,
+                                drm_version->version_minor,
+                                drm_version->version_patchlevel);
+               if (drm_version->version_major > 1 ||
+                       (drm_version->version_major == 1 && drm_version->version_minor >= 1))
+                       exynos_data->use_ippv2 = 1;
+               drmFreeVersion(drm_version);
+       }
+
+       value = getenv("TDM_HWC");
+       if (value)
+               exynos_data->hwc_mode = strtol(value, NULL, 10);
+
+       LIST_INITHEAD(&exynos_data->output_list);
+       LIST_INITHEAD(&exynos_data->buffer_list);
+
+       memset(&exynos_func_display, 0, sizeof(exynos_func_display));
+       exynos_func_display.display_get_capability = exynos_display_get_capability;
+       exynos_func_display.display_get_pp_capability = exynos_display_get_pp_capability;
+       exynos_func_display.display_get_capture_capability = exynos_display_get_capture_capability;
+       exynos_func_display.display_get_outputs = exynos_display_get_outputs;
+       exynos_func_display.display_get_fd = exynos_display_get_fd;
+       exynos_func_display.display_handle_events = exynos_display_handle_events;
+       exynos_func_display.display_create_pp = exynos_display_create_pp;
+
+       memset(&exynos_func_output, 0, sizeof(exynos_func_output));
+       exynos_func_output.output_get_capability = exynos_output_get_capability;
+       exynos_func_output.output_get_layers = exynos_output_get_layers;
+       exynos_func_output.output_set_property = exynos_output_set_property;
+       exynos_func_output.output_get_property = exynos_output_get_property;
+       exynos_func_output.output_wait_vblank = exynos_output_wait_vblank;
+       exynos_func_output.output_set_vblank_handler = exynos_output_set_vblank_handler;
+       exynos_func_output.output_commit = exynos_output_commit;
+       exynos_func_output.output_set_commit_handler = exynos_output_set_commit_handler;
+       exynos_func_output.output_set_dpms = exynos_output_set_dpms;
+       exynos_func_output.output_get_dpms = exynos_output_get_dpms;
+       exynos_func_output.output_set_mode = exynos_output_set_mode;
+       exynos_func_output.output_get_mode = exynos_output_get_mode;
+       exynos_func_output.output_create_capture = exynos_output_create_capture;
+#ifdef HAVE_UDEV
+       exynos_func_output.output_set_status_handler = exynos_output_set_status_handler;
+#endif
+       if (exynos_data->hwc_mode) {
+               exynos_func_output.output_get_hwc = exynos_output_get_hwc;
+
+               memset(&exynos_func_hwc, 0, sizeof(exynos_func_hwc));
+               exynos_func_hwc.hwc_create_window = exynos_hwc_create_window;
+               exynos_func_hwc.hwc_get_video_supported_formats = exynos_hwc_get_video_supported_formats;
+               exynos_func_hwc.hwc_get_capabilities = exynos_hwc_get_capabilities;
+               exynos_func_hwc.hwc_get_available_properties = exynos_hwc_get_available_properties;
+               exynos_func_hwc.hwc_get_client_target_buffer_queue = exynos_hwc_get_client_target_buffer_queue;
+               exynos_func_hwc.hwc_set_client_target_buffer = exynos_hwc_set_client_target_buffer;
+               exynos_func_hwc.hwc_validate = exynos_hwc_validate;
+               exynos_func_hwc.hwc_get_changed_composition_types = exynos_hwc_get_changed_composition_types;
+               exynos_func_hwc.hwc_accept_validation  = exynos_hwc_accept_validation;
+               exynos_func_hwc.hwc_commit = exynos_hwc_commit;
+               exynos_func_hwc.hwc_set_commit_handler = exynos_hwc_set_commit_handler;
+
+               memset(&exynos_func_hwc_window, 0, sizeof(exynos_func_hwc_window));
+               exynos_func_hwc_window.hwc_window_destroy = exynos_hwc_window_destroy;
+               exynos_func_hwc_window.hwc_window_acquire_buffer_queue = NULL;
+               exynos_func_hwc_window.hwc_window_release_buffer_queue = NULL;
+               exynos_func_hwc_window.hwc_window_set_composition_type = exynos_hwc_window_set_composition_type;
+               exynos_func_hwc_window.hwc_window_set_buffer_damage = exynos_hwc_window_set_buffer_damage;
+               exynos_func_hwc_window.hwc_window_set_info = exynos_hwc_window_set_info;
+               exynos_func_hwc_window.hwc_window_set_buffer = exynos_hwc_window_set_buffer;
+               exynos_func_hwc_window.hwc_window_set_property = exynos_hwc_window_set_property;
+               exynos_func_hwc_window.hwc_window_get_property = exynos_hwc_window_get_property;
+               exynos_func_hwc_window.hwc_window_get_constraints = exynos_hwc_window_get_constraints;
+       }
+
+       memset(&exynos_func_layer, 0, sizeof(exynos_func_layer));
+       exynos_func_layer.layer_get_capability = exynos_layer_get_capability;
+       exynos_func_layer.layer_set_property = exynos_layer_set_property;
+       exynos_func_layer.layer_get_property = exynos_layer_get_property;
+       exynos_func_layer.layer_set_info = exynos_layer_set_info;
+       exynos_func_layer.layer_get_info = exynos_layer_get_info;
+       exynos_func_layer.layer_set_buffer = exynos_layer_set_buffer;
+       exynos_func_layer.layer_unset_buffer = exynos_layer_unset_buffer;
+
+       memset(&exynos_func_pp, 0, sizeof(exynos_func_pp));
+       if (exynos_data->use_ippv2) {
+               exynos_func_pp.pp_destroy = exynos_pp_destroy;
+               exynos_func_pp.pp_set_info = exynos_pp_set_info;
+               exynos_func_pp.pp_attach = exynos_pp_attach;
+               exynos_func_pp.pp_commit = exynos_pp_commit;
+               exynos_func_pp.pp_set_done_handler = exynos_pp_set_done_handler;
+       } else {
+               exynos_func_pp.pp_destroy = exynos_pp_legacy_destroy;
+               exynos_func_pp.pp_set_info = exynos_pp_legacy_set_info;
+               exynos_func_pp.pp_attach = exynos_pp_legacy_attach;
+               exynos_func_pp.pp_commit = exynos_pp_legacy_commit;
+               exynos_func_pp.pp_set_done_handler = exynos_pp_legacy_set_done_handler;
+       }
+
+       memset(&exynos_func_capture, 0, sizeof(exynos_func_capture));
+       if (exynos_data->use_ippv2) {
+               exynos_func_capture.capture_destroy = exynos_capture_destroy;
+               exynos_func_capture.capture_set_info = exynos_capture_set_info;
+               exynos_func_capture.capture_attach = exynos_capture_attach;
+               exynos_func_capture.capture_commit = exynos_capture_commit;
+               exynos_func_capture.capture_set_done_handler = exynos_capture_set_done_handler;
+       } else {
+               exynos_func_capture.capture_destroy = exynos_capture_legacy_destroy;
+               exynos_func_capture.capture_set_info = exynos_capture_legacy_set_info;
+               exynos_func_capture.capture_attach = exynos_capture_legacy_attach;
+               exynos_func_capture.capture_commit = exynos_capture_legacy_commit;
+               exynos_func_capture.capture_set_done_handler = exynos_capture_legacy_set_done_handler;
+       }
+
+       ret = tdm_backend_register_func_display(dpy, &exynos_func_display);
+       if (ret != TDM_ERROR_NONE)
+               goto failed;
+
+       ret = tdm_backend_register_func_output(dpy, &exynos_func_output);
+       if (ret != TDM_ERROR_NONE)
+               goto failed;
+
+       ret = tdm_backend_register_func_layer(dpy, &exynos_func_layer);
+       if (ret != TDM_ERROR_NONE)
+               goto failed;
+
+       if (exynos_data->hwc_mode) {
+               ret = tdm_backend_register_func_hwc(dpy, &exynos_func_hwc);
+               if (ret != TDM_ERROR_NONE)
+                       goto failed;
+
+               ret = tdm_backend_register_func_hwc_window(dpy, &exynos_func_hwc_window);
+               if (ret != TDM_ERROR_NONE)
+                       goto failed;
+       }
+
+       ret = tdm_backend_register_func_pp(dpy, &exynos_func_pp);
+       if (ret != TDM_ERROR_NONE)
+               goto failed;
+
+       ret = tdm_backend_register_func_capture(dpy, &exynos_func_capture);
+       if (ret != TDM_ERROR_NONE)
+               goto failed;
+
+       if (exynos_data->use_ippv2)
+               drmAddUserHandler(exynos_data->drm_fd, _tdm_exynos_drm_user_handler);
+       else
+               drmAddUserHandler(exynos_data->drm_fd, _tdm_exynos_drm_user_handler_legacy);
+
+       if (drmSetClientCap(exynos_data->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) < 0)
+               TDM_WRN("Set DRM_CLIENT_CAP_UNIVERSAL_PLANES failed");
+
+       exynos_data->mode_res = drmModeGetResources(exynos_data->drm_fd);
+       if (!exynos_data->mode_res) {
+               TDM_ERR("no drm resource: %m");
+               ret = TDM_ERROR_OPERATION_FAILED;
+               goto failed;
+       }
+
+       exynos_data->plane_res = drmModeGetPlaneResources(exynos_data->drm_fd);
+       if (!exynos_data->plane_res) {
+               TDM_ERR("no drm plane resource: %m");
+               ret = TDM_ERROR_OPERATION_FAILED;
+               goto failed;
+       }
+
+       if (exynos_data->plane_res->count_planes <= 0) {
+               TDM_ERR("no drm plane resource");
+               ret = TDM_ERROR_OPERATION_FAILED;
+               goto failed;
+       }
+
+       ret = tdm_exynos_display_get_property(exynos_data,
+                                                                                 exynos_data->plane_res->planes[0],
+                                                                                 DRM_MODE_OBJECT_PLANE, "zpos", NULL,
+                                                                                 &exynos_data->is_immutable_zpos);
+       if (ret == TDM_ERROR_NONE) {
+               exynos_data->has_zpos_info = 1;
+               if (exynos_data->is_immutable_zpos)
+                       TDM_DBG("plane has immutable zpos info");
+       } else
+               TDM_DBG("plane doesn't have zpos info");
+
+       if (exynos_data->use_ippv2)
+               ret = tdm_exynos_pp_init(exynos_data);
+
+       if (ret != TDM_ERROR_NONE)
+               goto failed;
+
+       ret = tdm_exynos_display_create_output_list(exynos_data);
+       if (ret != TDM_ERROR_NONE)
+               goto failed;
+
+       ret = tdm_exynos_display_create_layer_list(exynos_data);
+       if (ret != TDM_ERROR_NONE)
+               goto failed;
+
+       if (error)
+               *error = TDM_ERROR_NONE;
+
+       TDM_INFO("init success!");
+
+       return (tdm_backend_data *)exynos_data;
+failed:
+       if (error)
+               *error = ret;
+
+       tdm_exynos_deinit(exynos_data);
+
+       TDM_ERR("init failed!");
+       return NULL;
+}
+
+tdm_backend_module tdm_backend_module_data = {
+       "exynos",
+       "Samsung",
+       TDM_BACKEND_SET_ABI_VERSION(2, 0),
+       tdm_exynos_init,
+       tdm_exynos_deinit
+};
+
diff --git a/src/libtdm-exynos/tdm_exynos.h b/src/libtdm-exynos/tdm_exynos.h
new file mode 100644 (file)
index 0000000..97ca58e
--- /dev/null
@@ -0,0 +1,115 @@
+#ifndef _TDM_EXYNOS_H_
+#define _TDM_EXYNOS_H_
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+#include <exynos_drm.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+#include <tbm_surface_queue.h>
+#include <tdm_backend.h>
+#include <tdm_log.h>
+#include <tdm_list.h>
+#include <tdm_helper.h>
+
+#include "tdm_exynos_types.h"
+#include "tdm_exynos_format.h"
+#include "tdm_exynos_display.h"
+#include "tdm_exynos_output.h"
+#include "tdm_exynos_layer.h"
+#include "tdm_exynos_hwc.h"
+#include "tdm_exynos_hwc_window.h"
+#include "tdm_exynos_pp_legacy.h"
+#include "tdm_exynos_capture_legacy.h"
+#include "tdm_exynos_pp.h"
+#include "tdm_exynos_capture.h"
+
+extern unsigned int exynos_screen_prerotation_hint;
+
+/* exynos backend functions */
+tdm_error    exynos_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps);
+tdm_error    exynos_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps);
+tdm_error    exynos_display_get_capture_capability(tdm_backend_data *bdata, tdm_caps_capture *caps);
+tdm_output** exynos_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error);
+tdm_error    exynos_display_get_fd(tdm_backend_data *bdata, int *fd);
+tdm_error    exynos_display_handle_events(tdm_backend_data *bdata);
+tdm_pp*      exynos_display_create_pp(tdm_backend_data *bdata, tdm_error *error);
+tdm_error    exynos_output_get_capability(tdm_output *output, tdm_caps_output *caps);
+tdm_layer**  exynos_output_get_layers(tdm_output *output, int *count, tdm_error *error);
+tdm_error    exynos_output_set_property(tdm_output *output, unsigned int id, tdm_value value);
+tdm_error    exynos_output_get_property(tdm_output *output, unsigned int id, tdm_value *value);
+tdm_error    exynos_output_wait_vblank(tdm_output *output, int interval, int sync, void *user_data);
+tdm_error    exynos_output_set_vblank_handler(tdm_output *output, tdm_output_vblank_handler func);
+tdm_error    exynos_output_commit(tdm_output *output, int sync, void *user_data);
+tdm_error    exynos_output_set_commit_handler(tdm_output *output, tdm_output_commit_handler func);
+tdm_error    exynos_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value);
+tdm_error    exynos_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value);
+tdm_error    exynos_output_set_mode(tdm_output *output, const tdm_output_mode *mode);
+tdm_error    exynos_output_get_mode(tdm_output *output, const tdm_output_mode **mode);
+tdm_capture* exynos_output_create_capture(tdm_output *output, tdm_error *error);
+tdm_error    exynos_output_set_status_handler(tdm_output *output, tdm_output_status_handler func, void *user_data);
+tdm_hwc     *exynos_output_get_hwc(tdm_output *output, tdm_error *error);
+tdm_error    exynos_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps);
+tdm_error    exynos_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value);
+tdm_error    exynos_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value);
+tdm_error    exynos_layer_set_info(tdm_layer *layer, tdm_info_layer *info);
+tdm_error    exynos_layer_get_info(tdm_layer *layer, tdm_info_layer *info);
+tdm_error    exynos_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer);
+tdm_error    exynos_layer_unset_buffer(tdm_layer *layer);
+
+tdm_hwc_window      *exynos_hwc_create_window(tdm_hwc *hwc, tdm_error *error);
+tdm_error            exynos_hwc_get_video_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count);
+tdm_error            exynos_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *capabilities);
+tdm_error            exynos_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count);
+tbm_surface_queue_h  exynos_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error);
+tdm_error            exynos_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage);
+tdm_error            exynos_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types);
+tdm_error            exynos_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements, tdm_hwc_window **hwc_wnds, tdm_hwc_window_composition *composition_types);
+tdm_error            exynos_hwc_accept_validation(tdm_hwc *hwc);
+tdm_error            exynos_hwc_commit(tdm_hwc *hwc, int sync, void *user_data);
+tdm_error            exynos_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func);
+
+void           exynos_hwc_window_destroy(tdm_hwc_window *hwc_window);
+tdm_error      exynos_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, tdm_hwc_window_composition composition_type);
+tdm_error      exynos_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage);
+tdm_error      exynos_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info);
+tdm_error      exynos_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface);
+tdm_error      exynos_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value);
+tdm_error      exynos_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value);
+tdm_error      exynos_hwc_window_get_constraints(tdm_hwc_window *hwc_window, int *constraints);
+
+void         exynos_pp_legacy_destroy(tdm_pp *pp);
+tdm_error    exynos_pp_legacy_set_info(tdm_pp *pp, tdm_info_pp *info);
+tdm_error    exynos_pp_legacy_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst);
+tdm_error    exynos_pp_legacy_commit(tdm_pp *pp);
+tdm_error    exynos_pp_legacy_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func, void *user_data);
+void         exynos_capture_legacy_destroy(tdm_capture *capture);
+tdm_error    exynos_capture_legacy_set_info(tdm_capture *capture, tdm_info_capture *info);
+tdm_error    exynos_capture_legacy_attach(tdm_capture *capture, tbm_surface_h buffer);
+tdm_error    exynos_capture_legacy_commit(tdm_capture *capture);
+tdm_error    exynos_capture_legacy_set_done_handler(tdm_pp *pp, tdm_capture_done_handler func, void *user_data);
+
+void         exynos_pp_destroy(tdm_pp *pp);
+tdm_error    exynos_pp_set_info(tdm_pp *pp, tdm_info_pp *info);
+tdm_error    exynos_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst);
+tdm_error    exynos_pp_commit(tdm_pp *pp);
+tdm_error    exynos_pp_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func, void *user_data);
+void         exynos_capture_destroy(tdm_capture *capture);
+tdm_error    exynos_capture_set_info(tdm_capture *capture, tdm_info_capture *info);
+tdm_error    exynos_capture_attach(tdm_capture *capture, tbm_surface_h buffer);
+tdm_error    exynos_capture_commit(tdm_capture *capture);
+tdm_error    exynos_capture_set_done_handler(tdm_pp *pp, tdm_capture_done_handler func, void *user_data);
+
+#endif /* _TDM_EXYNOS_H_ */
diff --git a/src/libtdm-exynos/tdm_exynos_capture.c b/src/libtdm-exynos/tdm_exynos_capture.c
new file mode 100644 (file)
index 0000000..74eb457
--- /dev/null
@@ -0,0 +1,454 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_exynos.h"
+
+typedef struct _tdm_exynos_capture_buffer {
+       int index;
+       tbm_surface_h ui_buffer;
+       tbm_surface_h buffer;
+       struct list_head link;
+} tdm_exynos_capture_buffer;
+
+typedef struct _tdm_exynos_pp_data {
+       tdm_exynos_data *exynos_data;
+
+       tdm_exynos_output_data *output_data;
+
+       tdm_info_capture info;
+       int info_changed;
+
+       struct list_head pending_buffer_list;
+       struct list_head buffer_list;
+
+       struct {
+               tdm_event_loop_source *timer_source;
+
+               int startd;
+               int first_event;
+       } stream;
+
+       tdm_capture_done_handler done_func;
+       void *done_user_data;
+
+       struct list_head link;
+} tdm_exynos_capture_data;
+
+static tbm_format capture_formats[] = {
+       TBM_FORMAT_ARGB8888,
+       TBM_FORMAT_XRGB8888,
+};
+
+#define NUM_CAPTURE_FORMAT   (sizeof(capture_formats) / sizeof(capture_formats[0]))
+
+static int capture_list_init;
+static struct list_head capture_list;
+
+static int
+_get_index(tdm_exynos_capture_data *capture_data)
+{
+       tdm_exynos_capture_buffer *b = NULL;
+       int ret = 0;
+
+       while (1) {
+               int found = 0;
+               LIST_FOR_EACH_ENTRY(b, &capture_data->pending_buffer_list, link) {
+                       if (ret == b->index) {
+                               found = 1;
+                               break;
+                       }
+               }
+               if (!found)
+                       LIST_FOR_EACH_ENTRY(b, &capture_data->buffer_list, link) {
+                       if (ret == b->index) {
+                               found = 1;
+                               break;
+                       }
+               }
+               if (!found)
+                       break;
+               ret++;
+       }
+
+       return ret;
+}
+
+static void
+_tdm_exynos_capture_oneshot_center_rect(int src_w, int src_h, int dst_w, int dst_h, tdm_pos *fit)
+{
+       float rw = (float)src_w / dst_w;
+       float rh = (float)src_h / dst_h;
+
+       fit->x = fit->y = 0;
+
+       if (rw > rh) {
+               fit->w = dst_w;
+               fit->h = src_h / rw;
+               fit->y = (dst_h - fit->h) / 2;
+       } else if (rw < rh) {
+               fit->w = src_w / rh;
+               fit->h = dst_h;
+               fit->x = (dst_w - fit->w) / 2;
+       } else {
+               fit->w = dst_w;
+               fit->h = dst_h;
+       }
+
+       fit->x = fit->x & ~0x1;
+}
+
+static void
+_tdm_exynos_capture_oneshot_rect_scale(int src_w, int src_h, int dst_w, int dst_h, tdm_pos *scale)
+{
+       float ratio;
+       tdm_pos center = {0,};
+
+       _tdm_exynos_capture_oneshot_center_rect(src_w, src_h, dst_w, dst_h, &center);
+
+       ratio = (float)center.w / src_w;
+       scale->x = scale->x * ratio + center.x;
+       scale->y = scale->y * ratio + center.y;
+       scale->w = scale->w * ratio;
+       scale->h = scale->h * ratio;
+}
+
+static void
+_tdm_exynos_capture_oneshot_get_showing_rect(tdm_pos *out_rect, tdm_pos *dst_rect, tdm_pos *showing_rect)
+{
+       showing_rect->x = dst_rect->x;
+       showing_rect->y = dst_rect->y;
+
+       if (dst_rect->x >= out_rect->w)
+               showing_rect->w = 0;
+       else if (dst_rect->x + dst_rect->w > out_rect->w)
+               showing_rect->w = out_rect->w - dst_rect->x;
+       else
+               showing_rect->w = dst_rect->w;
+
+       if (dst_rect->y >= out_rect->h)
+               showing_rect->h = 0;
+       else if (dst_rect->y + dst_rect->h > out_rect->h)
+               showing_rect->h = out_rect->h - dst_rect->y;
+       else
+               showing_rect->h = dst_rect->h;
+}
+
+static void
+_tdm_exynos_capture_oneshot_get_src_crop_info(tdm_exynos_capture_data *capture_data,
+                                                                                         tdm_exynos_layer_data *layer_data, tdm_pos *src_crop, tdm_pos *showing_rect)
+{
+       tdm_exynos_output_data *output_data = capture_data->output_data;
+       float ratio_x, ratio_y;
+       tdm_pos out_rect;
+       tdm_pos dst_rect;
+
+       out_rect.x = 0;
+       out_rect.y = 0;
+       out_rect.w = output_data->current_mode->hdisplay;
+       out_rect.h = output_data->current_mode->vdisplay;
+
+       dst_rect.x = layer_data->info.dst_pos.x;
+       dst_rect.y = layer_data->info.dst_pos.y;
+       dst_rect.w = layer_data->info.dst_pos.w;
+       dst_rect.h = layer_data->info.dst_pos.h;
+
+       _tdm_exynos_capture_oneshot_get_showing_rect(&out_rect, &dst_rect, showing_rect);
+
+       src_crop->x = layer_data->info.src_config.pos.x;
+       src_crop->y = layer_data->info.src_config.pos.y;
+
+       if (layer_data->info.transform % 2 == 0) {
+               ratio_x = (float)layer_data->info.src_config.pos.w / dst_rect.w;
+               ratio_y = (float)layer_data->info.src_config.pos.h / dst_rect.h;
+
+               src_crop->w = showing_rect->w * ratio_x;
+               src_crop->h = showing_rect->h * ratio_y;
+       } else {
+               ratio_x = (float)layer_data->info.src_config.pos.w / dst_rect.h;
+               ratio_y = (float)layer_data->info.src_config.pos.h / dst_rect.w;
+
+               src_crop->w = showing_rect->h * ratio_x;
+               src_crop->h = showing_rect->w * ratio_y;
+       }
+}
+
+static void
+_tdm_exynos_capture_oneshot_get_dst_crop_info(tdm_exynos_capture_data *capture_data, tdm_exynos_layer_data *layer_data,
+                                                                                         tdm_pos *dst_pos, tdm_pos *showing_pos, tdm_pos *dst_crop,
+                                                                                         tdm_transform transform)
+{
+       tdm_exynos_output_data *output_data = capture_data->output_data;
+
+       if (layer_data->info.src_config.pos.w == output_data->current_mode->hdisplay &&
+               layer_data->info.src_config.pos.h == output_data->current_mode->vdisplay &&
+               dst_pos->x == 0 && dst_pos->y == 0 &&
+               dst_pos->w == capture_data->info.dst_config.size.h &&
+               dst_pos->h == capture_data->info.dst_config.size.v) {
+               dst_crop->x = dst_pos->x;
+               dst_crop->y = dst_pos->y;
+               dst_crop->w = dst_pos->w;
+               dst_crop->h = dst_pos->h;
+       } else if ((output_data->current_mode->hdisplay == dst_pos->w) &&
+                          (output_data->current_mode->vdisplay == dst_pos->h) &&
+                          (showing_pos->w == dst_pos->w) && (showing_pos->h == dst_pos->h)) {
+               dst_crop->x = layer_data->info.dst_pos.x + dst_pos->x;
+               dst_crop->y = layer_data->info.dst_pos.y + dst_pos->y;
+               dst_crop->w = layer_data->info.dst_pos.w;
+               dst_crop->h = layer_data->info.dst_pos.h;
+       } else if (transform == TDM_TRANSFORM_NORMAL || transform == TDM_TRANSFORM_FLIPPED) {
+               dst_crop->x = showing_pos->x * dst_pos->w / output_data->current_mode->hdisplay + dst_pos->x;
+               dst_crop->y = showing_pos->y * dst_pos->h / output_data->current_mode->vdisplay + dst_pos->y;
+               dst_crop->w = showing_pos->w * dst_pos->w / output_data->current_mode->hdisplay;
+               dst_crop->h = showing_pos->h * dst_pos->h / output_data->current_mode->vdisplay;
+       } else if (transform == TDM_TRANSFORM_90 || transform == TDM_TRANSFORM_FLIPPED_90) {
+               dst_crop->x = (output_data->current_mode->vdisplay - showing_pos->y - showing_pos->h) *
+                                         dst_pos->w / output_data->current_mode->vdisplay + dst_pos->x;
+               dst_crop->y = showing_pos->x * dst_pos->h / output_data->current_mode->hdisplay + dst_pos->y;
+               dst_crop->w = showing_pos->h * dst_pos->w / output_data->current_mode->vdisplay;
+               dst_crop->h = showing_pos->w * dst_pos->h / output_data->current_mode->hdisplay;
+       } else if (transform == TDM_TRANSFORM_180 || transform == TDM_TRANSFORM_FLIPPED_180) {
+               dst_crop->x = (output_data->current_mode->hdisplay - showing_pos->x - showing_pos->w) *
+                                         dst_pos->w / output_data->current_mode->hdisplay + dst_pos->x;
+               dst_crop->y = (output_data->current_mode->vdisplay - showing_pos->y - showing_pos->h) *
+                                         dst_pos->h / output_data->current_mode->vdisplay + dst_pos->y;
+               dst_crop->w = showing_pos->w * dst_pos->w / output_data->current_mode->hdisplay;
+               dst_crop->h = showing_pos->h * dst_pos->h / output_data->current_mode->vdisplay;
+       } else if (transform == TDM_TRANSFORM_270 || transform == TDM_TRANSFORM_FLIPPED_270) {
+               dst_crop->x = showing_pos->y * dst_pos->w / output_data->current_mode->vdisplay + dst_pos->x;
+               dst_crop->y = (output_data->current_mode->hdisplay - showing_pos->x - showing_pos->w) *
+                                         dst_pos->h / output_data->current_mode->hdisplay + dst_pos->y;
+               dst_crop->w = showing_pos->h * dst_pos->w / output_data->current_mode->vdisplay;
+               dst_crop->h = showing_pos->w * dst_pos->h / output_data->current_mode->hdisplay;
+       } else {
+               dst_crop->x = dst_pos->x;
+               dst_crop->y = dst_pos->y;
+               dst_crop->w = dst_pos->w;
+               dst_crop->h = dst_pos->h;
+               TDM_ERR("oneshot: get_crop unknown case error");
+       }
+}
+
+static void
+_tdm_exynos_capture_oneshot_composite_layers_sw(tdm_exynos_capture_data *capture_data, tbm_surface_h buffer)
+{
+       tdm_exynos_output_data *output_data = capture_data->output_data;
+       tdm_exynos_layer_data *layer_data = NULL;
+       tbm_surface_info_s buf_info;
+       int err;
+
+       err = tbm_surface_get_info(buffer, &buf_info);
+       RETURN_IF_FAIL(err == TBM_SURFACE_ERROR_NONE);
+
+       LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+               tbm_surface_h buf;
+               tdm_pos dst_pos;
+               tdm_pos showing_pos;
+               tdm_pos src_crop;
+               tdm_pos dst_crop;
+               tdm_transform transform = TDM_TRANSFORM_NORMAL;
+
+               if (!layer_data->display_buffer)
+                       continue;
+
+               buf = layer_data->display_buffer->buffer;
+
+               if (capture_data->info.dst_config.pos.w == 0 ||
+                       capture_data->info.dst_config.pos.h == 0) {
+                       dst_pos = layer_data->info.dst_pos;
+                       _tdm_exynos_capture_oneshot_rect_scale(output_data->current_mode->hdisplay,
+                                                                                                  output_data->current_mode->vdisplay,
+                                                                                                  buf_info.width, buf_info.height, &dst_pos);
+               } else {
+                       dst_pos = capture_data->info.dst_config.pos;
+                       transform = capture_data->info.transform;
+               }
+
+               _tdm_exynos_capture_oneshot_get_src_crop_info(capture_data, layer_data, &src_crop, &showing_pos);
+               _tdm_exynos_capture_oneshot_get_dst_crop_info(capture_data, layer_data, &dst_pos, &showing_pos, &dst_crop, transform);
+
+               TDM_DBG("oneshot convert buff: src_crop(%dx%d, %dx%d), dst_crop(%dx%d, %dx%d)\n",
+                               src_crop.x, src_crop.y, src_crop.w, src_crop.h,
+                               dst_crop.x, dst_crop.y, dst_crop.w, dst_crop.h);
+
+               tdm_helper_convert_buffer(buf, buffer,
+                                                                 &src_crop, &dst_crop, transform, 1);
+       }
+}
+
+static tdm_error
+_tdm_exynos_capture_commit_oneshot(tdm_exynos_capture_data *capture_data)
+{
+       tdm_exynos_capture_buffer *b = NULL, *bb = NULL;
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &capture_data->pending_buffer_list, link) {
+               LIST_DEL(&b->link);
+
+               /* TODO: need to improve the performance with hardware */
+               _tdm_exynos_capture_oneshot_composite_layers_sw(capture_data, b->buffer);
+
+               if (capture_data->done_func)
+                       capture_data->done_func(capture_data,
+                                                                       b->buffer,
+                                                                       capture_data->done_user_data);
+               free(b);
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+tdm_exynos_capture_get_capability(tdm_exynos_data *exynos_data, tdm_caps_capture *caps)
+{
+       int i;
+
+       if (!caps) {
+               TDM_ERR("invalid params");
+               return TDM_ERROR_INVALID_PARAMETER;
+       }
+
+       caps->capabilities = TDM_CAPTURE_CAPABILITY_OUTPUT|
+                                                TDM_CAPTURE_CAPABILITY_ONESHOT;
+
+       caps->format_count = NUM_CAPTURE_FORMAT;
+       caps->formats = NULL;
+       if (NUM_CAPTURE_FORMAT) {
+               /* will be freed in frontend */
+               caps->formats = calloc(1, sizeof capture_formats);
+               if (!caps->formats) {
+                       TDM_ERR("alloc failed");
+                       return TDM_ERROR_OUT_OF_MEMORY;
+               }
+               for (i = 0; i < caps->format_count; i++)
+                       caps->formats[i] = capture_formats[i];
+       }
+
+       caps->min_w = 16;
+       caps->min_h = 8;
+       caps->preferred_align = 2;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_capture*
+tdm_exynos_capture_create_output(tdm_exynos_data *exynos_data, tdm_output *output, tdm_error *error)
+{
+       tdm_exynos_capture_data *capture_data = calloc(1, sizeof(tdm_exynos_capture_data));
+       if (!capture_data) {
+               TDM_ERR("alloc failed");
+               if (error)
+                       *error = TDM_ERROR_OUT_OF_MEMORY;
+               return NULL;
+       }
+
+       capture_data->exynos_data = exynos_data;
+       capture_data->output_data = output;
+
+       LIST_INITHEAD(&capture_data->pending_buffer_list);
+       LIST_INITHEAD(&capture_data->buffer_list);
+
+       if (!capture_list_init) {
+               capture_list_init = 1;
+               LIST_INITHEAD(&capture_list);
+       }
+       LIST_ADDTAIL(&capture_data->link, &capture_list);
+
+       TDM_DBG("capture(%p) create", capture_data);
+
+       return capture_data;
+}
+
+void
+exynos_capture_destroy(tdm_capture *capture)
+{
+       tdm_exynos_capture_data *capture_data = capture;
+       tdm_exynos_capture_buffer *b = NULL, *bb = NULL;
+
+       if (!capture_data)
+               return;
+
+       TDM_DBG("capture(%p) destroy", capture_data);
+
+       if (capture_data->stream.timer_source)
+               tdm_event_loop_source_remove(capture_data->stream.timer_source);
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &capture_data->pending_buffer_list, link) {
+               LIST_DEL(&b->link);
+               free(b);
+       }
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &capture_data->buffer_list, link) {
+               LIST_DEL(&b->link);
+               tdm_buffer_unref_backend(b->ui_buffer);
+               free(b);
+       }
+
+       LIST_DEL(&capture_data->link);
+
+       free(capture_data);
+}
+
+tdm_error
+exynos_capture_set_info(tdm_capture *capture, tdm_info_capture *info)
+{
+       tdm_exynos_capture_data *capture_data = capture;
+
+       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
+
+       capture_data->info = *info;
+       capture_data->info_changed = 1;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_capture_attach(tdm_capture *capture, tbm_surface_h buffer)
+{
+       tdm_exynos_capture_data *capture_data = capture;
+       tdm_exynos_capture_buffer *b;
+
+       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(buffer, TDM_ERROR_INVALID_PARAMETER);
+
+       b = calloc(1, sizeof(tdm_exynos_capture_buffer));
+       if (!b) {
+               TDM_ERR("alloc failed");
+               return TDM_ERROR_NONE;
+       }
+
+       LIST_ADDTAIL(&b->link, &capture_data->pending_buffer_list);
+
+       b->index = _get_index(capture_data);
+       b->buffer = buffer;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_capture_commit(tdm_capture *capture)
+{
+       tdm_exynos_capture_data *capture_data = capture;
+       tdm_error ret = TDM_ERROR_INVALID_PARAMETER;
+
+       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
+
+       if (capture_data->info.type == TDM_CAPTURE_TYPE_ONESHOT)
+               ret = _tdm_exynos_capture_commit_oneshot(capture_data);
+
+       return ret;
+}
+
+tdm_error
+exynos_capture_set_done_handler(tdm_capture *capture, tdm_capture_done_handler func, void *user_data)
+{
+       tdm_exynos_capture_data *capture_data = capture;
+
+       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
+
+       capture_data->done_func = func;
+       capture_data->done_user_data = user_data;
+
+       return TDM_ERROR_NONE;
+}
diff --git a/src/libtdm-exynos/tdm_exynos_capture.h b/src/libtdm-exynos/tdm_exynos_capture.h
new file mode 100644 (file)
index 0000000..9e77206
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _TDM_EXYNOS_CAPTURE_H_
+#define _TDM_EXYNOS_CAPTURE_H_
+
+#include "tdm_exynos.h"
+
+tdm_error    tdm_exynos_capture_get_capability(tdm_exynos_data *exynos_data, tdm_caps_capture *caps);
+tdm_pp*      tdm_exynos_capture_create_output(tdm_exynos_data *exynos_data, tdm_output *output, tdm_error *error);
+
+#endif /* _TDM_EXYNOS_CAPTURE_H_ */
diff --git a/src/libtdm-exynos/tdm_exynos_capture_legacy.c b/src/libtdm-exynos/tdm_exynos_capture_legacy.c
new file mode 100644 (file)
index 0000000..0fc4651
--- /dev/null
@@ -0,0 +1,742 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_exynos.h"
+
+typedef struct _tdm_exynos_capture_legacy_buffer {
+       int index;
+       tbm_surface_h ui_buffer;
+       tbm_surface_h buffer;
+       struct list_head link;
+} tdm_exynos_capture_legacy_buffer;
+
+typedef struct _tdm_exynos_pp_legacy_data {
+       tdm_exynos_data *exynos_data;
+
+       tdm_exynos_output_data *output_data;
+
+       tdm_info_capture info;
+       int info_changed;
+
+       struct list_head pending_buffer_list;
+       struct list_head buffer_list;
+
+       struct {
+               tdm_event_loop_source *timer_source;
+
+               unsigned int prop_id;
+
+               int startd;
+               int first_event;
+       } stream;
+
+       tdm_capture_done_handler done_func;
+       void *done_user_data;
+
+       struct list_head link;
+} tdm_exynos_capture_legacy_data;
+
+static tbm_format capture_formats[] = {
+       TBM_FORMAT_ARGB8888,
+       TBM_FORMAT_XRGB8888,
+};
+
+#define NUM_CAPTURE_FORMAT   (sizeof(capture_formats) / sizeof(capture_formats[0]))
+
+static int capture_list_init;
+static struct list_head capture_list;
+
+int
+tdm_exynos_capture_legacy_find_prop_id(unsigned int prop_id)
+{
+       tdm_exynos_capture_legacy_data *capture_data = NULL;
+
+       if (!capture_list_init) {
+               capture_list_init = 1;
+               LIST_INITHEAD(&capture_list);
+       }
+
+       if (LIST_IS_EMPTY(&capture_list))
+               return 0;
+
+       LIST_FOR_EACH_ENTRY(capture_data, &capture_list, link) {
+               if (capture_data->stream.prop_id == prop_id)
+                       return 1;
+       }
+
+       return 0;
+}
+
+static int
+_get_index(tdm_exynos_capture_legacy_data *capture_data)
+{
+       tdm_exynos_capture_legacy_buffer *b = NULL;
+       int ret = 0;
+
+       while (1) {
+               int found = 0;
+               LIST_FOR_EACH_ENTRY(b, &capture_data->pending_buffer_list, link) {
+                       if (ret == b->index) {
+                               found = 1;
+                               break;
+                       }
+               }
+               if (!found)
+                       LIST_FOR_EACH_ENTRY(b, &capture_data->buffer_list, link) {
+                       if (ret == b->index) {
+                               found = 1;
+                               break;
+                       }
+               }
+               if (!found)
+                       break;
+               ret++;
+       }
+
+       return ret;
+}
+
+static tdm_error
+_tdm_exynos_capture_legacy_stream_pp_set(tdm_exynos_capture_legacy_data *capture_data, tbm_surface_h ui_buffer)
+{
+       tdm_exynos_data *exynos_data = capture_data->exynos_data;
+       tdm_info_capture *info = &capture_data->info;
+       struct drm_exynos_ipp_property property;
+       unsigned int width, height, stride = 0;
+       int ret = 0;
+
+       tbm_surface_internal_get_plane_data(ui_buffer, 0, NULL, NULL, &stride);
+       width = tbm_surface_get_width(ui_buffer);
+       height = tbm_surface_get_height(ui_buffer);
+
+       CLEAR(property);
+
+       property.config[0].ops_id = EXYNOS_DRM_OPS_SRC;
+       property.config[0].fmt = tdm_exynos_format_to_drm_format(tbm_surface_get_format(ui_buffer));
+       property.config[0].sz.hsize = stride >> 2;
+       property.config[0].sz.vsize = height;
+       property.config[0].pos.w = width;
+       property.config[0].pos.h = height;
+
+       property.config[1].ops_id = EXYNOS_DRM_OPS_DST;
+       property.config[1].degree = info->transform % 4;
+       property.config[1].flip = (info->transform > 3) ? EXYNOS_DRM_FLIP_HORIZONTAL : 0;
+       property.config[1].fmt = tdm_exynos_format_to_drm_format(info->dst_config.format);
+       memcpy(&property.config[1].sz, &info->dst_config.size, sizeof(tdm_size));
+       memcpy(&property.config[1].pos, &info->dst_config.pos, sizeof(tdm_pos));
+       property.cmd = IPP_CMD_M2M;
+       property.prop_id = capture_data->stream.prop_id;
+
+       TDM_DBG("src : flip(%x) deg(%d) fmt(%c%c%c%c) sz(%dx%d) pos(%d,%d %dx%d)  ",
+                       property.config[0].flip, property.config[0].degree,
+                       FOURCC_STR(property.config[0].fmt),
+                       property.config[0].sz.hsize, property.config[0].sz.vsize,
+                       property.config[0].pos.x, property.config[0].pos.y, property.config[0].pos.w,
+                       property.config[0].pos.h);
+       TDM_DBG("dst : flip(%x) deg(%d) fmt(%c%c%c%c) sz(%dx%d) pos(%d,%d %dx%d)  ",
+                       property.config[1].flip, property.config[1].degree,
+                       FOURCC_STR(property.config[1].fmt),
+                       property.config[1].sz.hsize, property.config[1].sz.vsize,
+                       property.config[1].pos.x, property.config[1].pos.y, property.config[1].pos.w,
+                       property.config[1].pos.h);
+
+       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_SET_PROPERTY, &property);
+       if (ret) {
+               TDM_ERR("failed: %m");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       TDM_DBG("success. prop_id(%d) ", property.prop_id);
+       capture_data->stream.prop_id = property.prop_id;
+       return TDM_ERROR_NONE;
+}
+
+static tdm_error
+_tdm_exynos_capture_legacy_stream_pp_queue(tdm_exynos_capture_legacy_data *capture_data,
+                                                                       tdm_exynos_capture_legacy_buffer *b,
+                                                                       enum drm_exynos_ipp_buf_type type)
+{
+       tdm_exynos_data *exynos_data = capture_data->exynos_data;
+       struct drm_exynos_ipp_queue_buf buf;
+       int i, bo_num, ret = 0;
+
+       CLEAR(buf);
+       buf.prop_id = capture_data->stream.prop_id;
+       buf.ops_id = EXYNOS_DRM_OPS_SRC;
+       buf.buf_type = type;
+       buf.buf_id = b->index;
+       buf.user_data = (__u64)(uintptr_t)capture_data;
+       bo_num = tbm_surface_internal_get_num_bos(b->ui_buffer);
+       for (i = 0; i < EXYNOS_DRM_PLANAR_MAX && i < bo_num; i++) {
+               tbm_bo bo = tbm_surface_internal_get_bo(b->ui_buffer, i);
+               buf.handle[i] = (__u32)tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
+       }
+
+       TDM_DBG("prop_id(%d) ops_id(%d) ctrl(%d) id(%d) handles(%x %x %x). ",
+                       buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id,
+                       buf.handle[0], buf.handle[1], buf.handle[2]);
+
+       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
+       if (ret) {
+               TDM_ERR("src failed. prop_id(%d) op(%d) buf(%d) id(%d). %m",
+                               buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id);
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       CLEAR(buf);
+       buf.prop_id = capture_data->stream.prop_id;
+       buf.ops_id = EXYNOS_DRM_OPS_DST;
+       buf.buf_type = type;
+       buf.buf_id = b->index;
+       buf.user_data = (__u64)(uintptr_t)capture_data;
+       bo_num = tbm_surface_internal_get_num_bos(b->buffer);
+       for (i = 0; i < EXYNOS_DRM_PLANAR_MAX && i < bo_num; i++) {
+               tbm_bo bo = tbm_surface_internal_get_bo(b->buffer, i);
+               buf.handle[i] = (__u32)tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
+       }
+
+       TDM_DBG("prop_id(%d) ops_id(%d) ctrl(%d) id(%d) handles(%x %x %x). ",
+                       buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id,
+                       buf.handle[0], buf.handle[1], buf.handle[2]);
+
+       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
+       if (ret) {
+               TDM_ERR("dst failed. prop_id(%d) op(%d) buf(%d) id(%d). %m",
+                               buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id);
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       TDM_DBG("success. prop_id(%d)", buf.prop_id);
+
+       return TDM_ERROR_NONE;
+}
+
+static tdm_error
+_tdm_exynos_capture_legacy_stream_pp_cmd(tdm_exynos_capture_legacy_data *capture_data, enum drm_exynos_ipp_ctrl cmd)
+{
+       tdm_exynos_data *exynos_data = capture_data->exynos_data;
+       struct drm_exynos_ipp_cmd_ctrl ctrl;
+       int ret = 0;
+
+       ctrl.prop_id = capture_data->stream.prop_id;
+       ctrl.ctrl = cmd;
+
+       TDM_DBG("prop_id(%d) ctrl(%d). ", ctrl.prop_id, ctrl.ctrl);
+
+       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_CMD_CTRL, &ctrl);
+       if (ret) {
+               TDM_ERR("failed. prop_id(%d) ctrl(%d). %m", ctrl.prop_id, ctrl.ctrl);
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       TDM_DBG("success. prop_id(%d) ", ctrl.prop_id);
+
+       return TDM_ERROR_NONE;
+}
+
+void
+tdm_exynos_capture_legacy_stream_pp_handler(unsigned int prop_id, unsigned int *buf_idx,
+                                                                        unsigned int tv_sec, unsigned int tv_usec, void *data)
+{
+       tdm_exynos_capture_legacy_data *found = NULL, *d = NULL, *capture_data = data;
+       tdm_exynos_capture_legacy_buffer *b = NULL, *bb = NULL, *dequeued_buffer = NULL;
+
+       if (!capture_data || !buf_idx) {
+               TDM_ERR("invalid params");
+               return;
+       }
+
+       LIST_FOR_EACH_ENTRY(d, &capture_list, link) {
+               if (d == capture_data) {
+                       found = d;
+                       break;
+               }
+       }
+       if (!found)
+               return;
+
+       TDM_DBG("capture_data(%p) index(%d, %d)", capture_data, buf_idx[0], buf_idx[1]);
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &capture_data->buffer_list, link) {
+               if (buf_idx[0] == b->index) {
+                       dequeued_buffer = b;
+                       LIST_DEL(&dequeued_buffer->link);
+                       TDM_DBG("dequeued: %d", dequeued_buffer->index);
+                       break;
+               }
+       }
+
+       if (!dequeued_buffer) {
+               TDM_ERR("not found buffer index: %d", buf_idx[0]);
+               return;
+       }
+
+       if (!capture_data->stream.first_event) {
+               TDM_DBG("capture(%p) got a first event. ", capture_data);
+               capture_data->stream.first_event = 1;
+       }
+
+       if (capture_data->done_func)
+               capture_data->done_func(capture_data,
+                                                               dequeued_buffer->buffer,
+                                                               capture_data->done_user_data);
+
+       tdm_buffer_unref_backend(dequeued_buffer->ui_buffer);
+
+       free(dequeued_buffer);
+}
+
+static tdm_error
+_tdm_exynos_capture_legacy_stream_timer_handler(void *user_data)
+{
+       tdm_exynos_capture_legacy_data *capture_data = user_data;
+       unsigned int ms = 1000 / capture_data->info.frequency;
+       tdm_exynos_capture_legacy_buffer *b = NULL;
+       tbm_surface_h ui_buffer = NULL;
+       tdm_error ret;
+
+       tdm_event_loop_source_timer_update(capture_data->stream.timer_source, ms);
+
+       if (capture_data->output_data->primary_layer->display_buffer)
+               ui_buffer = capture_data->output_data->primary_layer->display_buffer->buffer;
+
+       if (!ui_buffer)
+               return TDM_ERROR_NONE;
+
+       if (capture_data->info_changed) {
+               if (capture_data->stream.startd)
+                       _tdm_exynos_capture_legacy_stream_pp_cmd(capture_data, IPP_CTRL_PAUSE);
+
+               ret = _tdm_exynos_capture_legacy_stream_pp_set(capture_data, ui_buffer);
+               if (ret < 0)
+                       return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       b = LIST_FIRST_ENTRY(&capture_data->pending_buffer_list, tdm_exynos_capture_legacy_buffer, link);
+       RETURN_VAL_IF_FAIL(b != NULL, TDM_ERROR_OPERATION_FAILED);
+
+       LIST_DEL(&b->link);
+       b->ui_buffer = tdm_buffer_ref_backend(ui_buffer);
+       _tdm_exynos_capture_legacy_stream_pp_queue(capture_data, b, IPP_BUF_ENQUEUE);
+       TDM_DBG("queued: %d", b->index);
+       LIST_ADDTAIL(&b->link, &capture_data->buffer_list);
+
+       if (capture_data->info_changed) {
+               capture_data->info_changed = 0;
+
+               if (!capture_data->stream.startd) {
+                       capture_data->stream.startd = 1;
+                       _tdm_exynos_capture_legacy_stream_pp_cmd(capture_data, IPP_CTRL_PLAY);
+               } else
+                       _tdm_exynos_capture_legacy_stream_pp_cmd(capture_data, IPP_CTRL_RESUME);
+       }
+
+
+       return TDM_ERROR_NONE;
+}
+
+
+static tdm_error
+_tdm_exynos_capture_legacy_commit_stream(tdm_exynos_capture_legacy_data *capture_data)
+{
+       unsigned int ms = 1000 / capture_data->info.frequency;
+
+       if (!capture_data->stream.timer_source) {
+               capture_data->stream.timer_source =
+                       tdm_event_loop_add_timer_handler(capture_data->exynos_data->dpy,
+                                                                                        _tdm_exynos_capture_legacy_stream_timer_handler,
+                                                                                        capture_data, NULL);
+                       RETURN_VAL_IF_FAIL(capture_data->stream.timer_source != NULL, TDM_ERROR_OUT_OF_MEMORY);
+       }
+
+       tdm_event_loop_source_timer_update(capture_data->stream.timer_source, ms);
+
+       return TDM_ERROR_NONE;
+}
+
+static void
+_tdm_exynos_capture_legacy_oneshot_center_rect(int src_w, int src_h, int dst_w, int dst_h, tdm_pos *fit)
+{
+       float rw = (float)src_w / dst_w;
+       float rh = (float)src_h / dst_h;
+
+       fit->x = fit->y = 0;
+
+       if (rw > rh) {
+               fit->w = dst_w;
+               fit->h = src_h / rw;
+               fit->y = (dst_h - fit->h) / 2;
+       } else if (rw < rh) {
+               fit->w = src_w / rh;
+               fit->h = dst_h;
+               fit->x = (dst_w - fit->w) / 2;
+       } else {
+               fit->w = dst_w;
+               fit->h = dst_h;
+       }
+
+       fit->x = fit->x & ~0x1;
+}
+
+static void
+_tdm_exynos_capture_legacy_oneshot_rect_scale(int src_w, int src_h, int dst_w, int dst_h, tdm_pos *scale)
+{
+       float ratio;
+       tdm_pos center = {0,};
+
+       _tdm_exynos_capture_legacy_oneshot_center_rect(src_w, src_h, dst_w, dst_h, &center);
+
+       ratio = (float)center.w / src_w;
+       scale->x = scale->x * ratio + center.x;
+       scale->y = scale->y * ratio + center.y;
+       scale->w = scale->w * ratio;
+       scale->h = scale->h * ratio;
+}
+
+static void
+_tdm_exynos_capture_legacy_oneshot_get_showing_rect(tdm_pos *out_rect, tdm_pos *dst_rect, tdm_pos *showing_rect)
+{
+       showing_rect->x = dst_rect->x;
+       showing_rect->y = dst_rect->y;
+
+       if (dst_rect->x >= out_rect->w)
+               showing_rect->w = 0;
+       else if (dst_rect->x + dst_rect->w > out_rect->w)
+               showing_rect->w = out_rect->w - dst_rect->x;
+       else
+               showing_rect->w = dst_rect->w;
+
+       if (dst_rect->y >= out_rect->h)
+               showing_rect->h = 0;
+       else if (dst_rect->y + dst_rect->h > out_rect->h)
+               showing_rect->h = out_rect->h - dst_rect->y;
+       else
+               showing_rect->h = dst_rect->h;
+}
+
+static void
+_tdm_exynos_capture_legacy_oneshot_get_src_crop_info(tdm_exynos_capture_legacy_data *capture_data,
+                                                                                         tdm_exynos_layer_data *layer_data, tdm_pos *src_crop, tdm_pos *showing_rect)
+{
+       tdm_exynos_output_data *output_data = capture_data->output_data;
+       float ratio_x, ratio_y;
+       tdm_pos out_rect;
+       tdm_pos dst_rect;
+
+       out_rect.x = 0;
+       out_rect.y = 0;
+       out_rect.w = output_data->current_mode->hdisplay;
+       out_rect.h = output_data->current_mode->vdisplay;
+
+       dst_rect.x = layer_data->info.dst_pos.x;
+       dst_rect.y = layer_data->info.dst_pos.y;
+       dst_rect.w = layer_data->info.dst_pos.w;
+       dst_rect.h = layer_data->info.dst_pos.h;
+
+       _tdm_exynos_capture_legacy_oneshot_get_showing_rect(&out_rect, &dst_rect, showing_rect);
+
+       src_crop->x = layer_data->info.src_config.pos.x;
+       src_crop->y = layer_data->info.src_config.pos.y;
+
+       if (layer_data->info.transform % 2 == 0) {
+               ratio_x = (float)layer_data->info.src_config.pos.w / dst_rect.w;
+               ratio_y = (float)layer_data->info.src_config.pos.h / dst_rect.h;
+
+               src_crop->w = showing_rect->w * ratio_x;
+               src_crop->h = showing_rect->h * ratio_y;
+       } else {
+               ratio_x = (float)layer_data->info.src_config.pos.w / dst_rect.h;
+               ratio_y = (float)layer_data->info.src_config.pos.h / dst_rect.w;
+
+               src_crop->w = showing_rect->h * ratio_x;
+               src_crop->h = showing_rect->w * ratio_y;
+       }
+}
+
+static void
+_tdm_exynos_capture_legacy_oneshot_get_dst_crop_info(tdm_exynos_capture_legacy_data *capture_data, tdm_exynos_layer_data *layer_data,
+                                                                                         tdm_pos *dst_pos, tdm_pos *showing_pos, tdm_pos *dst_crop,
+                                                                                         tdm_transform transform)
+{
+       tdm_exynos_output_data *output_data = capture_data->output_data;
+
+       if (layer_data->info.src_config.pos.w == output_data->current_mode->hdisplay &&
+               layer_data->info.src_config.pos.h == output_data->current_mode->vdisplay &&
+               dst_pos->x == 0 && dst_pos->y == 0 &&
+               dst_pos->w == capture_data->info.dst_config.size.h &&
+               dst_pos->h == capture_data->info.dst_config.size.v) {
+               dst_crop->x = dst_pos->x;
+               dst_crop->y = dst_pos->y;
+               dst_crop->w = dst_pos->w;
+               dst_crop->h = dst_pos->h;
+       } else if ((output_data->current_mode->hdisplay == dst_pos->w) &&
+                          (output_data->current_mode->vdisplay == dst_pos->h) &&
+                          (showing_pos->w == dst_pos->w) && (showing_pos->h == dst_pos->h)) {
+               dst_crop->x = layer_data->info.dst_pos.x + dst_pos->x;
+               dst_crop->y = layer_data->info.dst_pos.y + dst_pos->y;
+               dst_crop->w = layer_data->info.dst_pos.w;
+               dst_crop->h = layer_data->info.dst_pos.h;
+       } else if (transform == TDM_TRANSFORM_NORMAL || transform == TDM_TRANSFORM_FLIPPED) {
+               dst_crop->x = showing_pos->x * dst_pos->w / output_data->current_mode->hdisplay + dst_pos->x;
+               dst_crop->y = showing_pos->y * dst_pos->h / output_data->current_mode->vdisplay + dst_pos->y;
+               dst_crop->w = showing_pos->w * dst_pos->w / output_data->current_mode->hdisplay;
+               dst_crop->h = showing_pos->h * dst_pos->h / output_data->current_mode->vdisplay;
+       } else if (transform == TDM_TRANSFORM_90 || transform == TDM_TRANSFORM_FLIPPED_90) {
+               dst_crop->x = (output_data->current_mode->vdisplay - showing_pos->y - showing_pos->h) *
+                                         dst_pos->w / output_data->current_mode->vdisplay + dst_pos->x;
+               dst_crop->y = showing_pos->x * dst_pos->h / output_data->current_mode->hdisplay + dst_pos->y;
+               dst_crop->w = showing_pos->h * dst_pos->w / output_data->current_mode->vdisplay;
+               dst_crop->h = showing_pos->w * dst_pos->h / output_data->current_mode->hdisplay;
+       } else if (transform == TDM_TRANSFORM_180 || transform == TDM_TRANSFORM_FLIPPED_180) {
+               dst_crop->x = (output_data->current_mode->hdisplay - showing_pos->x - showing_pos->w) *
+                                         dst_pos->w / output_data->current_mode->hdisplay + dst_pos->x;
+               dst_crop->y = (output_data->current_mode->vdisplay - showing_pos->y - showing_pos->h) *
+                                         dst_pos->h / output_data->current_mode->vdisplay + dst_pos->y;
+               dst_crop->w = showing_pos->w * dst_pos->w / output_data->current_mode->hdisplay;
+               dst_crop->h = showing_pos->h * dst_pos->h / output_data->current_mode->vdisplay;
+       } else if (transform == TDM_TRANSFORM_270 || transform == TDM_TRANSFORM_FLIPPED_270) {
+               dst_crop->x = showing_pos->y * dst_pos->w / output_data->current_mode->vdisplay + dst_pos->x;
+               dst_crop->y = (output_data->current_mode->hdisplay - showing_pos->x - showing_pos->w) *
+                                         dst_pos->h / output_data->current_mode->hdisplay + dst_pos->y;
+               dst_crop->w = showing_pos->h * dst_pos->w / output_data->current_mode->vdisplay;
+               dst_crop->h = showing_pos->w * dst_pos->h / output_data->current_mode->hdisplay;
+       } else {
+               dst_crop->x = dst_pos->x;
+               dst_crop->y = dst_pos->y;
+               dst_crop->w = dst_pos->w;
+               dst_crop->h = dst_pos->h;
+               TDM_ERR("oneshot: get_crop unknown case error");
+       }
+}
+
+static void
+_tdm_exynos_capture_legacy_oneshot_composite_layers_sw(tdm_exynos_capture_legacy_data *capture_data, tbm_surface_h buffer)
+{
+       tdm_exynos_output_data *output_data = capture_data->output_data;
+       tdm_exynos_layer_data *layer_data = NULL;
+       tbm_surface_info_s buf_info;
+       int err;
+
+       err = tbm_surface_get_info(buffer, &buf_info);
+       RETURN_IF_FAIL(err == TBM_SURFACE_ERROR_NONE);
+
+       LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+               tbm_surface_h buf;
+               tdm_pos dst_pos;
+               tdm_pos showing_pos;
+               tdm_pos src_crop;
+               tdm_pos dst_crop;
+               tdm_transform transform = TDM_TRANSFORM_NORMAL;
+
+               if (!layer_data->display_buffer)
+                       continue;
+
+               buf = layer_data->display_buffer->buffer;
+
+               if (capture_data->info.dst_config.pos.w == 0 ||
+                       capture_data->info.dst_config.pos.h == 0) {
+                       dst_pos = layer_data->info.dst_pos;
+                       _tdm_exynos_capture_legacy_oneshot_rect_scale(output_data->current_mode->hdisplay,
+                                                                                                  output_data->current_mode->vdisplay,
+                                                                                                  buf_info.width, buf_info.height, &dst_pos);
+               } else {
+                       dst_pos = capture_data->info.dst_config.pos;
+                       transform = capture_data->info.transform;
+               }
+
+               _tdm_exynos_capture_legacy_oneshot_get_src_crop_info(capture_data, layer_data, &src_crop, &showing_pos);
+               _tdm_exynos_capture_legacy_oneshot_get_dst_crop_info(capture_data, layer_data, &dst_pos, &showing_pos, &dst_crop, transform);
+
+               TDM_DBG("oneshot convert buff: src_crop(%dx%d, %dx%d), dst_crop(%dx%d, %dx%d)\n",
+                               src_crop.x, src_crop.y, src_crop.w, src_crop.h,
+                               dst_crop.x, dst_crop.y, dst_crop.w, dst_crop.h);
+
+               tdm_helper_convert_buffer(buf, buffer,
+                                                                 &src_crop, &dst_crop, transform, 1);
+       }
+}
+
+static tdm_error
+_tdm_exynos_capture_legacy_commit_oneshot(tdm_exynos_capture_legacy_data *capture_data)
+{
+       tdm_exynos_capture_legacy_buffer *b = NULL, *bb = NULL;
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &capture_data->pending_buffer_list, link) {
+               LIST_DEL(&b->link);
+
+               /* TODO: need to improve the performance with hardware */
+               _tdm_exynos_capture_legacy_oneshot_composite_layers_sw(capture_data, b->buffer);
+
+               if (capture_data->done_func)
+                       capture_data->done_func(capture_data,
+                                                                       b->buffer,
+                                                                       capture_data->done_user_data);
+               free(b);
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+tdm_exynos_capture_legacy_get_capability(tdm_exynos_data *exynos_data, tdm_caps_capture *caps)
+{
+       int i;
+
+       if (!caps) {
+               TDM_ERR("invalid params");
+               return TDM_ERROR_INVALID_PARAMETER;
+       }
+
+       caps->capabilities = TDM_CAPTURE_CAPABILITY_OUTPUT|
+                                                TDM_CAPTURE_CAPABILITY_ONESHOT|
+                                                TDM_CAPTURE_CAPABILITY_STREAM;
+
+       caps->format_count = NUM_CAPTURE_FORMAT;
+       caps->formats = NULL;
+       if (NUM_CAPTURE_FORMAT) {
+               /* will be freed in frontend */
+               caps->formats = calloc(1, sizeof capture_formats);
+               if (!caps->formats) {
+                       TDM_ERR("alloc failed");
+                       return TDM_ERROR_OUT_OF_MEMORY;
+               }
+               for (i = 0; i < caps->format_count; i++)
+                       caps->formats[i] = capture_formats[i];
+       }
+
+       caps->min_w = 16;
+       caps->min_h = 8;
+       caps->preferred_align = 2;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_capture*
+tdm_exynos_capture_legacy_create_output(tdm_exynos_data *exynos_data, tdm_output *output, tdm_error *error)
+{
+       tdm_exynos_capture_legacy_data *capture_data = calloc(1, sizeof(tdm_exynos_capture_legacy_data));
+       if (!capture_data) {
+               TDM_ERR("alloc failed");
+               if (error)
+                       *error = TDM_ERROR_OUT_OF_MEMORY;
+               return NULL;
+       }
+
+       capture_data->exynos_data = exynos_data;
+       capture_data->output_data = output;
+
+       LIST_INITHEAD(&capture_data->pending_buffer_list);
+       LIST_INITHEAD(&capture_data->buffer_list);
+
+       if (!capture_list_init) {
+               capture_list_init = 1;
+               LIST_INITHEAD(&capture_list);
+       }
+       LIST_ADDTAIL(&capture_data->link, &capture_list);
+
+       TDM_DBG("capture(%p) create", capture_data);
+
+       return capture_data;
+}
+
+void
+exynos_capture_legacy_destroy(tdm_capture *capture)
+{
+       tdm_exynos_capture_legacy_data *capture_data = capture;
+       tdm_exynos_capture_legacy_buffer *b = NULL, *bb = NULL;
+
+       if (!capture_data)
+               return;
+
+       TDM_DBG("capture(%p) destroy", capture_data);
+
+       if (capture_data->stream.timer_source)
+               tdm_event_loop_source_remove(capture_data->stream.timer_source);
+
+       if (capture_data->stream.prop_id)
+               _tdm_exynos_capture_legacy_stream_pp_cmd(capture_data, IPP_CTRL_STOP);
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &capture_data->pending_buffer_list, link) {
+               LIST_DEL(&b->link);
+               free(b);
+       }
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &capture_data->buffer_list, link) {
+               LIST_DEL(&b->link);
+               tdm_buffer_unref_backend(b->ui_buffer);
+               _tdm_exynos_capture_legacy_stream_pp_queue(capture_data, b, IPP_BUF_DEQUEUE);
+               free(b);
+       }
+
+       LIST_DEL(&capture_data->link);
+
+       free(capture_data);
+}
+
+tdm_error
+exynos_capture_legacy_set_info(tdm_capture *capture, tdm_info_capture *info)
+{
+       tdm_exynos_capture_legacy_data *capture_data = capture;
+
+       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
+
+       capture_data->info = *info;
+       capture_data->info_changed = 1;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_capture_legacy_attach(tdm_capture *capture, tbm_surface_h buffer)
+{
+       tdm_exynos_capture_legacy_data *capture_data = capture;
+       tdm_exynos_capture_legacy_buffer *b;
+
+       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(buffer, TDM_ERROR_INVALID_PARAMETER);
+
+       b = calloc(1, sizeof(tdm_exynos_capture_legacy_buffer));
+       if (!b) {
+               TDM_ERR("alloc failed");
+               return TDM_ERROR_NONE;
+       }
+
+       LIST_ADDTAIL(&b->link, &capture_data->pending_buffer_list);
+
+       b->index = _get_index(capture_data);
+       b->buffer = buffer;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_capture_legacy_commit(tdm_capture *capture)
+{
+       tdm_exynos_capture_legacy_data *capture_data = capture;
+       tdm_error ret;
+
+       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
+
+       if (capture_data->info.type == TDM_CAPTURE_TYPE_ONESHOT)
+               ret = _tdm_exynos_capture_legacy_commit_oneshot(capture_data);
+       else
+               ret = _tdm_exynos_capture_legacy_commit_stream(capture_data);
+
+       return ret;
+}
+
+tdm_error
+exynos_capture_legacy_set_done_handler(tdm_capture *capture, tdm_capture_done_handler func, void *user_data)
+{
+       tdm_exynos_capture_legacy_data *capture_data = capture;
+
+       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
+
+       capture_data->done_func = func;
+       capture_data->done_user_data = user_data;
+
+       return TDM_ERROR_NONE;
+}
diff --git a/src/libtdm-exynos/tdm_exynos_capture_legacy.h b/src/libtdm-exynos/tdm_exynos_capture_legacy.h
new file mode 100644 (file)
index 0000000..dfcc01c
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _TDM_EXYNOS_CAPTURE_LEGACY_H_
+#define _TDM_EXYNOS_CAPTURE_LEGACY_H_
+
+#include "tdm_exynos.h"
+
+tdm_error    tdm_exynos_capture_legacy_get_capability(tdm_exynos_data *exynos_data, tdm_caps_capture *caps);
+tdm_pp*      tdm_exynos_capture_legacy_create_output(tdm_exynos_data *exynos_data, tdm_output *output, tdm_error *error);
+void         tdm_exynos_capture_legacy_stream_pp_handler(unsigned int prop_id, unsigned int *buf_idx,
+                                                                                                 unsigned int tv_sec, unsigned int tv_usec, void *data);
+int          tdm_exynos_capture_legacy_find_prop_id(unsigned int prop_id);
+
+#endif /* _TDM_EXYNOS_CAPTURE_LEGACY_H_ */
diff --git a/src/libtdm-exynos/tdm_exynos_display.c b/src/libtdm-exynos/tdm_exynos_display.c
new file mode 100644 (file)
index 0000000..a5993fb
--- /dev/null
@@ -0,0 +1,740 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <drm_fourcc.h>
+#include <tdm_helper.h>
+#include "tdm_exynos.h"
+
+#define LAYER_COUNT_FOR_NOT_FIXED           2
+#define LAYER_PRIMARY_INDEX_FOR_NOT_FIXED   1
+
+static tdm_error
+_tdm_exynos_display_create_layer_list_type(tdm_exynos_data *exynos_data)
+{
+       tdm_error ret;
+       int i;
+
+       for (i = 0; i < exynos_data->plane_res->count_planes; i++) {
+               tdm_exynos_output_data *output_data = NULL;
+               tdm_exynos_layer_data *layer_data;
+               drmModePlanePtr plane;
+               unsigned int type = 0;
+               int output_find = 0;
+
+               plane = drmModeGetPlane(exynos_data->drm_fd, exynos_data->plane_res->planes[i]);
+               if (!plane) {
+                       TDM_ERR("no plane");
+                       continue;
+               }
+
+               ret = tdm_exynos_display_get_property(exynos_data,
+                                                                                         exynos_data->plane_res->planes[i],
+                                                                                         DRM_MODE_OBJECT_PLANE, "type", &type, NULL);
+               if (ret != TDM_ERROR_NONE) {
+                       TDM_ERR("plane(%d) doesn't have 'type' info",
+                                       exynos_data->plane_res->planes[i]);
+                       drmModeFreePlane(plane);
+                       continue;
+               }
+
+               layer_data = calloc(1, sizeof(tdm_exynos_layer_data));
+               if (!layer_data) {
+                       TDM_ERR("alloc failed");
+                       drmModeFreePlane(plane);
+                       continue;
+               }
+
+               LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link) {
+                       if (plane->possible_crtcs & (1 << output_data->pipe)) {
+                               output_find = 1;
+                               break;
+                       }
+               }
+
+               if (!output_find) {
+                       TDM_ERR("plane(%d) couldn't found proper output", plane->plane_id);
+                       drmModeFreePlane(plane);
+                       free(layer_data);
+                       continue;
+               }
+
+               layer_data->exynos_data = exynos_data;
+               layer_data->output_data = output_data;
+               layer_data->plane_id = exynos_data->plane_res->planes[i];
+
+               if (type == DRM_PLANE_TYPE_CURSOR) {
+                       layer_data->capabilities = TDM_LAYER_CAPABILITY_CURSOR |
+                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
+                       layer_data->zpos = 2;
+               } else if (type == DRM_PLANE_TYPE_OVERLAY) {
+                       layer_data->capabilities = TDM_LAYER_CAPABILITY_OVERLAY |
+                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
+                       layer_data->zpos = 1;
+               } else if (type == DRM_PLANE_TYPE_PRIMARY) {
+                       layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY |
+                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
+                       layer_data->zpos = 0;
+                       output_data->primary_layer = layer_data;
+               } else {
+                       drmModeFreePlane(plane);
+                       free(layer_data);
+                       continue;
+               }
+
+               TDM_DBG("layer_data(%p) plane_id(%d) crtc_id(%d) zpos(%d) capabilities(%x)",
+                               layer_data, layer_data->plane_id, layer_data->output_data->crtc_id,
+                               layer_data->zpos, layer_data->capabilities);
+
+               LIST_ADDTAIL(&layer_data->link, &output_data->layer_list);
+
+               drmModeFreePlane(plane);
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+static tdm_error
+_tdm_exynos_display_create_layer_list_immutable_zpos(tdm_exynos_data *exynos_data)
+{
+       tdm_error ret;
+       int i;
+
+       for (i = 0; i < exynos_data->plane_res->count_planes; i++) {
+               tdm_exynos_output_data *output_data = NULL;
+               tdm_exynos_layer_data *layer_data;
+               drmModePlanePtr plane;
+               unsigned int type = 0, zpos = 0;
+               int output_find = 0;
+
+               plane = drmModeGetPlane(exynos_data->drm_fd, exynos_data->plane_res->planes[i]);
+               if (!plane) {
+                       TDM_ERR("no plane");
+                       continue;
+               }
+
+               ret = tdm_exynos_display_get_property(exynos_data,
+                                                                                         exynos_data->plane_res->planes[i],
+                                                                                         DRM_MODE_OBJECT_PLANE, "type", &type, NULL);
+               if (ret != TDM_ERROR_NONE) {
+                       TDM_ERR("plane(%d) doesn't have 'type' info",
+                                       exynos_data->plane_res->planes[i]);
+                       drmModeFreePlane(plane);
+                       continue;
+               }
+
+               ret = tdm_exynos_display_get_property(exynos_data,
+                                                                                         exynos_data->plane_res->planes[i],
+                                                                                         DRM_MODE_OBJECT_PLANE, "zpos", &zpos, NULL);
+               if (ret != TDM_ERROR_NONE) {
+                       TDM_ERR("plane(%d) doesn't have 'zpos' info",
+                                       exynos_data->plane_res->planes[i]);
+                       drmModeFreePlane(plane);
+                       continue;
+               }
+
+               layer_data = calloc(1, sizeof(tdm_exynos_layer_data));
+               if (!layer_data) {
+                       TDM_ERR("alloc failed");
+                       drmModeFreePlane(plane);
+                       continue;
+               }
+
+               LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link) {
+                       if (plane->possible_crtcs & (1 << output_data->pipe)) {
+                               output_find = 1;
+                               break;
+                       }
+               }
+
+               if (!output_find) {
+                       TDM_ERR("plane(%d) couldn't found proper output", plane->plane_id);
+                       drmModeFreePlane(plane);
+                       free(layer_data);
+                       continue;
+               }
+
+               layer_data->exynos_data = exynos_data;
+               layer_data->output_data = output_data;
+               layer_data->plane_id = exynos_data->plane_res->planes[i];
+               layer_data->zpos = zpos;
+
+               if (type == DRM_PLANE_TYPE_CURSOR)
+                       layer_data->capabilities = TDM_LAYER_CAPABILITY_CURSOR |
+                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
+               else if (type == DRM_PLANE_TYPE_OVERLAY)
+                       layer_data->capabilities = TDM_LAYER_CAPABILITY_OVERLAY |
+                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
+               else if (type == DRM_PLANE_TYPE_PRIMARY) {
+                       layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY |
+                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
+                       output_data->primary_layer = layer_data;
+               } else {
+                       drmModeFreePlane(plane);
+                       free(layer_data);
+                       continue;
+               }
+
+               TDM_DBG("layer_data(%p) plane_id(%d) crtc_id(%d) zpos(%d) capabilities(%x)",
+                               layer_data, layer_data->plane_id, layer_data->output_data->crtc_id,
+                               layer_data->zpos, layer_data->capabilities);
+
+               LIST_ADDTAIL(&layer_data->link, &output_data->layer_list);
+
+               drmModeFreePlane(plane);
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+/* Only in case of 1 output and 5 layers. For other cases, kernel should give
+ * the proper information. And _tdm_exynos_display_create_layer_list_immutable_zpos
+ * should be called.
+ */
+static tdm_error
+_tdm_exynos_display_create_layer_list_not_fixed(tdm_exynos_data *exynos_data)
+{
+       int find_pipe = -1;
+       int zpos = 0;
+       int output_count, i;
+
+       output_count = LIST_LENGTH(&exynos_data->output_list);
+
+       if (exynos_data->plane_res->count_planes < (output_count * LAYER_COUNT_FOR_NOT_FIXED)) {
+               TDM_ERR("not enough layers");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       for (i = 0; i < exynos_data->plane_res->count_planes; i++) {
+               tdm_exynos_output_data *output_data = NULL;
+               tdm_exynos_layer_data *layer_data;
+               drmModePlanePtr plane;
+
+               plane = drmModeGetPlane(exynos_data->drm_fd, exynos_data->plane_res->planes[i]);
+               if (!plane) {
+                       TDM_ERR("no plane");
+                       continue;
+               }
+
+               layer_data = calloc(1, sizeof(tdm_exynos_layer_data));
+               if (!layer_data) {
+                       TDM_ERR("alloc failed");
+                       drmModeFreePlane(plane);
+                       continue;
+               }
+
+               if (i % LAYER_COUNT_FOR_NOT_FIXED == 0) {
+                       find_pipe++;
+                       zpos = 0;
+               }
+
+               LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link) {
+                       if (output_data->pipe == find_pipe)
+                               break;
+               }
+
+               layer_data->exynos_data = exynos_data;
+               layer_data->output_data = output_data;
+               layer_data->plane_id = exynos_data->plane_res->planes[i];
+
+               layer_data->zpos = zpos++;
+
+               if (layer_data->zpos == LAYER_PRIMARY_INDEX_FOR_NOT_FIXED) {
+                       layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY |
+                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
+                       output_data->primary_layer = layer_data;
+               } else {
+                       tdm_error ret;
+
+                       layer_data->capabilities = TDM_LAYER_CAPABILITY_OVERLAY |
+                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
+
+                       ret = tdm_exynos_display_set_property(exynos_data, layer_data->plane_id,
+                                                                                                 DRM_MODE_OBJECT_PLANE, "zpos", layer_data->zpos);
+                       if (ret != TDM_ERROR_NONE) {
+                               drmModeFreePlane(plane);
+                               free(layer_data);
+                               return TDM_ERROR_OPERATION_FAILED;
+                       }
+               }
+
+               TDM_DBG("layer_data(%p) plane_id(%d) crtc_id(%d) zpos(%d) capabilities(%x)",
+                               layer_data, layer_data->plane_id, layer_data->output_data->crtc_id,
+                               layer_data->zpos, layer_data->capabilities);
+
+               LIST_ADDTAIL(&layer_data->link, &output_data->layer_list);
+
+               drmModeFreePlane(plane);
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+void
+tdm_exynos_display_to_tdm_mode(drmModeModeInfoPtr drm_mode,
+                                                                               tdm_output_mode *tdm_mode)
+{
+       tdm_mode->clock = drm_mode->clock;
+       if (exynos_screen_prerotation_hint % 180) {
+               tdm_mode->hdisplay = drm_mode->vdisplay;
+               tdm_mode->hsync_start = drm_mode->vsync_start;
+               tdm_mode->hsync_end = drm_mode->vsync_end;
+               tdm_mode->htotal = drm_mode->vtotal;
+               tdm_mode->vdisplay = drm_mode->hdisplay;
+               tdm_mode->vsync_start = drm_mode->hsync_start;
+               tdm_mode->vsync_end = drm_mode->hsync_end;
+               tdm_mode->vtotal = drm_mode->htotal;
+       } else {
+               tdm_mode->hdisplay = drm_mode->hdisplay;
+               tdm_mode->hsync_start = drm_mode->hsync_start;
+               tdm_mode->hsync_end = drm_mode->hsync_end;
+               tdm_mode->htotal = drm_mode->htotal;
+               tdm_mode->vdisplay = drm_mode->vdisplay;
+               tdm_mode->vsync_start = drm_mode->vsync_start;
+               tdm_mode->vsync_end = drm_mode->vsync_end;
+               tdm_mode->vtotal = drm_mode->vtotal;
+       }
+       tdm_mode->hskew = drm_mode->hskew;
+       tdm_mode->vscan = drm_mode->vscan;
+       tdm_mode->vrefresh = drm_mode->vrefresh;
+       tdm_mode->flags = drm_mode->flags;
+       tdm_mode->type = drm_mode->type;
+       snprintf(tdm_mode->name, TDM_NAME_LEN, "%s", drm_mode->name);
+}
+
+tdm_error
+tdm_exynos_display_create_layer_list(tdm_exynos_data *exynos_data)
+{
+       tdm_exynos_output_data *output_data = NULL;
+       tdm_error ret;
+
+       if (!exynos_data->has_zpos_info)
+               ret = _tdm_exynos_display_create_layer_list_type(exynos_data);
+       else if (exynos_data->is_immutable_zpos)
+               ret = _tdm_exynos_display_create_layer_list_immutable_zpos(exynos_data);
+       else
+               ret = _tdm_exynos_display_create_layer_list_not_fixed(exynos_data);
+
+       if (ret != TDM_ERROR_NONE)
+               return ret;
+
+       LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link) {
+               if (!output_data->primary_layer) {
+                       TDM_ERR("output(%d) no primary layer", output_data->pipe);
+                       return TDM_ERROR_OPERATION_FAILED;
+               }
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+void
+tdm_exynos_display_destroy_output_list(tdm_exynos_data *exynos_data)
+{
+       tdm_exynos_output_data *o = NULL, *oo = NULL;
+
+       if (LIST_IS_EMPTY(&exynos_data->output_list))
+               return;
+
+       LIST_FOR_EACH_ENTRY_SAFE(o, oo, &exynos_data->output_list, link) {
+               LIST_DEL(&o->link);
+               if (!LIST_IS_EMPTY(&o->layer_list)) {
+                       tdm_exynos_layer_data *l = NULL, *ll = NULL;
+                       LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link) {
+                               LIST_DEL(&l->link);
+                               if (l->display_buffer)
+                                       tbm_surface_internal_unref(l->display_buffer->buffer);
+                               if (l->formats)
+                                       free(l->formats);
+                               if (l->props)
+                                       free(l->props);
+                               free(l);
+                       }
+               }
+               free(o->drm_modes);
+               free(o->output_modes);
+               free(o);
+       }
+}
+
+void
+tdm_exynos_display_update_output_status(tdm_exynos_data *exynos_data)
+{
+       tdm_exynos_output_data *output_data = NULL;
+
+       if (LIST_IS_EMPTY(&exynos_data->output_list))
+               return;
+
+       LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link) {
+               drmModeConnectorPtr connector;
+               tdm_output_conn_status new_status;
+
+               connector = drmModeGetConnector(exynos_data->drm_fd,
+                                                                               output_data->connector_id);
+               if (!connector) {
+                       TDM_ERR("no connector: %d", output_data->connector_id);
+                       continue;
+               }
+
+               if (connector->connection == DRM_MODE_CONNECTED)
+                       new_status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
+               else
+                       new_status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+
+               tdm_exynos_output_update_status(output_data, new_status);
+
+               drmModeFreeConnector(connector);
+       }
+}
+
+tdm_error
+tdm_exynos_display_create_output_list(tdm_exynos_data *exynos_data)
+{
+       tdm_exynos_output_data *output_data;
+       int i;
+       tdm_error ret;
+       int allocated = 0;
+
+       RETURN_VAL_IF_FAIL(LIST_IS_EMPTY(&exynos_data->output_list),
+                                          TDM_ERROR_OPERATION_FAILED);
+
+       for (i = 0; i < exynos_data->mode_res->count_connectors; i++) {
+               drmModeConnectorPtr connector;
+               drmModeEncoderPtr encoder;
+               int crtc_id = 0, c, j;
+
+               connector = drmModeGetConnector(exynos_data->drm_fd,
+                                                                               exynos_data->mode_res->connectors[i]);
+               if (!connector) {
+                       TDM_ERR("no connector");
+                       ret = TDM_ERROR_OPERATION_FAILED;
+                       goto failed_create;
+               }
+
+               if (connector->count_encoders != 1) {
+                       TDM_ERR("too many encoders: %d", connector->count_encoders);
+                       drmModeFreeConnector(connector);
+                       ret = TDM_ERROR_OPERATION_FAILED;
+                       goto failed_create;
+               }
+
+               encoder = drmModeGetEncoder(exynos_data->drm_fd, connector->encoders[0]);
+               if (!encoder) {
+                       TDM_ERR("no encoder");
+                       drmModeFreeConnector(connector);
+                       ret = TDM_ERROR_OPERATION_FAILED;
+                       goto failed_create;
+               }
+
+               for (c = 0; c < exynos_data->mode_res->count_crtcs; c++) {
+                       if (allocated & (1 << c))
+                               continue;
+
+                       if ((encoder->possible_crtcs & (1 << c)) == 0)
+                               continue;
+
+                       crtc_id = exynos_data->mode_res->crtcs[c];
+                       allocated |= (1 << c);
+                       break;
+               }
+
+               if (crtc_id == 0) {
+                       TDM_ERR("no possible crtc");
+                       drmModeFreeConnector(connector);
+                       drmModeFreeEncoder(encoder);
+                       ret = TDM_ERROR_OPERATION_FAILED;
+                       goto failed_create;
+               }
+
+               output_data = calloc(1, sizeof(tdm_exynos_output_data));
+               if (!output_data) {
+                       TDM_ERR("alloc failed");
+                       drmModeFreeConnector(connector);
+                       drmModeFreeEncoder(encoder);
+                       ret = TDM_ERROR_OUT_OF_MEMORY;
+                       goto failed_create;
+               }
+
+               LIST_INITHEAD(&output_data->layer_list);
+
+               output_data->exynos_data = exynos_data;
+               output_data->connector_id = exynos_data->mode_res->connectors[i];
+               output_data->encoder_id = encoder->encoder_id;
+               output_data->crtc_id = crtc_id;
+               output_data->pipe = c;
+               output_data->connector_type = connector->connector_type;
+               output_data->connector_type_id = connector->connector_type_id;
+
+               if (connector->connection == DRM_MODE_CONNECTED)
+                       output_data->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
+               else
+                       output_data->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+
+               for (j = 0; j < connector->count_props; j++) {
+                       drmModePropertyPtr prop = drmModeGetProperty(exynos_data->drm_fd,
+                                                                                                                connector->props[j]);
+                       if (!prop)
+                               continue;
+                       if (!strcmp(prop->name, "DPMS")) {
+                               output_data->dpms_prop_id = connector->props[j];
+                               drmModeFreeProperty(prop);
+                               break;
+                       }
+                       drmModeFreeProperty(prop);
+               }
+
+               output_data->count_modes = connector->count_modes;
+               output_data->drm_modes = calloc(connector->count_modes, sizeof(drmModeModeInfo));
+               if (!output_data->drm_modes) {
+                       TDM_ERR("alloc failed");
+                       free(output_data);
+                       drmModeFreeConnector(connector);
+                       drmModeFreeEncoder(encoder);
+                       ret = TDM_ERROR_OUT_OF_MEMORY;
+                       goto failed_create;
+               }
+               output_data->output_modes = calloc(connector->count_modes, sizeof(tdm_output_mode));
+               if (!output_data->output_modes) {
+                       TDM_ERR("alloc failed");
+                       free(output_data->drm_modes);
+                       free(output_data);
+                       drmModeFreeConnector(connector);
+                       drmModeFreeEncoder(encoder);
+                       ret = TDM_ERROR_OUT_OF_MEMORY;
+                       goto failed_create;
+               }
+               for (j = 0; j < connector->count_modes; j++) {
+                       output_data->drm_modes[j] = connector->modes[j];
+                       tdm_exynos_display_to_tdm_mode(&output_data->drm_modes[j],
+                                                                                  &output_data->output_modes[j]);
+               }
+
+               /* now E20 supported HWC API only for the main output */
+               if (output_data->exynos_data->hwc_mode &&
+                       output_data->connector_type == TDM_OUTPUT_TYPE_DSI) {
+                       output_data->hwc_enable = 1;
+               }
+
+               LIST_ADDTAIL(&output_data->link, &exynos_data->output_list);
+
+               TDM_DBG("output_data(%p) connector_id(%d:%d:%d-%d) encoder_id(%d) crtc_id(%d) pipe(%d) dpms_id(%d)",
+                               output_data, output_data->connector_id, output_data->status,
+                               output_data->connector_type,
+                               output_data->connector_type_id, output_data->encoder_id, output_data->crtc_id,
+                               output_data->pipe, output_data->dpms_prop_id);
+
+               drmModeFreeEncoder(encoder);
+               drmModeFreeConnector(connector);
+       }
+
+       TDM_DBG("output count: %d", exynos_data->mode_res->count_connectors);
+
+       return TDM_ERROR_NONE;
+failed_create:
+       tdm_exynos_display_destroy_output_list(exynos_data);
+       return ret;
+}
+
+tdm_error
+tdm_exynos_display_set_property(tdm_exynos_data *exynos_data,
+                                                                          unsigned int obj_id, unsigned int obj_type,
+                                                                          const char *name, unsigned int value)
+{
+       drmModeObjectPropertiesPtr props = NULL;
+       unsigned int i;
+
+       props = drmModeObjectGetProperties(exynos_data->drm_fd, obj_id, obj_type);
+       if (!props) {
+               TDM_ERR("drmModeObjectGetProperties failed: %m");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+       for (i = 0; i < props->count_props; i++) {
+               drmModePropertyPtr prop = drmModeGetProperty(exynos_data->drm_fd,
+                                                                                                        props->props[i]);
+               int ret;
+               if (!prop) {
+                       TDM_ERR("drmModeGetProperty failed: %m");
+                       drmModeFreeObjectProperties(props);
+                       return TDM_ERROR_OPERATION_FAILED;
+               }
+               if (!strcmp(prop->name, name)) {
+                       ret = drmModeObjectSetProperty(exynos_data->drm_fd, obj_id, obj_type,
+                                                                                  prop->prop_id, value);
+                       if (ret < 0) {
+                               TDM_ERR("drmModeObjectSetProperty failed: %m");
+                               drmModeFreeProperty(prop);
+                               drmModeFreeObjectProperties(props);
+                               return TDM_ERROR_OPERATION_FAILED;
+                       }
+                       drmModeFreeProperty(prop);
+                       drmModeFreeObjectProperties(props);
+                       return TDM_ERROR_NONE;
+               }
+               drmModeFreeProperty(prop);
+       }
+
+       TDM_ERR("not found '%s' property", name);
+
+       drmModeFreeObjectProperties(props);
+       /* TODO
+       * kernel info error
+       * it must be changed to 'return TDM_ERROR_OPERATION_FAILED' after kernel fix.
+       */
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+tdm_exynos_display_get_property(tdm_exynos_data *exynos_data,
+                                                                          unsigned int obj_id, unsigned int obj_type,
+                                                                          const char *name, unsigned int *value, int *is_immutable)
+{
+       drmModeObjectPropertiesPtr props = NULL;
+       int i;
+
+       props = drmModeObjectGetProperties(exynos_data->drm_fd, obj_id, obj_type);
+       if (!props)
+               return TDM_ERROR_OPERATION_FAILED;
+
+       for (i = 0; i < props->count_props; i++) {
+               drmModePropertyPtr prop = drmModeGetProperty(exynos_data->drm_fd,
+                                                                                                        props->props[i]);
+
+               if (!prop)
+                       continue;
+
+               if (!strcmp(prop->name, name)) {
+                       if (is_immutable)
+                               *is_immutable = prop->flags & DRM_MODE_PROP_IMMUTABLE;
+                       if (value)
+                               *value = (unsigned int)props->prop_values[i];
+                       drmModeFreeProperty(prop);
+                       drmModeFreeObjectProperties(props);
+                       return TDM_ERROR_NONE;
+               }
+
+               drmModeFreeProperty(prop);
+       }
+       drmModeFreeObjectProperties(props);
+       TDM_DBG("coundn't find '%s' property", name);
+       return TDM_ERROR_OPERATION_FAILED;
+}
+
+tdm_error
+exynos_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps)
+{
+       RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
+
+       caps->max_layer_count = -1; /* not defined */
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps)
+{
+       tdm_exynos_data *exynos_data = bdata;
+       if (exynos_data->use_ippv2)
+               return tdm_exynos_pp_get_capability(bdata, caps);
+       else
+               return tdm_exynos_pp_legacy_get_capability(bdata, caps);
+}
+
+tdm_error
+exynos_display_get_capture_capability(tdm_backend_data *bdata, tdm_caps_capture *caps)
+{
+       tdm_exynos_data *exynos_data = bdata;
+       if (exynos_data->use_ippv2)
+               return tdm_exynos_capture_get_capability(bdata, caps);
+       else
+               return tdm_exynos_capture_legacy_get_capability(bdata, caps);
+}
+
+tdm_output **
+exynos_display_get_outputs(tdm_backend_data *bdata, int *count,
+                                                                tdm_error *error)
+{
+       tdm_exynos_data *exynos_data = bdata;
+       tdm_exynos_output_data *output_data = NULL;
+       tdm_output **outputs;
+       tdm_error ret;
+       int i;
+
+       RETURN_VAL_IF_FAIL(exynos_data, NULL);
+       RETURN_VAL_IF_FAIL(count, NULL);
+
+       *count = 0;
+       LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link)
+       (*count)++;
+
+       if (*count == 0) {
+               ret = TDM_ERROR_NONE;
+               goto failed_get;
+       }
+
+       /* will be freed in frontend */
+       outputs = calloc(*count, sizeof(tdm_exynos_output_data *));
+       if (!outputs) {
+               TDM_ERR("failed: alloc memory");
+               *count = 0;
+               ret = TDM_ERROR_OUT_OF_MEMORY;
+               goto failed_get;
+       }
+
+       i = 0;
+       LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link)
+       outputs[i++] = output_data;
+
+       if (error)
+               *error = TDM_ERROR_NONE;
+
+       return outputs;
+failed_get:
+       if (error)
+               *error = ret;
+       return NULL;
+}
+
+tdm_error
+exynos_display_get_fd(tdm_backend_data *bdata, int *fd)
+{
+       tdm_exynos_data *exynos_data = bdata;
+
+       RETURN_VAL_IF_FAIL(exynos_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(fd, TDM_ERROR_INVALID_PARAMETER);
+
+       *fd = exynos_data->drm_fd;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_display_handle_events(tdm_backend_data *bdata)
+{
+       tdm_exynos_data *exynos_data = bdata;
+       drmEventContext ctx;
+
+       RETURN_VAL_IF_FAIL(exynos_data, TDM_ERROR_INVALID_PARAMETER);
+
+       memset(&ctx, 0, sizeof(drmEventContext));
+
+       ctx.version = DRM_EVENT_CONTEXT_VERSION;
+       ctx.page_flip_handler = tdm_exynos_output_cb_event;
+       ctx.vblank_handler = tdm_exynos_output_cb_event;
+
+       drmHandleEvent(exynos_data->drm_fd, &ctx);
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_pp *
+exynos_display_create_pp(tdm_backend_data *bdata, tdm_error *error)
+{
+       tdm_exynos_data *exynos_data = bdata;
+
+       RETURN_VAL_IF_FAIL(exynos_data, NULL);
+
+       if (exynos_data->use_ippv2)
+               return tdm_exynos_pp_create(exynos_data, error);
+       else
+               return tdm_exynos_pp_legacy_create(exynos_data, error);
+}
diff --git a/src/libtdm-exynos/tdm_exynos_display.h b/src/libtdm-exynos/tdm_exynos_display.h
new file mode 100644 (file)
index 0000000..94a1fe9
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _TDM_EXYNOS_DISPLAY_H_
+#define _TDM_EXYNOS_DISPLAY_H_
+
+#include "tdm_exynos.h"
+
+void         tdm_exynos_display_update_output_status(tdm_exynos_data *exynos_data);
+tdm_error    tdm_exynos_display_create_output_list(tdm_exynos_data *exynos_data);
+void         tdm_exynos_display_destroy_output_list(tdm_exynos_data *exynos_data);
+tdm_error    tdm_exynos_display_create_layer_list(tdm_exynos_data *exynos_data);
+tdm_error    tdm_exynos_display_set_property(tdm_exynos_data *exynos_data,
+                                                                                                       unsigned int obj_id, unsigned int obj_type,
+                                                                                                       const char *name, unsigned int value);
+tdm_error    tdm_exynos_display_get_property(tdm_exynos_data *exynos_data,
+                                                                                                       unsigned int obj_id, unsigned int obj_type,
+                                                                                                       const char *name, unsigned int *value, int *is_immutable);
+void         tdm_exynos_display_to_tdm_mode(drmModeModeInfoPtr drm_mode, tdm_output_mode *tdm_mode);
+
+
+#endif /* _TDM_EXYNOS_DISPLAY_H_ */
diff --git a/src/libtdm-exynos/tdm_exynos_format.c b/src/libtdm-exynos/tdm_exynos_format.c
new file mode 100644 (file)
index 0000000..9a030ad
--- /dev/null
@@ -0,0 +1,113 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <drm_fourcc.h>
+#include <tbm_surface.h>
+
+#include "tdm_exynos.h"
+
+#ifndef TBM_FORMAT_NV12MT
+#define TBM_FORMAT_NV12MT   FOURCC('T', 'M', '1', '2')
+#endif
+
+#ifndef DRM_FORMAT_12MT
+#define DRM_FORMAT_12MT     FOURCC('T', 'M', '1', '2')
+#endif
+
+typedef struct {
+       tbm_format  tbm_format;
+       uint32_t    drm_format;
+} tbm_exynos_format_data;
+
+static const tbm_exynos_format_data formats[] = {
+       {TBM_FORMAT_C8, DRM_FORMAT_C8},
+       {TBM_FORMAT_RGB332, DRM_FORMAT_RGB332},
+       {TBM_FORMAT_BGR233, DRM_FORMAT_BGR233},
+       {TBM_FORMAT_XRGB4444, DRM_FORMAT_XRGB4444},
+       {TBM_FORMAT_XBGR4444, DRM_FORMAT_XBGR4444},
+       {TBM_FORMAT_RGBX4444, DRM_FORMAT_RGBX4444},
+       {TBM_FORMAT_BGRX4444, DRM_FORMAT_BGRX4444},
+       {TBM_FORMAT_ARGB4444, DRM_FORMAT_ARGB4444},
+       {TBM_FORMAT_ABGR4444, DRM_FORMAT_ABGR4444},
+       {TBM_FORMAT_RGBA4444, DRM_FORMAT_RGBA4444},
+       {TBM_FORMAT_BGRA4444, DRM_FORMAT_BGRA4444},
+       {TBM_FORMAT_XRGB1555, DRM_FORMAT_XRGB1555},
+       {TBM_FORMAT_XBGR1555, DRM_FORMAT_XBGR1555},
+       {TBM_FORMAT_RGBX5551, DRM_FORMAT_RGBX5551},
+       {TBM_FORMAT_BGRX5551, DRM_FORMAT_BGRX5551},
+       {TBM_FORMAT_ARGB1555, DRM_FORMAT_ARGB1555},
+       {TBM_FORMAT_ABGR1555, DRM_FORMAT_ABGR1555},
+       {TBM_FORMAT_RGBA5551, DRM_FORMAT_RGBA5551},
+       {TBM_FORMAT_BGRA5551, DRM_FORMAT_BGRA5551},
+       {TBM_FORMAT_RGB565, DRM_FORMAT_RGB565},
+       {TBM_FORMAT_BGR565, DRM_FORMAT_BGR565},
+       {TBM_FORMAT_RGB888, DRM_FORMAT_RGB888},
+       {TBM_FORMAT_BGR888, DRM_FORMAT_BGR888},
+       {TBM_FORMAT_XRGB8888, DRM_FORMAT_XRGB8888},
+       {TBM_FORMAT_XBGR8888, DRM_FORMAT_XBGR8888},
+       {TBM_FORMAT_RGBX8888, DRM_FORMAT_RGBX8888},
+       {TBM_FORMAT_BGRX8888, DRM_FORMAT_BGRX8888},
+       {TBM_FORMAT_ARGB8888, DRM_FORMAT_ARGB8888},
+       {TBM_FORMAT_ABGR8888, DRM_FORMAT_ABGR8888},
+       {TBM_FORMAT_RGBA8888, DRM_FORMAT_RGBA8888},
+       {TBM_FORMAT_BGRA8888, DRM_FORMAT_BGRA8888},
+       {TBM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB2101010},
+       {TBM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR2101010},
+       {TBM_FORMAT_RGBX1010102, DRM_FORMAT_RGBX1010102},
+       {TBM_FORMAT_BGRX1010102, DRM_FORMAT_BGRX1010102},
+       {TBM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB2101010},
+       {TBM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR2101010},
+       {TBM_FORMAT_RGBA1010102, DRM_FORMAT_RGBA1010102},
+       {TBM_FORMAT_BGRA1010102, DRM_FORMAT_BGRA1010102},
+       {TBM_FORMAT_YUYV, DRM_FORMAT_YUYV},
+       {TBM_FORMAT_YVYU, DRM_FORMAT_YVYU},
+       {TBM_FORMAT_UYVY, DRM_FORMAT_UYVY},
+       {TBM_FORMAT_VYUY, DRM_FORMAT_VYUY},
+       {TBM_FORMAT_AYUV, DRM_FORMAT_AYUV},
+       {TBM_FORMAT_NV12, DRM_FORMAT_NV12},
+       {TBM_FORMAT_NV21, DRM_FORMAT_NV21},
+       {TBM_FORMAT_NV16, DRM_FORMAT_NV16},
+       {TBM_FORMAT_NV61, DRM_FORMAT_NV61},
+       {TBM_FORMAT_YUV410, DRM_FORMAT_YUV410},
+       {TBM_FORMAT_YVU410, DRM_FORMAT_YVU410},
+       {TBM_FORMAT_YUV411, DRM_FORMAT_YUV411},
+       {TBM_FORMAT_YVU411, DRM_FORMAT_YVU411},
+       {TBM_FORMAT_YUV420, DRM_FORMAT_YUV420},
+       {TBM_FORMAT_YVU420, DRM_FORMAT_YVU420},
+       {TBM_FORMAT_YUV422, DRM_FORMAT_YUV422},
+       {TBM_FORMAT_YVU422, DRM_FORMAT_YVU422},
+       {TBM_FORMAT_YUV444, DRM_FORMAT_YUV444},
+       {TBM_FORMAT_YVU444, DRM_FORMAT_YVU444},
+       {TBM_FORMAT_NV12MT, DRM_FORMAT_12MT},
+};
+
+#define NUM_FORMATS (sizeof(formats) / sizeof(formats[0]))
+
+uint32_t
+tdm_exynos_format_to_drm_format(tbm_format format)
+{
+       int i;
+
+       for (i = 0; i < NUM_FORMATS; i++)
+               if (formats[i].tbm_format == format)
+                       return formats[i].drm_format;
+
+       TDM_ERR("tbm format '%c%c%c%c' not found", FOURCC_STR(format));
+
+       return 0;
+}
+
+tbm_format
+tdm_exynos_format_to_tbm_format(uint32_t format)
+{
+       int i;
+
+       for (i = 0; i < NUM_FORMATS; i++)
+               if (formats[i].drm_format == format)
+                       return formats[i].tbm_format;
+
+       TDM_ERR("drm format '%c%c%c%c' not found", FOURCC_STR(format));
+
+       return 0;
+}
diff --git a/src/libtdm-exynos/tdm_exynos_format.h b/src/libtdm-exynos/tdm_exynos_format.h
new file mode 100644 (file)
index 0000000..f41400c
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _TDM_EXYNOS_FORMAT_H_
+#define _TDM_EXYNOS_FORMAT_H_
+
+#include "tdm_exynos.h"
+
+uint32_t     tdm_exynos_format_to_drm_format(tbm_format format);
+tbm_format   tdm_exynos_format_to_tbm_format(uint32_t format);
+
+#endif /* _TDM_EXYNOS_FORMAT_H_ */
diff --git a/src/libtdm-exynos/tdm_exynos_hwc.c b/src/libtdm-exynos/tdm_exynos_hwc.c
new file mode 100644 (file)
index 0000000..b8a5bc6
--- /dev/null
@@ -0,0 +1,714 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tdm_helper.h>
+#include "tdm_exynos.h"
+
+#define MIN_WIDTH   32
+
+tdm_hwc_window *
+_exynos_hwc_create_window(tdm_hwc *hwc, tdm_hwc_window_info *info,
+                                                                tdm_error *error);
+
+const char *
+_comp_to_str(tdm_hwc_window_composition composition_type)
+{
+       if (composition_type == TDM_HWC_WIN_COMPOSITION_CLIENT)
+               return "CLIENT";
+       else if (composition_type == TDM_HWC_WIN_COMPOSITION_DEVICE)
+               return "DEVICE";
+       else if (composition_type == TDM_HWC_WIN_COMPOSITION_CURSOR)
+               return "CURSOR";
+       else if (composition_type == TDM_HWC_WIN_COMPOSITION_VIDEO)
+               return "VIDEO";
+       else if (composition_type == TDM_HWC_WIN_COMPOSITION_NONE)
+               return "SKIP";
+
+       return "unknown";
+}
+
+static int
+_can_set_hwc_window_on_hw_layer(tdm_exynos_hwc_window_data *hwc_window_data)
+{
+       if (!hwc_window_data->surface)
+               return 0;
+
+       if (hwc_window_data->info.transform != TDM_TRANSFORM_NORMAL)
+               return 0;
+
+       if (hwc_window_data->info.src_config.pos.w != hwc_window_data->info.dst_pos.w)
+               return 0;
+
+       if (hwc_window_data->info.src_config.pos.h != hwc_window_data->info.dst_pos.h)
+               return 0;
+
+       if (!IS_RGB(hwc_window_data->info.src_config.format))
+               return 0;
+
+       if (hwc_window_data->info.dst_pos.x > hwc_window_data->hwc_data->output_data->current_mode->hdisplay ||
+               hwc_window_data->info.dst_pos.y > hwc_window_data->hwc_data->output_data->current_mode->vdisplay)
+               return 0;
+
+       if (hwc_window_data->info.src_config.size.h < MIN_WIDTH || hwc_window_data->info.src_config.size.h % 2)
+               return 0;
+
+       return 1;
+}
+
+tdm_exynos_layer_data *
+_exynos_hwc_get_layer(tdm_exynos_hwc_data *hwc_data, int zpos)
+{
+       tdm_exynos_output_data *output_data = hwc_data->output_data;
+       tdm_exynos_layer_data *l = NULL;
+
+       LIST_FOR_EACH_ENTRY(l, &output_data->layer_list, link)
+               if (l->zpos == zpos)
+                       return l;
+
+       return NULL;
+}
+
+static tdm_error
+_set_hwc_window_buffer_to_layer(tdm_exynos_layer_data *layer_data,
+                                                               tdm_exynos_hwc_window_data *hwc_window_data)
+{
+       tdm_error ret;
+
+       if (hwc_window_data == NULL || !hwc_window_data->surface) {
+               ret = exynos_layer_unset_buffer(layer_data);
+       } else {
+               ret = exynos_layer_set_buffer(layer_data, hwc_window_data->surface);
+       }
+
+       RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+
+       return ret;
+}
+
+static tdm_exynos_hwc_window_data *
+_find_maped_hwc_window_to_layer(struct list_head *hwc_wnds, int layer_zpos)
+{
+       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
+
+       LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
+               if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
+                       continue;
+
+               if (hwc_window_data->assigned_layer_zpos == layer_zpos &&
+                       (hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_DEVICE ||
+                        hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_CURSOR ||
+                        hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_VIDEO)) {
+                               TDM_DBG(" window(%p) type: %s -> %s : candidate_zpos:%d assigned_zpos:%d", hwc_window_data,
+                                               _comp_to_str(hwc_window_data->client_type), _comp_to_str(hwc_window_data->validated_type),
+                                               hwc_window_data->candidate_layer_zpos, hwc_window_data->assigned_layer_zpos);
+                               return hwc_window_data;
+                }
+       }
+
+       return NULL;
+}
+
+static void
+_update_layers_info(tdm_exynos_hwc_data *hwc_data)
+{
+       tdm_exynos_layer_data *layer = NULL;
+       tdm_exynos_output_data *output_data = hwc_data->output_data;
+       tdm_exynos_hwc_window_data *hwc_window_data;
+       tdm_error ret;
+
+       LIST_FOR_EACH_ENTRY(layer, &output_data->layer_list, link) {
+               if (hwc_data->need_target_window && layer->zpos == hwc_data->target_window_zpos)
+                       hwc_window_data = hwc_data->target_hwc_window;
+               else
+                       hwc_window_data = _find_maped_hwc_window_to_layer(&hwc_data->hwc_window_list, layer->zpos);
+
+               if (hwc_window_data) {
+                       ret = exynos_layer_set_info((tdm_layer *)layer, (tdm_info_layer *)&(hwc_window_data->info));
+                       if (ret != TDM_ERROR_NONE)
+                               TDM_ERR("cannot set info to layer with %d zpos", layer->zpos);
+               }
+       }
+}
+
+static tdm_exynos_hwc_window_data *
+_exynos_hwc_find_assigned_hwc_window(struct list_head *hwc_wnds, int layer_zpos)
+{
+       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
+
+       LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
+               if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
+                       continue;
+
+               if (hwc_window_data->assigned_layer_zpos == layer_zpos) {
+                       return hwc_window_data;
+               }
+       }
+
+       return NULL;
+}
+
+static tdm_error
+_exynos_hwc_prepare_commit(tdm_exynos_hwc_data *hwc_data) {
+       tdm_exynos_layer_data *layer = NULL;
+       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
+       tdm_exynos_output_data *output_data = hwc_data->output_data;
+
+       _update_layers_info(hwc_data);
+
+       /* set target hwc window */
+       if (hwc_data->need_target_window) {
+               layer = _exynos_hwc_get_layer(hwc_data, hwc_data->target_window_zpos);
+               _set_hwc_window_buffer_to_layer(layer, hwc_data->target_hwc_window);
+       }
+
+       LIST_FOR_EACH_ENTRY(layer, &output_data->layer_list, link) {
+               if (hwc_data->need_target_window && layer == output_data->primary_layer)
+                       continue;
+
+               hwc_window_data = _exynos_hwc_find_assigned_hwc_window(&hwc_data->hwc_window_list, layer->zpos);
+               if (hwc_window_data) {
+                       _set_hwc_window_buffer_to_layer(layer, hwc_window_data);
+               } else {
+                       /* do not set the null on the primary layer */
+                       if (layer != output_data->primary_layer)
+                               _set_hwc_window_buffer_to_layer(layer, NULL);
+               }
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+static int
+_exynos_hwc_get_primary_layer_zpos(tdm_exynos_hwc_data *hwc_data)
+{
+       tdm_exynos_output_data *output_data = hwc_data->output_data;
+       tdm_exynos_layer_data *layer = NULL;
+
+       LIST_FOR_EACH_ENTRY(layer, &output_data->layer_list, link) {
+               if (layer->capabilities & TDM_LAYER_CAPABILITY_PRIMARY)
+                       return layer->zpos;
+       }
+
+       return 0;
+}
+
+/* decide the validated_types and the assigned_layer_zpos of the hwc_windows */
+static void
+_exynos_hwc_adapt_policy(tdm_exynos_hwc_data *hwc_data , tdm_hwc_window **composited_wnds, uint32_t num_wnds)
+{
+       tdm_exynos_output_data *output_data = hwc_data->output_data;
+       tdm_exynos_hwc_window_data **composited_list = NULL;
+       int num_visible_windows = num_wnds;
+       int available_layers = LIST_LENGTH(&output_data->layer_list);
+       int num_videos = 0, num_clients = 0;
+       int min_zpos = 0, max_zpos = 0;
+       int i;
+
+       composited_list = (tdm_exynos_hwc_window_data**)composited_wnds;
+
+       TDM_DBG("1. available_layers=%d, primary_layer_zpos=%d, num_visible_windows=%d",
+                       available_layers, _exynos_hwc_get_primary_layer_zpos(hwc_data), num_visible_windows);
+
+       if (output_data->status != TDM_OUTPUT_CONN_STATUS_MODE_SETTED) {
+               hwc_data->target_window_zpos = _exynos_hwc_get_primary_layer_zpos(hwc_data);
+               hwc_data->need_target_window = 1;
+               goto set_all_client_types;
+       } else {
+               /* initialize the zpos of the target_window */
+               hwc_data->target_window_zpos = _exynos_hwc_get_primary_layer_zpos(hwc_data);
+               hwc_data->need_target_window = 0;
+       }
+
+       /* need_target_window is true and return when there are no visible windows */
+       if (!num_visible_windows) {
+               hwc_data->need_target_window = 1;
+               return;
+       }
+
+       /* reset the validated_type and hw layer policy */
+       for (i = 0; i < num_wnds; i++) {
+               if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_VIDEO) {
+                       composited_list[i]->validated_type = composited_list[i]->client_type;
+                       composited_list[i]->candidate_layer_zpos = 0;
+                       ++num_videos;
+                       /* The video window occupies the bottom layer */
+                       ++min_zpos;
+                       --available_layers;
+                       continue;
+               }
+
+               composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CLIENT;
+               composited_list[i]->candidate_layer_zpos = -1;
+
+               /* The validate type of all windows below this window are TDM_HWC_WIN_COMPOSITION_CLIENT
+                * if the upper window is TDM_COMPSITION_CLIENT type.
+                */
+               if (num_clients > 0) {
+                       ++num_clients;
+                       continue;
+               }
+
+               /* increase the num_clients when the type of the window is TDM_COMPOSITE_CLIENT. */
+               if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_CLIENT) {
+                       ++num_clients;
+                       /* need target_window to composite */
+                       ++min_zpos;
+                       --available_layers;
+                       hwc_data->need_target_window = 1;
+               }
+       }
+
+       /* calculate the num windows which can be the candidates */
+       num_visible_windows = num_visible_windows - num_clients - num_videos;
+       if (num_visible_windows > available_layers) {
+               /* need target_window to composite if need_target_window is not set above */
+               if (hwc_data->need_target_window == 0) {
+                       if (num_videos > 0) {
+                               ++min_zpos;
+                               --available_layers;
+                       } else {
+                                min_zpos = min_zpos + 2;
+                                available_layers = available_layers - 2;
+                       }
+                       hwc_data->need_target_window = 1;
+               }
+               max_zpos = LIST_LENGTH(&output_data->layer_list) - 1;
+       } else {
+               if (num_visible_windows == 1)
+                       max_zpos = 1;
+               else
+                       max_zpos = min_zpos + num_visible_windows - 1;
+       }
+
+       TDM_DBG("2. available_layers=%d, max_zpos=%d, num_visible_windows=%d", available_layers, max_zpos, num_visible_windows);
+
+       /* assgin the hw layers to the ui windows from the top to the bottom */
+       for (i = 0; i < num_wnds; i++) {
+               if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_VIDEO)
+                       continue;
+               if (available_layers == 0)
+                       break;
+
+               if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_DEVICE ||
+                   composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_CURSOR) {
+                       if (_can_set_hwc_window_on_hw_layer(composited_list[i])) {
+                               composited_list[i]->validated_type = composited_list[i]->client_type;
+                               composited_list[i]->candidate_layer_zpos = max_zpos;
+                               max_zpos--;
+                               available_layers--;
+                       } else
+                               goto set_all_client_types;
+               }
+       }
+
+       return;
+
+set_all_client_types:
+       TDM_DBG("Set all windows to be CLIENT type due to hw restriction.!!");
+
+       for (i = 0; i < num_wnds; i++) {
+               if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_VIDEO)
+                       continue;
+
+               composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CLIENT;
+               composited_list[i]->candidate_layer_zpos = -1;
+       }
+
+       hwc_data->need_target_window = 1;
+       hwc_data->target_window_zpos = _exynos_hwc_get_primary_layer_zpos(hwc_data);;
+}
+
+static void
+_print_validate_result(tdm_exynos_hwc_data *hwc_data)
+{
+       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
+       int primary_layer_zpos = _exynos_hwc_get_primary_layer_zpos(hwc_data);
+
+       LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
+               if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
+                       continue;
+
+               if (hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_DEVICE ||
+                   hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_CURSOR ||
+                       hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_VIDEO)
+                       TDM_DBG(" window(%p) type: %s -> %s : is mapped to layer with %d zpos", hwc_window_data,
+                                       _comp_to_str(hwc_window_data->client_type), _comp_to_str(hwc_window_data->validated_type),
+                                       hwc_window_data->candidate_layer_zpos);
+               else
+                       TDM_DBG(" window(%p) type: %s -> %s : is composited to layer with %d zpos. need_target_window: %d", hwc_window_data,
+                                       _comp_to_str(hwc_window_data->client_type), _comp_to_str(hwc_window_data->validated_type),
+                                       primary_layer_zpos, hwc_data->need_target_window);
+       }
+}
+
+static void
+_exynos_hwc_assigned_layer_zpos_update(tdm_exynos_hwc_data *hwc_data)
+{
+       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
+
+       LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
+               if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
+                       continue;
+
+               if (hwc_window_data->candidate_layer_zpos == -1) {
+                       hwc_window_data->assigned_layer_zpos = -1;
+                       continue;
+               }
+
+               hwc_window_data->assigned_layer_zpos = hwc_window_data->candidate_layer_zpos;
+
+               TDM_DBG(" window(%p) type: %s -> %s : candidate_zpos:%d assigned_zpos:%d", hwc_window_data,
+                               _comp_to_str(hwc_window_data->client_type), _comp_to_str(hwc_window_data->validated_type),
+                               hwc_window_data->candidate_layer_zpos, hwc_window_data->assigned_layer_zpos);
+       }
+}
+
+static int
+_exynos_hwc_get_changed_number(tdm_exynos_hwc_data *hwc_data)
+{
+       int num = 0;
+       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
+
+       LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
+               if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
+                       continue;
+               if (hwc_window_data->client_type != hwc_window_data->validated_type)
+                       num++;
+       }
+
+       return num;
+}
+
+#if 0
+static int
+_exynos_hwc_exynos_hwc_get_primary_layer_zpos(tdm_exynos_hwc_data *hwc_data)
+{
+       tdm_exynos_output_data *output_data = hwc_data->output_data;
+       tdm_exynos_layer_data *layer = NULL;
+
+       LIST_FOR_EACH_ENTRY(layer, &output_data->layer_list, link) {
+               if (layer->capabilities & TDM_LAYER_CAPABILITY_PRIMARY)
+                       return layer->zpos;
+       }
+
+       return 0;
+}
+#endif
+
+static tbm_surface_queue_h
+_exynos_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
+{
+       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
+       tbm_surface_queue_h tqueue = NULL;
+       int width, height;
+       tbm_format format;
+
+       if (error)
+               *error = TDM_ERROR_INVALID_PARAMETER;
+
+       RETURN_VAL_IF_FAIL(hwc_window != NULL, NULL);
+
+       hwc_window_data = hwc_window;
+
+       width = hwc_window_data->info.src_config.size.h;
+       height = hwc_window_data->info.src_config.size.v;
+       format = hwc_window_data->info.src_config.format;
+
+       tqueue = tbm_surface_queue_create(3, width, height, format, TBM_BO_SCANOUT);
+       if (error)
+               *error = TDM_ERROR_OPERATION_FAILED;
+       RETURN_VAL_IF_FAIL(tqueue != NULL, NULL);
+
+       if (error)
+               *error = TDM_ERROR_NONE;
+
+       return tqueue;
+
+}
+
+tdm_hwc_window *
+_exynos_hwc_create_window(tdm_hwc *hwc, tdm_hwc_window_info *info, tdm_error *error)
+{
+       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
+       tdm_exynos_hwc_data *hwc_data = hwc;
+
+       if (error)
+               *error = TDM_ERROR_NONE;
+
+       if (!hwc_data) {
+               TDM_ERR("invalid params");
+               if (error)
+                       *error = TDM_ERROR_INVALID_PARAMETER;
+               return NULL;
+       }
+
+       hwc_window_data = calloc(1, sizeof(tdm_exynos_hwc_window_data));
+       if (!hwc_window_data) {
+               TDM_ERR("alloc failed");
+               if (error)
+                       *error = TDM_ERROR_OUT_OF_MEMORY;
+               return NULL;
+       }
+
+       hwc_window_data->client_type = TDM_HWC_WIN_COMPOSITION_NONE;
+       hwc_window_data->validated_type = -1;
+       hwc_window_data->assigned_layer_zpos = -1;
+
+       hwc_window_data->hwc_data = hwc_data;
+
+       if (info)
+               memcpy(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info));
+
+       LIST_INITHEAD(&hwc_window_data->link);
+
+       return hwc_window_data;
+}
+
+tdm_error
+exynos_hwc_initailize_target_window(tdm_exynos_hwc_data *hwc_data, int width, int height)
+{
+       tdm_hwc_window_info info = {0};
+       tdm_error ret = TDM_ERROR_NONE;
+       tdm_exynos_hwc_window_data *target_hwc_window;
+
+       RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
+
+       info.dst_pos.x = 0;
+       info.dst_pos.y = 0;
+       info.dst_pos.h = height;
+       info.dst_pos.w = width;
+
+       info.src_config.pos.x = 0;
+       info.src_config.pos.y = 0;
+       info.src_config.pos.h = height;
+       info.src_config.pos.w = width;
+
+       info.src_config.size.h = width;
+       info.src_config.size.v = height;
+       info.src_config.format = TBM_FORMAT_ARGB8888;
+
+       target_hwc_window = _exynos_hwc_create_window(hwc_data, &info, &ret);
+       if (target_hwc_window == NULL) {
+               TDM_ERR("create target hwc window failed (%d)", ret);
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       if (hwc_data->target_hwc_window)
+               exynos_hwc_window_destroy(hwc_data->target_hwc_window);
+
+       hwc_data->target_hwc_window = target_hwc_window;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_hwc_window *
+exynos_hwc_create_window(tdm_hwc *hwc, tdm_error *error)
+{
+       tdm_exynos_hwc_data *hwc_data = hwc;
+       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
+
+       hwc_window_data = _exynos_hwc_create_window(hwc_data, NULL, error);
+       if (hwc_window_data == NULL)
+               return NULL;
+
+       LIST_ADDTAIL(&hwc_window_data->link, &hwc_data->hwc_window_list);
+
+       TDM_DBG("hwc_window_data(%p) create", hwc_window_data);
+       if (error)
+               *error = TDM_ERROR_NONE;
+
+       return hwc_window_data;
+}
+
+tdm_error
+exynos_hwc_get_video_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count)
+{
+       tdm_exynos_hwc_data *hwc_data = hwc;
+
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       // TODO:
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *capabilities)
+{
+       tdm_exynos_hwc_data *hwc_data = hwc;
+
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       *capabilities = 0;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count)
+{
+       tdm_exynos_hwc_data *hwc_data = hwc;
+
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       // TODO:
+
+       return TDM_ERROR_NONE;
+}
+
+tbm_surface_queue_h
+exynos_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error)
+{
+       tdm_exynos_hwc_data *hwc_data = hwc;
+       tbm_surface_queue_h tqueue = NULL;
+
+       if (error)
+               *error = TDM_ERROR_INVALID_PARAMETER;
+
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, NULL);
+
+       if (hwc_data->target_hwc_window == NULL) {
+               if (error)
+                       *error = TDM_ERROR_OPERATION_FAILED;
+               return NULL;
+       }
+
+       tqueue = _exynos_hwc_window_get_tbm_buffer_queue(hwc_data->target_hwc_window, error);
+       RETURN_VAL_IF_FAIL(tqueue, NULL);
+
+       if (error)
+               *error = TDM_ERROR_NONE;
+
+       return tqueue;
+}
+
+tdm_error
+exynos_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer,
+                                                                       tdm_region damage)
+{
+       tdm_exynos_hwc_data *hwc_data = hwc;
+       tdm_error err;
+
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window  != NULL, TDM_ERROR_OPERATION_FAILED);
+
+       err = exynos_hwc_window_set_buffer(hwc_data->target_hwc_window, buffer);
+       RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
+
+       err = exynos_hwc_window_set_buffer_damage(hwc_data->target_hwc_window, damage);
+       RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds,    uint32_t num_wnds, uint32_t *num_types)
+{
+       tdm_exynos_hwc_data *hwc_data = hwc;
+
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       _exynos_hwc_adapt_policy(hwc_data, composited_wnds, num_wnds);
+
+       TDM_DBG(" ==============Validate=================================");
+       *num_types = _exynos_hwc_get_changed_number(hwc_data);
+       if (*num_types == 0) {
+               hwc_data->need_validate = 0;
+               _exynos_hwc_assigned_layer_zpos_update(hwc_data);
+               _print_validate_result(hwc_data);
+       } else {
+               _print_validate_result(hwc_data);
+               TDM_DBG(" !!!!!!! BUT NEED TO ACCEPT CHANES.!!!!!!!!");
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements, tdm_hwc_window **hwc_wnds,
+                                                                       tdm_hwc_window_composition *composition_types)
+{
+       tdm_exynos_hwc_data *hwc_data = hwc;
+       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
+       int num = 0;
+
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(num_elements != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       if ((hwc_wnds == NULL) || (composition_types == NULL)) {
+               *num_elements = _exynos_hwc_get_changed_number(hwc_data);
+               return TDM_ERROR_NONE;
+       }
+
+       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
+               if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
+                       continue;
+
+               if (num >= *num_elements)
+                       break;
+
+               if (hwc_window_data->client_type != hwc_window_data->validated_type) {
+                       composition_types[num] = hwc_window_data->validated_type;
+                       hwc_wnds[num] = hwc_window_data;
+                       num++;
+               }
+       }
+
+       /* set real num of changed composition types */
+       *num_elements = num;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_hwc_accept_validation(tdm_hwc *hwc)
+{
+       tdm_exynos_hwc_data *hwc_data = hwc;
+
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       TDM_DBG(" ==============Accept Changes Done=================================");
+
+       _exynos_hwc_assigned_layer_zpos_update(hwc_data);
+       hwc_data->need_validate = 0;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_hwc_commit(tdm_hwc *hwc, int sync, void *user_data)
+{
+       tdm_exynos_hwc_data *hwc_data = hwc;
+       tdm_exynos_output_data *output_data = NULL;
+       tdm_error ret;
+
+       RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
+
+       output_data = hwc_data->output_data;
+
+       ret = _exynos_hwc_prepare_commit(hwc_data);
+       RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+
+       ret = exynos_output_commit(output_data, sync, user_data);
+       RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func)
+{
+       tdm_exynos_hwc_data *hwc_data = hwc;
+
+       RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
+
+       hwc_data->commit_func = func;
+
+       return TDM_ERROR_NONE;
+}
\ No newline at end of file
diff --git a/src/libtdm-exynos/tdm_exynos_hwc.h b/src/libtdm-exynos/tdm_exynos_hwc.h
new file mode 100644 (file)
index 0000000..f14053c
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _TDM_EXYNOS_HWC_H_
+#define _TDM_EXYNOS_HWC_H_
+
+#include "tdm_exynos.h"
+
+tdm_error exynos_hwc_initailize_target_window(tdm_exynos_hwc_data *hwc_data, int width, int height);
+
+#endif /* _TDM_EXYNOS_HWC_H_ */
diff --git a/src/libtdm-exynos/tdm_exynos_hwc_window.c b/src/libtdm-exynos/tdm_exynos_hwc_window.c
new file mode 100644 (file)
index 0000000..23b352a
--- /dev/null
@@ -0,0 +1,146 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_exynos.h"
+
+tdm_exynos_layer_data *
+_exynos_output_get_layer(tdm_exynos_output_data *output_data, int index);
+
+void
+exynos_hwc_window_destroy(tdm_hwc_window *hwc_window)
+{
+       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
+
+       RETURN_IF_FAIL(hwc_window_data != NULL);
+
+       LIST_DEL(&hwc_window_data->link);
+
+       free(hwc_window_data);
+}
+
+tdm_error
+exynos_hwc_window_set_composition_type(tdm_hwc_window *hwc_window,
+                                                                       tdm_hwc_window_composition comp_type)
+{
+       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
+       tdm_exynos_hwc_data *hwc_data = hwc_window_data->hwc_data;
+
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       /* change the client_type when it is different from one which has before */
+       if (hwc_window_data->client_type == comp_type)
+               return TDM_ERROR_NONE;
+
+       hwc_window_data->client_type = comp_type;
+
+       /* if the type is none, reset all status */
+       if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE) {
+               hwc_window_data->client_type = TDM_HWC_WIN_COMPOSITION_NONE;
+               hwc_window_data->validated_type = -1;
+               hwc_window_data->candidate_layer_zpos = -1;
+               hwc_window_data->assigned_layer_zpos = -1;
+       }
+
+       hwc_data->need_validate = 1;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage)
+{
+       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
+       tdm_exynos_hwc_data *hwc_data = hwc_window_data->hwc_data;
+
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       /* TODO:: */
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
+{
+       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
+       tdm_exynos_hwc_data *hwc_data;
+
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       hwc_data = hwc_window_data->hwc_data;
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       if (!memcmp(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info)))
+               return TDM_ERROR_NONE;
+
+       hwc_window_data->info = *info;
+       hwc_data->need_validate = 1;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface)
+{
+       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
+       tdm_error err = TDM_ERROR_OPERATION_FAILED;
+
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, err);
+
+       if (hwc_window_data->surface == surface)
+               return TDM_ERROR_NONE;
+
+       hwc_window_data->surface = surface;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value)
+{
+       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
+
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+#if 0
+       output_data = hwc_window_data->output_data;
+       RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       layer_data = _exynos_output_get_layer(output_data, hwc_window_data->assigned_layer_zpos);
+
+       return exynos_layer_set_property(layer_data, id, value);
+#endif
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value)
+{
+       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
+
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+#if 0
+       output_data = hwc_window_data->output_data;
+       RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       layer_data = _exynos_output_get_layer(output_data, hwc_window_data->assigned_layer_zpos);
+
+       return exynos_layer_get_property(layer_data, id, value);
+#endif
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_hwc_window_get_constraints(tdm_hwc_window *hwc_window, int *constraints)
+{
+       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
+
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       return TDM_ERROR_NONE;
+}
diff --git a/src/libtdm-exynos/tdm_exynos_hwc_window.h b/src/libtdm-exynos/tdm_exynos_hwc_window.h
new file mode 100644 (file)
index 0000000..4237eb7
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _TDM_EXYNOS_HWC_WINDOW_H_
+#define _TDM_EXYNOS_HWC_WINDOW_H_
+
+#include "tdm_exynos.h"
+
+#endif /* _TDM_EXYNOS_HWC_WINDOW_H_ */
diff --git a/src/libtdm-exynos/tdm_exynos_layer.c b/src/libtdm-exynos/tdm_exynos_layer.c
new file mode 100644 (file)
index 0000000..cb326e4
--- /dev/null
@@ -0,0 +1,474 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <drm_fourcc.h>
+#include <tdm_helper.h>
+#include "tdm_exynos.h"
+
+static int tdm_exynos_buffer_key;
+#define TDM_EXYNOS_BUFFER_KEY ((unsigned long)&tdm_exynos_buffer_key)
+
+static void
+_tdm_exynos_display_buffer_destroy(void *user_data)
+{
+       tdm_exynos_display_buffer *display_buffer = (tdm_exynos_display_buffer *)user_data;
+
+       if (display_buffer->fb_id > 0) {
+               int ret = drmModeRmFB(display_buffer->exynos_data->drm_fd, display_buffer->fb_id);
+               if (ret < 0) {
+                       TDM_ERR("rm fb failed");
+                       return;
+               }
+               TDM_DBG("drmModeRmFB success!!! fb_id:%d", display_buffer->fb_id);
+       } else
+               TDM_DBG("drmModeRmFB not called fb_id:%d", display_buffer->fb_id);
+
+       free(display_buffer);
+}
+
+static tdm_exynos_display_buffer *
+_tdm_exynos_display_get_buffer(tdm_exynos_data *exynos_data, tbm_surface_h buffer)
+{
+       tdm_exynos_display_buffer *display_buffer = NULL;
+
+       if (!tbm_surface_internal_get_user_data(buffer, TDM_EXYNOS_BUFFER_KEY, (void **)&display_buffer)) {
+               unsigned int width;
+               unsigned int height;
+               unsigned int format;
+               unsigned int handles[4] = {0,};
+               unsigned int pitches[4] = {0,};
+               unsigned int offsets[4] = {0,};
+               unsigned int size;
+               tbm_bo bo;
+               int i, count, ret;
+
+               display_buffer = calloc(1, sizeof(tdm_exynos_display_buffer));
+               RETURN_VAL_IF_FAIL(display_buffer != NULL, NULL);
+
+               if (!tbm_surface_internal_add_user_data(buffer, TDM_EXYNOS_BUFFER_KEY, _tdm_exynos_display_buffer_destroy)) {
+                       TDM_ERR("FAIL to create user_data for surface %p", buffer);
+                       free(display_buffer);
+                       return NULL;
+               }
+               if (!tbm_surface_internal_set_user_data(buffer, TDM_EXYNOS_BUFFER_KEY, display_buffer)) {
+                       TDM_ERR("FAIL to set user_data for surface %p", buffer);
+                       tbm_surface_internal_delete_user_data(buffer, TDM_EXYNOS_BUFFER_KEY);
+                       free(display_buffer);
+                       return NULL;
+               }
+
+               display_buffer->exynos_data = exynos_data;
+               display_buffer->buffer = buffer;
+
+               width = tbm_surface_get_width(buffer);
+               height = tbm_surface_get_height(buffer);
+               format = tbm_surface_get_format(buffer);
+               count = tbm_surface_internal_get_num_planes(format);
+               bo = tbm_surface_internal_get_bo(buffer, 0);
+               handles[0] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
+               for (i = 1; i < count; i++)
+                       handles[i] = handles[0];
+
+               for (i = 0; i < count; i++)
+                       tbm_surface_internal_get_plane_data(buffer, i, &size, &offsets[i], &pitches[i]);
+
+               ret = drmModeAddFB2(exynos_data->drm_fd, width, height, format,
+                                                       handles, pitches, offsets, &display_buffer->fb_id, 0);
+               if (ret < 0) {
+                       TDM_ERR("add fb failed: %m");
+                       free(display_buffer);
+                       return NULL;
+               }
+               TDM_DBG("exynos_data->drm_fd : %d, display_buffer->fb_id:%u", exynos_data->drm_fd,
+                               display_buffer->fb_id);
+
+               if (IS_RGB(format))
+                       display_buffer->width = pitches[0] >> 2;
+               else
+                       display_buffer->width = pitches[0];
+       }
+
+       return display_buffer;
+}
+
+tdm_error
+exynos_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps)
+{
+       tdm_exynos_layer_data *layer_data = layer;
+       tdm_exynos_data *exynos_data;
+       drmModePlanePtr plane = NULL;
+       drmModeObjectPropertiesPtr props = NULL;
+       int i, fmt_count;
+       tdm_error ret;
+
+       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
+
+       memset(caps, 0, sizeof(tdm_caps_layer));
+
+       exynos_data = layer_data->exynos_data;
+       plane = drmModeGetPlane(exynos_data->drm_fd, layer_data->plane_id);
+       if (!plane) {
+               TDM_ERR("get plane failed: %m");
+               ret = TDM_ERROR_OPERATION_FAILED;
+               goto failed_get;
+       }
+
+       caps->capabilities = layer_data->capabilities;
+       caps->zpos = layer_data->zpos;  /* if VIDEO layer, zpos is -1 */
+
+       caps->formats = calloc(1, sizeof(tbm_format) * plane->count_formats);
+       if (!caps->formats) {
+               ret = TDM_ERROR_OUT_OF_MEMORY;
+               TDM_ERR("alloc failed\n");
+               goto failed_get;
+       }
+
+       fmt_count = 0;
+       for (i = 0; i < plane->count_formats; i++) {
+               /* TODO: kernel reports wrong formats */
+               if (plane->formats[i] != DRM_FORMAT_XRGB8888 &&
+                   plane->formats[i] != DRM_FORMAT_ARGB8888)
+                       continue;
+               caps->formats[fmt_count] = tdm_exynos_format_to_tbm_format(plane->formats[i]);
+               fmt_count++;
+       }
+       caps->format_count = fmt_count;
+
+       props = drmModeObjectGetProperties(exynos_data->drm_fd, layer_data->plane_id,
+                                                                          DRM_MODE_OBJECT_PLANE);
+       if (!props) {
+               ret = TDM_ERROR_OPERATION_FAILED;
+               TDM_ERR("get plane properties failed: %m\n");
+               goto failed_get;
+       }
+
+       caps->props = calloc(1, sizeof(tdm_prop) * props->count_props);
+       if (!caps->props) {
+               ret = TDM_ERROR_OUT_OF_MEMORY;
+               TDM_ERR("alloc failed\n");
+               goto failed_get;
+       }
+
+       caps->prop_count = 0;
+       for (i = 0; i < props->count_props; i++) {
+               drmModePropertyPtr prop = drmModeGetProperty(exynos_data->drm_fd,
+                                                                                                        props->props[i]);
+               if (!prop)
+                       continue;
+               if (!strncmp(prop->name, "type", TDM_NAME_LEN)) {
+                       drmModeFreeProperty(prop);
+                       continue;
+               }
+               if (!strncmp(prop->name, "zpos", TDM_NAME_LEN)) {
+                       drmModeFreeProperty(prop);
+                       continue;
+               }
+               snprintf(caps->props[caps->prop_count].name, TDM_NAME_LEN, "%s", prop->name);
+               caps->props[caps->prop_count].id = props->props[i];
+               caps->prop_count++;
+               drmModeFreeProperty(prop);
+       }
+
+       drmModeFreeObjectProperties(props);
+       drmModeFreePlane(plane);
+
+       return TDM_ERROR_NONE;
+failed_get:
+       drmModeFreeObjectProperties(props);
+       drmModeFreePlane(plane);
+       free(caps->formats);
+       free(caps->props);
+       memset(caps, 0, sizeof(tdm_caps_layer));
+       return ret;
+}
+
+tdm_error
+exynos_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
+{
+       tdm_exynos_layer_data *layer_data = layer;
+       tdm_exynos_data *exynos_data;
+       int ret;
+
+       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(layer_data->plane_id > 0, TDM_ERROR_INVALID_PARAMETER);
+
+       exynos_data = layer_data->exynos_data;
+       ret = drmModeObjectSetProperty(exynos_data->drm_fd,
+                                                                  layer_data->plane_id, DRM_MODE_OBJECT_PLANE,
+                                                                  id, value.u32);
+       if (ret < 0) {
+               TDM_ERR("set property failed: %m");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
+{
+       tdm_exynos_layer_data *layer_data = layer;
+       tdm_exynos_data *exynos_data;
+       drmModeObjectPropertiesPtr props;
+       tdm_error ret = TDM_ERROR_INVALID_PARAMETER;
+       int i;
+
+       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(layer_data->plane_id > 0, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(value, TDM_ERROR_INVALID_PARAMETER);
+
+       exynos_data = layer_data->exynos_data;
+       props = drmModeObjectGetProperties(exynos_data->drm_fd, layer_data->plane_id,
+                                                                          DRM_MODE_OBJECT_PLANE);
+       if (props == NULL) {
+               TDM_ERR("get property failed: %m");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       for (i = 0; i < props->count_props; i++)
+               if (props->props[i] == id) {
+                       (*value).u32 = (uint)props->prop_values[i];
+                       ret = TDM_ERROR_NONE;
+                       break;
+               }
+
+       drmModeFreeObjectProperties(props);
+
+       if (ret != TDM_ERROR_NONE)
+               TDM_ERR("unknown property id: %ud", id);
+
+       return ret;
+}
+
+tdm_error
+exynos_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
+{
+       tdm_exynos_layer_data *layer_data = layer;
+
+       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
+
+       layer_data->info = *info;
+       layer_data->info_changed = 1;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
+{
+       tdm_exynos_layer_data *layer_data = layer;
+
+       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
+
+       *info = layer_data->info;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
+{
+       tdm_exynos_layer_data *layer_data = layer;
+       tdm_exynos_data *exynos_data;
+       tdm_exynos_display_buffer *display_buffer;
+
+       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(buffer, TDM_ERROR_INVALID_PARAMETER);
+
+       exynos_data = layer_data->exynos_data;
+
+       display_buffer = _tdm_exynos_display_get_buffer(exynos_data, buffer);
+       if (!display_buffer) {
+               TDM_ERR("alloc failed");
+               return TDM_ERROR_OUT_OF_MEMORY;
+       }
+
+       if (layer_data->display_buffer)
+               tbm_surface_internal_unref(layer_data->display_buffer->buffer);
+
+       layer_data->display_buffer = display_buffer;
+       tbm_surface_internal_ref(layer_data->display_buffer->buffer);
+
+       layer_data->display_buffer_changed = 1;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_layer_unset_buffer(tdm_layer *layer)
+{
+       tdm_exynos_layer_data *layer_data = layer;
+
+       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
+
+       if (layer_data->display_buffer &&
+               (!(layer_data->capabilities & TDM_LAYER_CAPABILITY_PRIMARY) || layer_data->display_buffer_force_unset)) {
+               layer_data->display_buffer_force_unset = 0;
+               tbm_surface_internal_unref(layer_data->display_buffer->buffer);
+               layer_data->display_buffer = NULL;
+       }
+       layer_data->display_buffer_changed = 1;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+tdm_exynos_layer_get_supported_format(tdm_layer *layer, const tbm_format **out_formats,
+                                                                         int *out_format_count)
+{
+       tdm_exynos_layer_data *layer_data = layer;
+       tdm_exynos_data *exynos_data;
+       drmModePlanePtr plane = NULL;
+       int i, j;
+       tdm_error ret;
+       tbm_format *formats = NULL;
+       int format_count = 0;
+
+       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(out_formats, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(out_format_count, TDM_ERROR_INVALID_PARAMETER);
+
+       if (layer_data->formats) {
+               *out_formats = layer_data->formats;
+               *out_format_count = layer_data->format_count;
+
+               return TDM_ERROR_NONE;
+       }
+
+       exynos_data = layer_data->exynos_data;
+       plane = drmModeGetPlane(exynos_data->drm_fd, layer_data->plane_id);
+       if (!plane) {
+               TDM_ERR("get plane failed: %m");
+               ret = TDM_ERROR_OPERATION_FAILED;
+               goto failed_get;
+       }
+
+       for (i = 0; i < plane->count_formats; i++) {
+               /* TODO: kernel reports wrong formats */
+               if (plane->formats[i] != DRM_FORMAT_XRGB8888 &&
+                   plane->formats[i] != DRM_FORMAT_ARGB8888)
+                       continue;
+               format_count++;
+       }
+
+       formats = calloc(1, sizeof(tbm_format) * format_count);
+       if (!formats) {
+               ret = TDM_ERROR_OUT_OF_MEMORY;
+               TDM_ERR("alloc failed\n");
+               goto failed_get;
+       }
+
+       for (i = 0, j = 0; j < plane->count_formats; j++) {
+               /* TODO: kernel reports wrong formats */
+               if (plane->formats[j] != DRM_FORMAT_XRGB8888 &&
+                   plane->formats[j] != DRM_FORMAT_ARGB8888)
+                       continue;
+               formats[i++] = tdm_exynos_format_to_tbm_format(plane->formats[j]);
+       }
+
+       drmModeFreePlane(plane);
+
+       layer_data->formats = formats;
+       layer_data->format_count = format_count;
+
+       *out_formats = layer_data->formats;
+       *out_format_count = layer_data->format_count;
+
+       return TDM_ERROR_NONE;
+failed_get:
+       drmModeFreePlane(plane);
+       free(formats);
+       *out_formats = NULL;
+       *out_format_count = 0;
+       return ret;
+}
+
+tdm_error
+exynos_layer_get_available_properties(tdm_layer *layer, const tdm_prop **out_props,
+                                                                         int *out_prop_count)
+{
+       tdm_exynos_layer_data *layer_data = layer;
+       tdm_exynos_data *exynos_data;
+       drmModePlanePtr plane = NULL;
+       drmModeObjectPropertiesPtr props = NULL;
+       int i;
+       tdm_error ret;
+       tdm_prop *tdm_props = NULL;
+       int prop_count;
+
+       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(out_props, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(out_prop_count, TDM_ERROR_INVALID_PARAMETER);
+
+       if (layer_data->props) {
+               *out_props = layer_data->props;
+               *out_prop_count = layer_data->prop_count;
+
+               return TDM_ERROR_NONE;
+       }
+
+       exynos_data = layer_data->exynos_data;
+       plane = drmModeGetPlane(exynos_data->drm_fd, layer_data->plane_id);
+       if (!plane) {
+               TDM_ERR("get plane failed: %m");
+               ret = TDM_ERROR_OPERATION_FAILED;
+               goto failed_get;
+       }
+
+       props = drmModeObjectGetProperties(exynos_data->drm_fd, layer_data->plane_id,
+                                                                          DRM_MODE_OBJECT_PLANE);
+       if (!props) {
+               ret = TDM_ERROR_OPERATION_FAILED;
+               TDM_ERR("get plane properties failed: %m\n");
+               goto failed_get;
+       }
+
+       tdm_props = calloc(1, sizeof(tdm_prop) * props->count_props);
+       if (!tdm_props) {
+               ret = TDM_ERROR_OUT_OF_MEMORY;
+               TDM_ERR("alloc failed\n");
+               goto failed_get;
+       }
+
+       prop_count = 0;
+       for (i = 0; i < props->count_props; i++) {
+               drmModePropertyPtr prop = drmModeGetProperty(exynos_data->drm_fd,
+                                                                                                        props->props[i]);
+               if (!prop)
+                       continue;
+               if (!strncmp(prop->name, "type", TDM_NAME_LEN)) {
+                       drmModeFreeProperty(prop);
+                       continue;
+               }
+               if (!strncmp(prop->name, "zpos", TDM_NAME_LEN)) {
+                       drmModeFreeProperty(prop);
+                       continue;
+               }
+               snprintf(tdm_props[prop_count].name, TDM_NAME_LEN, "%s", prop->name);
+               tdm_props[prop_count].id = props->props[i];
+               prop_count++;
+               drmModeFreeProperty(prop);
+       }
+
+       drmModeFreeObjectProperties(props);
+       drmModeFreePlane(plane);
+
+       layer_data->props = tdm_props;
+       layer_data->prop_count = prop_count;
+
+       *out_props = layer_data->props;
+       *out_prop_count = layer_data->prop_count;
+
+       return TDM_ERROR_NONE;
+failed_get:
+       drmModeFreeObjectProperties(props);
+       drmModeFreePlane(plane);
+       *out_props = NULL;
+       *out_prop_count = 0;
+
+       return ret;
+}
diff --git a/src/libtdm-exynos/tdm_exynos_layer.h b/src/libtdm-exynos/tdm_exynos_layer.h
new file mode 100644 (file)
index 0000000..cad66b4
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _TDM_EXYNOS_LAYER_H_
+#define _TDM_EXYNOS_LAYER_H_
+
+#include "tdm_exynos.h"
+
+tdm_error
+tdm_exynos_layer_get_supported_format(tdm_layer *layer, const tbm_format **out_formats,
+                                                                         int *out_format_count);
+tdm_error
+exynos_layer_get_available_properties(tdm_layer *layer, const tdm_prop **out_props,
+                                                                         int *out_prop_count);
+
+#endif /* _TDM_EXYNOS_LAYER_H_ */
diff --git a/src/libtdm-exynos/tdm_exynos_output.c b/src/libtdm-exynos/tdm_exynos_output.c
new file mode 100644 (file)
index 0000000..acf2a42
--- /dev/null
@@ -0,0 +1,1085 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <drm_fourcc.h>
+#include <tdm_helper.h>
+#include "tdm_exynos.h"
+
+#define MIN_WIDTH   32
+
+#define LIST_INSERT_AFTER(__after, __item) \
+               (__item)->prev = (__after); \
+               (__item)->next = (__after)->next; \
+               (__after)->next->prev = (__item); \
+               (__after)->next = (__item);
+
+static tdm_error
+check_hw_restriction_crtc(unsigned int crtc_w,
+                                                         unsigned int buf_w, unsigned int buf_h,
+                                                         unsigned int src_x, unsigned int src_y,
+                                                         unsigned int src_w, unsigned int src_h,
+                                                         unsigned int dst_w, unsigned int dst_h,
+                                                         unsigned int *new_x, unsigned int *new_y)
+{
+       int tmp;
+       int dx = 1, dy = 1;
+       int changed_x = 0;
+       int changed_y = 0;
+
+       (void) crtc_w;
+       (void) dst_w;
+       (void) dst_h;
+
+       *new_x = src_x;
+       *new_y = src_y;
+
+       if (src_x + src_w > buf_w) {
+               tmp = src_x;
+               while (tmp + src_w != buf_w)
+                       tmp -= dx;
+
+               changed_x = 1;
+               *new_x = tmp;
+       }
+
+       if (src_y + src_h > buf_h) {
+               tmp = src_y;
+               while (tmp + src_h != buf_h)
+                       tmp -= dy;
+
+               changed_y = 1;
+               *new_y = tmp;
+       }
+
+       if (changed_x == 1 || changed_y == 1)
+               return TDM_ERROR_INVALID_PARAMETER;
+       return TDM_ERROR_NONE;
+}
+
+static tdm_error
+check_hw_restriction(unsigned int crtc_w, unsigned int crtc_h, unsigned int buf_w,
+                                               unsigned int src_x, unsigned int src_w,
+                                               unsigned int dst_x, unsigned int dst_y, unsigned int dst_w,
+                                               unsigned int *new_src_x, unsigned int *new_src_w,
+                                               unsigned int *new_dst_x, unsigned int *new_dst_w)
+{
+       int start, end, diff;
+       int virtual_screen;
+
+       *new_src_x = src_x;
+       *new_src_w = src_w;
+       *new_dst_x = dst_x;
+       *new_dst_w = dst_w;
+
+       if (buf_w < MIN_WIDTH || buf_w % 2) {
+               TDM_ERR("buf_w(%u) not 2's multiple or less than %u", buf_w, MIN_WIDTH);
+               return TDM_ERROR_BAD_REQUEST;
+       }
+
+       if (dst_x > crtc_w || dst_y > crtc_h) {
+               TDM_ERR("dst_pos(%u,%u) is out of crtc(%ux%u)", dst_x, dst_y, crtc_w, crtc_h);
+               return TDM_ERROR_BAD_REQUEST;
+       }
+
+       if (src_x > dst_x || ((dst_x - src_x) + buf_w) > crtc_w)
+               virtual_screen = 1;
+       else
+               virtual_screen = 0;
+
+       start = dst_x;
+       end = ((dst_x + dst_w) > crtc_w) ? crtc_w : (dst_x + dst_w);
+
+       /* check window minimun width */
+       if ((end - start) < MIN_WIDTH) {
+               TDM_ERR("visible_w(%d) less than %u", end - start, MIN_WIDTH);
+               return TDM_ERROR_BAD_REQUEST;
+       }
+
+       if (!virtual_screen) {
+               /* Pagewidth of window (= 8 byte align / bytes-per-pixel ) */
+               if ((end - start) % 2)
+                       end--;
+       } else {
+               /* You should align the sum of PAGEWIDTH_F and OFFSIZE_F double-word (8 byte) boundary. */
+               if (end % 2)
+                       end--;
+       }
+
+       *new_dst_x = start;
+       *new_dst_w = end - start;
+       *new_src_w = *new_dst_w;
+       diff = start - dst_x;
+       *new_src_x += diff;
+
+       RETURN_VAL_IF_FAIL(*new_src_w > 0, TDM_ERROR_BAD_REQUEST);
+       RETURN_VAL_IF_FAIL(*new_dst_w > 0, TDM_ERROR_BAD_REQUEST);
+
+       if (src_x != *new_src_x || src_w != *new_src_w || dst_x != *new_dst_x ||
+           dst_w != *new_dst_w)
+               TDM_DBG("=> buf_w(%d) src(%d,%d) dst(%d,%d), virt(%d) start(%d) end(%d)",
+                               buf_w, *new_src_x, *new_src_w, *new_dst_x, *new_dst_w, virtual_screen, start,
+                               end);
+
+       return TDM_ERROR_NONE;
+}
+
+static drmModeModeInfoPtr
+_tdm_exynos_output_get_mode(tdm_exynos_output_data *output_data)
+{
+       int i;
+
+       if (!output_data->current_mode) {
+               TDM_ERR("no output_data->current_mode");
+               return NULL;
+       }
+
+       for (i = 0; i < output_data->count_modes; i++) {
+               drmModeModeInfoPtr drm_mode = &output_data->drm_modes[i];
+               if (exynos_screen_prerotation_hint % 180) {
+                       if ((drm_mode->hdisplay == output_data->current_mode->vdisplay) &&
+                           (drm_mode->vdisplay == output_data->current_mode->hdisplay) &&
+                           (drm_mode->vrefresh == output_data->current_mode->vrefresh) &&
+                           (drm_mode->flags == output_data->current_mode->flags) &&
+                           (drm_mode->type == output_data->current_mode->type) &&
+                           !(strncmp(drm_mode->name, output_data->current_mode->name, TDM_NAME_LEN)))
+                               return drm_mode;
+               } else {
+                       if ((drm_mode->hdisplay == output_data->current_mode->hdisplay) &&
+                           (drm_mode->vdisplay == output_data->current_mode->vdisplay) &&
+                           (drm_mode->vrefresh == output_data->current_mode->vrefresh) &&
+                           (drm_mode->flags == output_data->current_mode->flags) &&
+                           (drm_mode->type == output_data->current_mode->type) &&
+                           !(strncmp(drm_mode->name, output_data->current_mode->name, TDM_NAME_LEN)))
+                               return drm_mode;
+               }
+       }
+
+       return NULL;
+}
+
+static tdm_error
+_tdm_exynos_output_get_cur_msc(int fd, int pipe, uint *msc)
+{
+       drmVBlank vbl;
+
+       vbl.request.type = DRM_VBLANK_RELATIVE;
+       if (pipe == 1)
+               vbl.request.type |= DRM_VBLANK_SECONDARY;
+       else if (pipe > 1)
+               vbl.request.type |= pipe << DRM_VBLANK_HIGH_CRTC_SHIFT;
+
+       vbl.request.sequence = 0;
+       if (drmWaitVBlank(fd, &vbl)) {
+               TDM_ERR("get vblank counter failed: %m");
+               *msc = 0;
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       *msc = vbl.reply.sequence;
+
+       return TDM_ERROR_NONE;
+}
+
+static tdm_error
+_tdm_exynos_output_wait_vblank(int fd, int pipe, uint *target_msc, void *data)
+{
+       drmVBlank vbl;
+
+       vbl.request.type =  DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
+       if (pipe == 1)
+               vbl.request.type |= DRM_VBLANK_SECONDARY;
+       else if (pipe > 1)
+               vbl.request.type |= pipe << DRM_VBLANK_HIGH_CRTC_SHIFT;
+
+       vbl.request.sequence = *target_msc;
+       vbl.request.signal = (unsigned long)(uintptr_t)data;
+
+       if (drmWaitVBlank(fd, &vbl)) {
+               TDM_ERR("wait vblank failed: %m");
+               *target_msc = 0;
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       *target_msc = vbl.reply.sequence;
+
+       return TDM_ERROR_NONE;
+}
+
+static void
+_tdm_exynos_output_transform_layer_info(int width, int height, tdm_info_layer *info)
+{
+       tdm_pos dst_pos;
+
+       switch (exynos_screen_prerotation_hint) {
+       case 90:
+               dst_pos.x = info->dst_pos.y;
+               dst_pos.y = width - info->dst_pos.x - info->dst_pos.w;
+               dst_pos.w = info->dst_pos.h;
+               dst_pos.h = info->dst_pos.w;
+               break;
+       case 180:
+               dst_pos.x = width - info->dst_pos.x - info->dst_pos.w;
+               dst_pos.y = height - info->dst_pos.y - info->dst_pos.h;
+               dst_pos.w = info->dst_pos.w;
+               dst_pos.h = info->dst_pos.h;
+               break;
+       case 270:
+               dst_pos.x = height - info->dst_pos.y - info->dst_pos.h;
+               dst_pos.y = info->dst_pos.x;
+               dst_pos.w = info->dst_pos.h;
+               dst_pos.h = info->dst_pos.w;
+               break;
+       default:
+               return;
+       }
+
+       info->dst_pos = dst_pos;
+}
+
+static tdm_error
+_tdm_exynos_output_commit_primary_layer(tdm_exynos_layer_data *layer_data,
+                                                                                                 void *user_data, int *do_waitvblank)
+{
+       tdm_exynos_data *exynos_data = layer_data->exynos_data;
+       tdm_exynos_output_data *output_data = layer_data->output_data;
+       unsigned int new_x = -1, new_y = -1;
+       uint32_t fx, fy;
+       int crtc_w, crtc_h;
+
+       if (output_data->mode_changed && layer_data->display_buffer_changed) {
+               tdm_info_layer layer_info = layer_data->info;
+               drmModeModeInfoPtr mode;
+
+               if (!layer_data->display_buffer) {
+                       TDM_ERR("primary layer should have a buffer for modestting");
+                       return TDM_ERROR_BAD_REQUEST;
+               }
+
+               if (output_data->current_mode) {
+                       crtc_w = output_data->current_mode->hdisplay;
+                       crtc_h = output_data->current_mode->vdisplay;
+               } else {
+                       drmModeCrtcPtr crtc = drmModeGetCrtc(exynos_data->drm_fd, output_data->crtc_id);
+                       if (!crtc) {
+                               TDM_ERR("getting crtc failed");
+                               return TDM_ERROR_OPERATION_FAILED;
+                       }
+                       crtc_w = crtc->width;
+                       crtc_h = crtc->height;
+                       if (crtc_w == 0) {
+                               TDM_ERR("getting crtc width failed");
+                               drmModeFreeCrtc(crtc);
+                               return TDM_ERROR_OPERATION_FAILED;
+                       }
+                       drmModeFreeCrtc(crtc);
+               }
+
+               output_data->mode_changed = 0;
+               layer_data->display_buffer_changed = 0;
+               layer_data->info_changed = 0;
+
+               mode = _tdm_exynos_output_get_mode(output_data);
+               if (!mode) {
+                       TDM_ERR("couldn't find proper mode");
+                       return TDM_ERROR_BAD_REQUEST;
+               }
+
+               _tdm_exynos_output_transform_layer_info(crtc_w, crtc_h, &layer_info);
+
+               if (check_hw_restriction_crtc(crtc_w,
+                                                                         layer_info.src_config.size.h, layer_info.src_config.size.v,
+                                                                         layer_info.src_config.pos.x, layer_info.src_config.pos.y,
+                                                                         layer_info.src_config.pos.w, layer_info.src_config.pos.h,
+                                                                         layer_info.dst_pos.w, layer_info.dst_pos.h,
+                                                                         &new_x, &new_y) != TDM_ERROR_NONE)
+               TDM_WRN("not going to set crtc(%u)", output_data->crtc_id);
+
+               if (layer_info.src_config.pos.x != new_x)
+                       TDM_DBG("src_x changed: %u => %u", layer_info.src_config.pos.x,
+                                       new_x);
+               if (layer_info.src_config.pos.y != new_y)
+                       TDM_DBG("src_y changed: %u => %u", layer_info.src_config.pos.y,
+                                       new_y);
+
+               fx = (unsigned int)new_x;
+               fy = (unsigned int)new_y;
+
+               TDM_DBG("SetCrtc: drm_fd(%d) crtc_id(%u) fb_id(%u) mode(%ux%u, %uhz) pos(%u %u)",
+                               exynos_data->drm_fd, output_data->crtc_id, layer_data->display_buffer->fb_id,
+                               mode->hdisplay, mode->vdisplay, mode->vrefresh, fx, fy);
+
+               if (drmModeSetCrtc(exynos_data->drm_fd, output_data->crtc_id,
+                                                  layer_data->display_buffer->fb_id, fx, fy,
+                                                  &output_data->connector_id, 1, mode)) {
+                       TDM_ERR("set crtc failed: %m");
+                       return TDM_ERROR_OPERATION_FAILED;
+               }
+
+               tdm_exynos_output_update_status(output_data, TDM_OUTPUT_CONN_STATUS_MODE_SETTED);
+
+               *do_waitvblank = 1;
+
+               return TDM_ERROR_NONE;
+       } else if (layer_data->display_buffer_changed) {
+               layer_data->display_buffer_changed = 0;
+
+               if (layer_data->display_buffer) {
+                       tbm_surface_info_s info;
+                       int ret;
+                       tdm_exynos_event_data *event_data = calloc(1, sizeof(tdm_exynos_event_data));
+
+                       if (!event_data) {
+                               TDM_ERR("alloc failed");
+                               return TDM_ERROR_OUT_OF_MEMORY;
+                       }
+                       event_data->type = TDM_EXYNOS_EVENT_TYPE_PAGEFLIP;
+                       event_data->output_data = output_data;
+                       event_data->user_data = user_data;
+                       event_data->hwc_mode = exynos_data->hwc_mode;
+
+                       TDM_DBG("PageFlip: drm_fd(%d) crtc_id(%u) fb_id(%u)",
+                                       exynos_data->drm_fd, output_data->crtc_id,
+                                       layer_data->display_buffer->fb_id);
+
+                       ret = tbm_surface_map(layer_data->display_buffer->buffer, TBM_SURF_OPTION_READ, &info);
+                       if (ret == TBM_SURFACE_ERROR_NONE)
+                               tbm_surface_unmap(layer_data->display_buffer->buffer);
+
+                       if (drmModePageFlip(exynos_data->drm_fd, output_data->crtc_id,
+                                                               layer_data->display_buffer->fb_id, DRM_MODE_PAGE_FLIP_EVENT, event_data)) {
+                               TDM_ERR("pageflip failed: %m");
+                               free(event_data);
+                               return TDM_ERROR_OPERATION_FAILED;
+                       }
+                       *do_waitvblank = 0;
+               } else {
+                       /* to call a user commit handler whenever committed */
+                       *do_waitvblank = 1;
+               }
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+static tdm_error
+_tdm_exynos_output_commit_layer(tdm_exynos_layer_data *layer_data)
+{
+       tdm_exynos_data *exynos_data = layer_data->exynos_data;
+       tdm_exynos_output_data *output_data = layer_data->output_data;
+       unsigned int new_src_x, new_src_w;
+       unsigned int new_dst_x, new_dst_w;
+       uint32_t fx, fy, fw, fh;
+       int crtc_w, crtc_h;
+       tdm_info_layer layer_info = layer_data->info;
+
+       if (!layer_data->display_buffer_changed && !layer_data->info_changed)
+               return TDM_ERROR_NONE;
+
+       if (output_data->current_mode) {
+               crtc_w = output_data->current_mode->hdisplay;
+               crtc_h = output_data->current_mode->vdisplay;
+       } else {
+               drmModeCrtcPtr crtc = drmModeGetCrtc(exynos_data->drm_fd, output_data->crtc_id);
+               if (!crtc) {
+                       TDM_ERR("getting crtc failed");
+                       return TDM_ERROR_OPERATION_FAILED;
+               }
+               crtc_w = crtc->width;
+               crtc_h = crtc->height;
+               if (crtc_w == 0) {
+                       TDM_ERR("getting crtc width failed");
+                       drmModeFreeCrtc(crtc);
+                       return TDM_ERROR_OPERATION_FAILED;
+               }
+               drmModeFreeCrtc(crtc);
+       }
+
+       layer_data->display_buffer_changed = 0;
+       layer_data->info_changed = 0;
+
+       if (!layer_data->display_buffer) {
+               TDM_DBG("SetPlane: drm_fd(%d) plane_id(%u) crtc_id(%u) off",
+                               exynos_data->drm_fd, layer_data->plane_id, output_data->crtc_id);
+
+               if (drmModeSetPlane(exynos_data->drm_fd, layer_data->plane_id,
+                                                       output_data->crtc_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
+                       TDM_ERR("unset plane(%u) filed: %m", layer_data->plane_id);
+
+               return TDM_ERROR_NONE;
+       }
+
+               _tdm_exynos_output_transform_layer_info(crtc_w, crtc_h, &layer_info);
+
+       /* check hw restriction*/
+       if (check_hw_restriction(crtc_w, crtc_h, layer_data->display_buffer->width,
+                                                        layer_info.src_config.pos.x,
+                                                        layer_info.src_config.pos.w,
+                                                        layer_info.dst_pos.x,
+                                                        layer_info.dst_pos.y,
+                                                        layer_info.dst_pos.w,
+                                                        &new_src_x, &new_src_w, &new_dst_x, &new_dst_w) != TDM_ERROR_NONE) {
+               TDM_WRN("not going to set plane(%u)", layer_data->plane_id);
+               return TDM_ERROR_NONE;
+       }
+
+       if (layer_info.src_config.pos.x != new_src_x)
+               TDM_DBG("src_x changed: %u => %u", layer_info.src_config.pos.x, new_src_x);
+       if (layer_info.src_config.pos.w != new_src_w)
+               TDM_DBG("src_w changed: %u => %u", layer_info.src_config.pos.w, new_src_w);
+       if (layer_info.dst_pos.x != new_dst_x)
+               TDM_DBG("dst_x changed: %u => %u", layer_info.dst_pos.x, new_dst_x);
+       if (layer_info.dst_pos.w != new_dst_w)
+               TDM_DBG("dst_w changed: %u => %u", layer_info.dst_pos.w, new_dst_w);
+
+       /* Source values are 16.16 fixed point */
+       fx = ((unsigned int)new_src_x) << 16;
+       fy = ((unsigned int)layer_info.src_config.pos.y) << 16;
+       fw = ((unsigned int)new_src_w) << 16;
+       fh = ((unsigned int)layer_info.src_config.pos.h) << 16;
+
+       TDM_DBG("SetPlane: drm_fd(%d) plane_id(%u) zpos(%d) crtc_id(%u) fb_id(%u) src(%u,%u %ux%u) dst(%u,%u %ux%u)",
+                       exynos_data->drm_fd, layer_data->plane_id, layer_data->zpos,
+                       output_data->crtc_id, layer_data->display_buffer->fb_id,
+                       new_src_x, layer_info.src_config.pos.y,
+                       new_src_w, layer_info.src_config.pos.h,
+                       layer_info.dst_pos.x, layer_info.dst_pos.y,
+                       layer_info.dst_pos.w, layer_info.dst_pos.h);
+
+       if (drmModeSetPlane(exynos_data->drm_fd, layer_data->plane_id,
+                                               output_data->crtc_id, layer_data->display_buffer->fb_id, 0,
+                                               new_dst_x, layer_info.dst_pos.y,
+                                               new_dst_w, layer_info.dst_pos.h,
+                                               fx, fy, fw, fh) < 0) {
+               TDM_ERR("SetPlane: drm_fd(%d) plane_id(%u) zpos(%d) crtc_id(%u) fb_id(%u) src(%u,%u %ux%u) dst(%u,%u %ux%u) failed: %m",
+                               exynos_data->drm_fd, layer_data->plane_id, layer_data->zpos,
+                               output_data->crtc_id, layer_data->display_buffer->fb_id,
+                               new_src_x, layer_info.src_config.pos.y,
+                               new_src_w, layer_info.src_config.pos.h,
+                               layer_info.dst_pos.x, layer_info.dst_pos.y,
+                               layer_info.dst_pos.w, layer_info.dst_pos.h);
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+void
+tdm_exynos_output_cb_event(int fd, unsigned int sequence,
+                                                                 unsigned int tv_sec, unsigned int tv_usec,
+                                                                 void *user_data)
+{
+       tdm_exynos_event_data *event_data = user_data;
+       tdm_exynos_output_data *output_data;
+       tdm_exynos_hwc_data *hwc_data;
+
+       if (!event_data) {
+               TDM_ERR("no event data");
+               return;
+       }
+
+       output_data = event_data->output_data;
+       hwc_data = output_data->hwc_data;
+
+       switch (event_data->type) {
+       case TDM_EXYNOS_EVENT_TYPE_PAGEFLIP:
+       case TDM_EXYNOS_EVENT_TYPE_COMMIT:
+               if (event_data->hwc_mode && hwc_data) {
+                       if (hwc_data->commit_func)
+                               hwc_data->commit_func(hwc_data, sequence, tv_sec, tv_usec,
+                                                                         event_data->user_data);
+               } else {
+                       if (output_data->commit_func)
+                               output_data->commit_func(output_data, sequence, tv_sec, tv_usec,
+                                                                                event_data->user_data);
+               }
+               break;
+       case TDM_EXYNOS_EVENT_TYPE_WAIT:
+               if (output_data->vblank_func)
+                       output_data->vblank_func(output_data, sequence, tv_sec, tv_usec,
+                                                                        event_data->user_data);
+               break;
+       default:
+               break;
+       }
+
+       free(event_data);
+}
+
+tdm_error
+tdm_exynos_output_update_status(tdm_exynos_output_data *output_data,
+                                                                               tdm_output_conn_status status)
+{
+       tdm_exynos_layer_data *layer_data = NULL;
+
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+
+       if (output_data->status == status)
+               return TDM_ERROR_NONE;
+
+       output_data->status = status;
+
+       LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+               if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) {
+                       if (layer_data->display_buffer)
+                               layer_data->display_buffer_force_unset = 1;
+               } else
+                       layer_data->display_buffer_force_unset = 0;
+       }
+
+       if (output_data->status_func)
+               output_data->status_func(output_data, status,
+                                                                output_data->status_user_data);
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_output_get_capability(tdm_output *output, tdm_caps_output *caps)
+{
+       tdm_exynos_output_data *output_data = output;
+       tdm_exynos_data *exynos_data;
+       drmModeConnectorPtr connector = NULL;
+       drmModeCrtcPtr crtc = NULL;
+       drmModeObjectPropertiesPtr props = NULL;
+       int i;
+       tdm_error ret;
+
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
+
+       memset(caps, 0, sizeof(tdm_caps_output));
+
+       exynos_data = output_data->exynos_data;
+
+       snprintf(caps->maker, TDM_NAME_LEN, "unknown");
+       snprintf(caps->model, TDM_NAME_LEN, "unknown");
+       snprintf(caps->name, TDM_NAME_LEN, "unknown");
+
+       caps->type = output_data->connector_type;
+       caps->type_id = output_data->connector_type_id;
+
+       connector = drmModeGetConnector(exynos_data->drm_fd, output_data->connector_id);
+       RETURN_VAL_IF_FAIL(connector, TDM_ERROR_OPERATION_FAILED);
+
+       caps->mode_count = connector->count_modes;
+       caps->modes = calloc(1, sizeof(tdm_output_mode) * caps->mode_count);
+       if (!caps->modes) {
+               ret = TDM_ERROR_OUT_OF_MEMORY;
+               TDM_ERR("alloc failed\n");
+               goto failed_get;
+       }
+       if (caps->mode_count != output_data->count_modes) {
+               drmModeModeInfoPtr new_drm_modes;
+               tdm_output_mode *new_output_modes;
+
+               new_drm_modes = calloc(connector->count_modes,
+                                               sizeof(drmModeModeInfo));
+               if (!new_drm_modes) {
+                       ret = TDM_ERROR_OUT_OF_MEMORY;
+                       TDM_ERR("alloc failed drm_modes\n");
+                       goto failed_get;
+               }
+               new_output_modes = calloc(connector->count_modes,
+                                               sizeof(tdm_output_mode));
+               if (!new_output_modes) {
+                       ret = TDM_ERROR_OUT_OF_MEMORY;
+                       TDM_ERR("alloc failed output_modes\n");
+                       free(new_drm_modes);
+                       goto failed_get;
+               }
+               free(output_data->drm_modes);
+               free(output_data->output_modes);
+
+               output_data->drm_modes = new_drm_modes;
+               output_data->output_modes = new_output_modes;
+               output_data->count_modes = caps->mode_count;
+       }
+       for (i = 0; i < caps->mode_count; i++) {
+               output_data->drm_modes[i] = connector->modes[i];
+               tdm_exynos_display_to_tdm_mode(&output_data->drm_modes[i],
+                                                                          &output_data->output_modes[i]);
+               caps->modes[i] = output_data->output_modes[i];
+       }
+
+       if (connector->connection == DRM_MODE_CONNECTED)
+               output_data->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
+       else
+               output_data->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+       caps->status = output_data->status;
+
+       if (exynos_screen_prerotation_hint % 180) {
+               caps->mmWidth = connector->mmHeight;
+               caps->mmHeight = connector->mmWidth;
+               caps->min_w = exynos_data->mode_res->min_height;
+               caps->min_h = exynos_data->mode_res->min_width;
+               caps->max_w = exynos_data->mode_res->max_height;
+               caps->max_h = exynos_data->mode_res->max_width;
+       } else {
+               caps->mmWidth = connector->mmWidth;
+               caps->mmHeight = connector->mmHeight;
+               caps->min_w = exynos_data->mode_res->min_width;
+               caps->min_h = exynos_data->mode_res->min_height;
+               caps->max_w = exynos_data->mode_res->max_width;
+               caps->max_h = exynos_data->mode_res->max_height;
+       }
+
+       caps->subpixel = connector->subpixel;
+       caps->preferred_align = -1;
+
+       caps->cursor_min_w = 32;
+       caps->cursor_min_h = 32;
+       caps->cursor_max_w = -1;
+       caps->cursor_max_h = -1;
+       caps->cursor_preferred_align = -1;
+
+       crtc = drmModeGetCrtc(exynos_data->drm_fd, output_data->crtc_id);
+       if (!crtc) {
+               ret = TDM_ERROR_OPERATION_FAILED;
+               TDM_ERR("get crtc failed: %m\n");
+               goto failed_get;
+       }
+
+       props = drmModeObjectGetProperties(exynos_data->drm_fd, output_data->crtc_id,
+                                                                          DRM_MODE_OBJECT_CRTC);
+       if (!props) {
+               ret = TDM_ERROR_OPERATION_FAILED;
+               TDM_ERR("get crtc properties failed: %m\n");
+               goto failed_get;
+       }
+
+       caps->props = calloc(1, sizeof(tdm_prop) * props->count_props);
+       if (!caps->props) {
+               ret = TDM_ERROR_OUT_OF_MEMORY;
+               TDM_ERR("alloc failed\n");
+               goto failed_get;
+       }
+
+       caps->prop_count = 0;
+       for (i = 0; i < props->count_props; i++) {
+               drmModePropertyPtr prop = drmModeGetProperty(exynos_data->drm_fd,
+                                                                                                        props->props[i]);
+               if (!prop)
+                       continue;
+               snprintf(caps->props[caps->prop_count].name, TDM_NAME_LEN, "%s", prop->name);
+               caps->props[caps->prop_count].id = props->props[i];
+               caps->prop_count++;
+               drmModeFreeProperty(prop);
+       }
+
+       if (output_data->hwc_enable)
+               caps->capabilities |= TDM_OUTPUT_CAPABILITY_HWC;
+
+       drmModeFreeObjectProperties(props);
+       drmModeFreeCrtc(crtc);
+       drmModeFreeConnector(connector);
+
+       return TDM_ERROR_NONE;
+failed_get:
+       drmModeFreeCrtc(crtc);
+       drmModeFreeObjectProperties(props);
+       drmModeFreeConnector(connector);
+       free(caps->modes);
+       free(caps->props);
+       memset(caps, 0, sizeof(tdm_caps_output));
+       return ret;
+}
+
+tdm_layer **
+exynos_output_get_layers(tdm_output *output,  int *count, tdm_error *error)
+{
+       tdm_exynos_output_data *output_data = output;
+       tdm_exynos_layer_data *layer_data = NULL;
+       tdm_layer **layers;
+       tdm_error ret;
+       int i;
+
+       RETURN_VAL_IF_FAIL(output_data, NULL);
+       RETURN_VAL_IF_FAIL(count, NULL);
+
+       if (output_data->hwc_enable) {
+               *count = 0;
+               ret = TDM_ERROR_NONE;
+               goto failed_get;
+       }
+
+       *count = 0;
+       LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link)
+       (*count)++;
+
+       if (*count == 0) {
+               ret = TDM_ERROR_NONE;
+               goto failed_get;
+       }
+
+       /* will be freed in frontend */
+       layers = calloc(*count, sizeof(tdm_exynos_layer_data *));
+       if (!layers) {
+               TDM_ERR("failed: alloc memory");
+               *count = 0;
+               ret = TDM_ERROR_OUT_OF_MEMORY;
+               goto failed_get;
+       }
+
+       i = 0;
+       LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link)
+       layers[i++] = layer_data;
+
+       if (error)
+               *error = TDM_ERROR_NONE;
+
+       return layers;
+failed_get:
+       if (error)
+               *error = ret;
+       return NULL;
+}
+
+tdm_error
+exynos_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
+{
+       tdm_exynos_output_data *output_data = output;
+       tdm_exynos_data *exynos_data;
+       int ret;
+
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(output_data->crtc_id > 0, TDM_ERROR_INVALID_PARAMETER);
+
+       exynos_data = output_data->exynos_data;
+       ret = drmModeObjectSetProperty(exynos_data->drm_fd,
+                                                                  output_data->crtc_id, DRM_MODE_OBJECT_CRTC,
+                                                                  id, value.u32);
+       if (ret < 0) {
+               TDM_ERR("set property failed: %m");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_output_get_property(tdm_output *output, unsigned int id,
+                                                                tdm_value *value)
+{
+       tdm_exynos_output_data *output_data = output;
+       tdm_exynos_data *exynos_data;
+       drmModeObjectPropertiesPtr props;
+       int i;
+
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(output_data->crtc_id > 0, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(value, TDM_ERROR_INVALID_PARAMETER);
+
+       exynos_data = output_data->exynos_data;
+       props = drmModeObjectGetProperties(exynos_data->drm_fd, output_data->crtc_id,
+                                                                          DRM_MODE_OBJECT_CRTC);
+       if (props == NULL) {
+               TDM_ERR("get property failed: %m");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       for (i = 0; i < props->count_props; i++)
+               if (props->props[i] == id) {
+                       (*value).u32 = (uint)props->prop_values[i];
+                       break;
+               }
+
+       drmModeFreeObjectProperties(props);
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_output_wait_vblank(tdm_output *output, int interval, int sync,
+                                                               void *user_data)
+{
+       tdm_exynos_output_data *output_data = output;
+       tdm_exynos_data *exynos_data;
+       tdm_exynos_event_data *event_data;
+       uint target_msc;
+       tdm_error ret;
+
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+
+       event_data = calloc(1, sizeof(tdm_exynos_event_data));
+       if (!event_data) {
+               TDM_ERR("alloc failed");
+               return TDM_ERROR_OUT_OF_MEMORY;
+       }
+
+       exynos_data = output_data->exynos_data;
+
+       ret = _tdm_exynos_output_get_cur_msc(exynos_data->drm_fd, output_data->pipe,
+                                                                                &target_msc);
+       if (ret != TDM_ERROR_NONE)
+               goto failed_vblank;
+
+       target_msc += interval;
+
+       event_data->type = TDM_EXYNOS_EVENT_TYPE_WAIT;
+       event_data->output_data = output_data;
+       event_data->user_data = user_data;
+
+       ret = _tdm_exynos_output_wait_vblank(exynos_data->drm_fd, output_data->pipe,
+                                                                                &target_msc, event_data);
+       if (ret != TDM_ERROR_NONE)
+               goto failed_vblank;
+
+       return TDM_ERROR_NONE;
+failed_vblank:
+       free(event_data);
+       return ret;
+}
+
+tdm_error
+exynos_output_set_vblank_handler(tdm_output *output,
+                                                                               tdm_output_vblank_handler func)
+{
+       tdm_exynos_output_data *output_data = output;
+
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
+
+       output_data->vblank_func = func;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_output_commit(tdm_output *output, int sync, void *user_data)
+{
+       tdm_exynos_output_data *output_data = output;
+       tdm_exynos_data *exynos_data;
+       tdm_exynos_layer_data *layer_data = NULL;
+       tdm_error ret;
+       int do_waitvblank = 1;
+
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+
+       exynos_data = output_data->exynos_data;
+
+       LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+               if (layer_data == output_data->primary_layer) {
+                       if (!layer_data->display_buffer ||
+                               (output_data->current_mode->hdisplay == layer_data->info.src_config.pos.w &&
+                               output_data->current_mode->vdisplay == layer_data->info.src_config.pos.h)) {
+                               ret = _tdm_exynos_output_commit_primary_layer(layer_data, user_data,
+                                                                                                                                                 &do_waitvblank);
+                       } else
+                               ret = _tdm_exynos_output_commit_layer(layer_data);
+
+                       if (ret != TDM_ERROR_NONE)
+                               return ret;
+               } else {
+                       ret = _tdm_exynos_output_commit_layer(layer_data);
+                       if (ret != TDM_ERROR_NONE)
+                               return ret;
+               }
+       }
+
+       if (do_waitvblank == 1) {
+               tdm_exynos_event_data *event_data = calloc(1, sizeof(tdm_exynos_event_data));
+               uint target_msc;
+
+               if (!event_data) {
+                       TDM_ERR("alloc failed");
+                       return TDM_ERROR_OUT_OF_MEMORY;
+               }
+
+               ret = _tdm_exynos_output_get_cur_msc(exynos_data->drm_fd, output_data->pipe,
+                                                                                        &target_msc);
+               if (ret != TDM_ERROR_NONE) {
+                       free(event_data);
+                       return ret;
+               }
+
+               target_msc++;
+
+               event_data->type = TDM_EXYNOS_EVENT_TYPE_COMMIT;
+               event_data->output_data = output_data;
+               event_data->user_data = user_data;
+               event_data->hwc_mode = exynos_data->hwc_mode;
+
+               ret = _tdm_exynos_output_wait_vblank(exynos_data->drm_fd, output_data->pipe,
+                                                                                        &target_msc, event_data);
+               if (ret != TDM_ERROR_NONE) {
+                       free(event_data);
+                       return ret;
+               }
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_output_set_commit_handler(tdm_output *output,
+                                                                                tdm_output_commit_handler func)
+{
+       tdm_exynos_output_data *output_data = output;
+
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
+
+       output_data->commit_func = func;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
+{
+       tdm_exynos_output_data *output_data = output;
+       tdm_exynos_data *exynos_data;
+       int ret;
+
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+
+       exynos_data = output_data->exynos_data;
+       ret = drmModeObjectSetProperty(exynos_data->drm_fd,
+                                                                  output_data->connector_id, DRM_MODE_OBJECT_CONNECTOR,
+                                                                  output_data->dpms_prop_id, dpms_value);
+       if (ret < 0) {
+               TDM_ERR("set dpms failed: %m");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
+{
+       tdm_exynos_output_data *output_data = output;
+       tdm_exynos_data *exynos_data;
+       drmModeObjectPropertiesPtr props;
+       int i;
+
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(dpms_value, TDM_ERROR_INVALID_PARAMETER);
+
+       exynos_data = output_data->exynos_data;
+       props = drmModeObjectGetProperties(exynos_data->drm_fd,
+                                                                          output_data->connector_id, DRM_MODE_OBJECT_CONNECTOR);
+       if (props == NULL) {
+               TDM_ERR("get property failed: %m");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       for (i = 0; i < props->count_props; i++)
+               if (props->props[i] == output_data->dpms_prop_id) {
+                       *dpms_value = (uint)props->prop_values[i];
+                       break;
+               }
+
+       drmModeFreeObjectProperties(props);
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
+{
+       tdm_exynos_output_data *output_data = output;
+       tdm_error ret = TDM_ERROR_NONE;
+
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER);
+
+       /* create or replace the target_window when the output mode is set */
+       if (output_data->hwc_enable) {
+               ret = exynos_hwc_initailize_target_window(output_data->hwc_data, mode->hdisplay, mode->vdisplay);
+               if (ret != TDM_ERROR_NONE) {
+                       TDM_ERR("create target hwc window failed (%d)", ret);
+                       return ret;
+               }
+       }
+
+       output_data->current_mode = mode;
+       output_data->mode_changed = 1;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
+{
+       tdm_exynos_output_data *output_data = output;
+
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER);
+
+       *mode = output_data->current_mode;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_capture*
+exynos_output_create_capture(tdm_output *output, tdm_error *error)
+{
+       tdm_exynos_output_data *output_data = output;
+       tdm_exynos_data *exynos_data;
+
+       RETURN_VAL_IF_FAIL(output_data, NULL);
+
+       exynos_data = output_data->exynos_data;
+
+       if (exynos_data->use_ippv2)
+               return tdm_exynos_capture_create_output(exynos_data, output, error);
+       else
+               return tdm_exynos_capture_legacy_create_output(exynos_data, output, error);
+}
+
+tdm_error
+exynos_output_set_status_handler(tdm_output *output,
+                                                                          tdm_output_status_handler func,
+                                                                          void *user_data)
+{
+       tdm_exynos_output_data *output_data = output;
+
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
+
+       output_data->status_func = func;
+       output_data->status_user_data = user_data;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_hwc *
+exynos_output_get_hwc(tdm_output *output, tdm_error *error)
+{
+       tdm_exynos_hwc_data *hwc_data = NULL;
+       tdm_exynos_output_data *output_data = output;
+
+       if (!output_data) {
+               TDM_ERR("invalid params");
+               if (error)
+                       *error = TDM_ERROR_INVALID_PARAMETER;
+               return NULL;
+       }
+
+       if (output_data->hwc_data) {
+               TDM_INFO("hwc_data already exists");
+               if (error)
+                       *error = TDM_ERROR_NONE;
+               return output_data->hwc_data;
+       }
+
+       hwc_data = calloc(1, sizeof(tdm_exynos_hwc_data));
+       if (!hwc_data) {
+               TDM_ERR("alloc failed");
+               if (error)
+                       *error = TDM_ERROR_OUT_OF_MEMORY;
+               return NULL;
+       }
+       hwc_data->output_data = output_data;
+
+       LIST_INITHEAD(&hwc_data->hwc_window_list);
+
+       output_data->hwc_data = hwc_data;
+
+       if (error)
+               *error = TDM_ERROR_NONE;
+
+       return hwc_data;
+}
diff --git a/src/libtdm-exynos/tdm_exynos_output.h b/src/libtdm-exynos/tdm_exynos_output.h
new file mode 100644 (file)
index 0000000..195f15f
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _TDM_EXYNOS_OUTPUT_H_
+#define _TDM_EXYNOS_OUTPUT_H_
+
+#include "tdm_exynos.h"
+
+void tdm_exynos_output_cb_event(int fd, unsigned int sequence,
+                                                                          unsigned int tv_sec, unsigned int tv_usec,
+                                                                          void *user_data);
+tdm_error
+tdm_exynos_output_update_status(tdm_exynos_output_data *output_data,
+                                                                               tdm_output_conn_status status);
+
+#endif /* _TDM_EXYNOS_OUTPUT_H_ */
diff --git a/src/libtdm-exynos/tdm_exynos_pp.c b/src/libtdm-exynos/tdm_exynos_pp.c
new file mode 100644 (file)
index 0000000..fb63e6d
--- /dev/null
@@ -0,0 +1,433 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_exynos.h"
+
+typedef struct _tdm_exynos_pp_data {
+       tdm_exynos_data *exynos_data;
+
+       tdm_info_pp info;
+
+       struct list_head pending_buffer_list;
+       struct list_head buffer_list;
+
+       tdm_pp_done_handler done_func;
+       void *done_user_data;
+
+       int first_event;
+
+       struct list_head link;
+} tdm_exynos_pp_data;
+
+typedef struct _tdm_exynos_pp_buffer {
+       tdm_exynos_pp_data *pp_data;
+       tbm_surface_h src;
+       tbm_surface_h dst;
+
+       struct list_head link;
+} tdm_exynos_pp_buffer;
+
+
+static int pp_list_init;
+static struct list_head pp_list;
+
+struct exynos_drm_ipp_std_task {
+       struct drm_exynos_ipp_task_buffer buf[2];
+       struct drm_exynos_ipp_task_rect rect[2];
+       struct drm_exynos_ipp_task_transform transform;
+} __packed;
+
+static unsigned int tdm_transform_to_drm(tdm_transform t)
+{
+       switch (t) {
+       case TDM_TRANSFORM_NORMAL:
+               return DRM_MODE_ROTATE_0;
+       case TDM_TRANSFORM_90:
+               return DRM_MODE_ROTATE_90;
+       case TDM_TRANSFORM_180:
+               return DRM_MODE_ROTATE_180;
+       case TDM_TRANSFORM_270:
+               return DRM_MODE_ROTATE_270;
+       case TDM_TRANSFORM_FLIPPED:
+               return DRM_MODE_REFLECT_Y;
+       case TDM_TRANSFORM_FLIPPED_90:
+               return DRM_MODE_REFLECT_Y | DRM_MODE_ROTATE_90;
+       case TDM_TRANSFORM_FLIPPED_180:
+               return DRM_MODE_REFLECT_Y | DRM_MODE_ROTATE_180;
+       case TDM_TRANSFORM_FLIPPED_270:
+               return DRM_MODE_REFLECT_Y | DRM_MODE_ROTATE_270;
+       }
+       return 0;
+}
+
+static tdm_error
+_tdm_exynos_pp_process(tdm_exynos_pp_data *pp_data, tdm_exynos_pp_buffer *buffer)
+{
+       tdm_exynos_data *exynos_data = pp_data->exynos_data;
+       tdm_info_pp *info = &pp_data->info;
+       int i, plane_num, ret = 0;
+
+       struct exynos_drm_ipp_std_task task;
+       struct drm_exynos_ioctl_ipp_commit arg;
+
+       CLEAR(task);
+
+       /* src buf */
+       task.buf[0].id = DRM_EXYNOS_IPP_TASK_BUFFER | DRM_EXYNOS_IPP_TASK_TYPE_SOURCE;
+       task.buf[0].fourcc = tdm_exynos_format_to_drm_format(tbm_surface_get_format(buffer->src));
+       task.buf[0].width = tbm_surface_get_width(buffer->src);
+       task.buf[0].height = tbm_surface_get_height(buffer->src);
+
+       plane_num = tbm_surface_internal_get_num_planes(tbm_surface_get_format(buffer->src));
+       for (i = 0; i < EXYNOS_DRM_PLANAR_MAX && i < plane_num; i++) {
+               uint32_t size, offset, pitch;
+               int bo_index;
+               tbm_bo bo;
+
+               bo_index = tbm_surface_internal_get_plane_bo_idx(buffer->src, i);
+               bo = tbm_surface_internal_get_bo(buffer->src, bo_index);
+
+               tbm_surface_internal_get_plane_data(buffer->src, i, &size, &offset, &pitch);
+               task.buf[0].gem_id[i] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
+               task.buf[0].pitch[i] = pitch;
+               task.buf[0].offset[i] = offset;
+       }
+
+       /* dst buf */
+       task.buf[1].id = DRM_EXYNOS_IPP_TASK_BUFFER | DRM_EXYNOS_IPP_TASK_TYPE_DESTINATION;
+       task.buf[1].fourcc = tdm_exynos_format_to_drm_format(tbm_surface_get_format(buffer->dst));
+       task.buf[1].width = tbm_surface_get_width(buffer->dst);
+       task.buf[1].height = tbm_surface_get_height(buffer->dst);
+
+       plane_num = tbm_surface_internal_get_num_planes(tbm_surface_get_format(buffer->dst));
+       for (i = 0; i < EXYNOS_DRM_PLANAR_MAX && i < plane_num; i++) {
+               uint32_t size, offset, pitch;
+               int bo_index;
+               tbm_bo bo;
+
+               bo_index = tbm_surface_internal_get_plane_bo_idx(buffer->dst, i);
+               bo = tbm_surface_internal_get_bo(buffer->dst, bo_index);
+
+               tbm_surface_internal_get_plane_data(buffer->dst, i, &size, &offset, &pitch);
+               task.buf[1].gem_id[i] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
+               task.buf[1].pitch[i] = pitch;
+               task.buf[1].offset[i] = offset;
+       }
+
+       task.rect[0].id = DRM_EXYNOS_IPP_TASK_RECTANGLE | DRM_EXYNOS_IPP_TASK_TYPE_SOURCE;
+       task.rect[0].x = info->src_config.pos.x;
+       task.rect[0].y = info->src_config.pos.y;
+       task.rect[0].w = info->src_config.pos.w;
+       task.rect[0].h = info->src_config.pos.h;
+
+       task.rect[1].id = DRM_EXYNOS_IPP_TASK_RECTANGLE | DRM_EXYNOS_IPP_TASK_TYPE_DESTINATION;
+       task.rect[1].x = info->dst_config.pos.x;
+       task.rect[1].y = info->dst_config.pos.y;
+       task.rect[1].w = info->dst_config.pos.w;
+       task.rect[1].h = info->dst_config.pos.h;
+
+       task.transform.id = DRM_EXYNOS_IPP_TASK_TRANSFORM;
+       task.transform.rotation = tdm_transform_to_drm(info->transform);
+
+       CLEAR(arg);
+       arg.flags = DRM_EXYNOS_IPP_FLAG_EVENT | DRM_EXYNOS_IPP_FLAG_NONBLOCK;
+       arg.ipp_id = exynos_data->ipp_module_id;
+       arg.params_size = sizeof(task);
+       arg.params_ptr = (unsigned long)(&task);
+       arg.user_data = (__u64)(uintptr_t)buffer;
+
+       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_COMMIT, &arg);
+       if (ret) {
+               TDM_ERR("ipp commit failed. %xx pp_data(%p), buffer(%p). %m", DRM_IOCTL_EXYNOS_IPP_COMMIT, pp_data, buffer);
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+void
+tdm_exynos_pp_handler(unsigned int tv_sec, unsigned int tv_usec, void *data)
+{
+       tdm_exynos_pp_buffer *b = NULL, *bb, *dequeued_buffer = data;
+       tdm_exynos_pp_data *pp_data;
+
+       if (!dequeued_buffer) {
+               TDM_ERR("invalid params");
+               return;
+       }
+
+       if (!pp_list_init)
+               return;
+
+       pp_data = dequeued_buffer->pp_data;
+
+       TDM_DBG("pp_data(%p) buffer(%p)", pp_data, dequeued_buffer);
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->buffer_list, link) {
+               if (b == dequeued_buffer) {
+                       LIST_DEL(&dequeued_buffer->link);
+                       TDM_DBG("dequeued: %p", dequeued_buffer);
+                       break;
+               }
+       }
+
+       if (!pp_data->first_event) {
+               TDM_DBG("pp(%p) got a first event. ", pp_data);
+               pp_data->first_event = 1;
+       }
+
+       if (pp_data->done_func)
+               pp_data->done_func(pp_data,
+                                  dequeued_buffer->src,
+                                  dequeued_buffer->dst,
+                                  pp_data->done_user_data);
+       free(dequeued_buffer);
+}
+
+static enum drm_exynos_ipp_capability required_exynos_ipp_caps =
+       DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE |
+       DRM_EXYNOS_IPP_CAP_SCALE | DRM_EXYNOS_IPP_CAP_CONVERT;
+
+tdm_error
+tdm_exynos_pp_init(tdm_exynos_data *exynos_data)
+{
+       struct drm_exynos_ioctl_ipp_get_caps caps_arg;
+       struct drm_exynos_ioctl_ipp_get_res res_arg;
+       uint32_t *ipps;
+       int i;
+
+       exynos_data->ipp_module_id = -1;
+
+       CLEAR(res_arg);
+       if (ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_RESOURCES,
+                 &res_arg)) {
+               TDM_ERR("failed to get Exynos IPP resources");
+               return TDM_ERROR_NO_CAPABILITY;
+       }
+
+       ipps = calloc(res_arg.count_ipps, sizeof(*ipps));
+       if (!ipps) {
+               TDM_ERR("alloc failed");
+               return TDM_ERROR_OUT_OF_MEMORY;
+       }
+
+       res_arg.ipp_id_ptr = (unsigned long)ipps;
+       if (ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_RESOURCES,
+                 &res_arg)) {
+               TDM_ERR("failed to get Exynos IPP resources");
+               free(ipps);
+               return TDM_ERROR_NO_CAPABILITY;
+       }
+
+       for (i = 0; i < res_arg.count_ipps; i++) {
+               CLEAR(caps_arg);
+               caps_arg.ipp_id = ipps[i];
+               if (ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_CAPS,
+                 &caps_arg)) {
+                       TDM_ERR("failed to get IPP capabilities");
+                       free(ipps);
+                       return TDM_ERROR_NO_CAPABILITY;
+               }
+               if ((caps_arg.capabilities & required_exynos_ipp_caps) ==
+                   required_exynos_ipp_caps)
+                       break;
+       }
+       if (i == res_arg.count_ipps) {
+               free(ipps);
+               return TDM_ERROR_NO_CAPABILITY;
+       }
+
+       TDM_INFO("selected Exynos IPP module id %d", ipps[i]);
+       exynos_data->ipp_module_id = ipps[i];
+       free(ipps);
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+tdm_exynos_pp_get_capability(tdm_exynos_data *exynos_data, tdm_caps_pp *caps)
+{
+       struct drm_exynos_ioctl_ipp_get_caps caps_arg;
+       struct drm_exynos_ipp_format *formats;
+       int i, pp_formats;
+
+       if (!caps) {
+               TDM_ERR("invalid params");
+               return TDM_ERROR_INVALID_PARAMETER;
+       }
+
+       CLEAR(caps_arg);
+       caps_arg.ipp_id = exynos_data->ipp_module_id;
+       if (ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_CAPS,
+                 &caps_arg)) {
+               TDM_ERR("failed to get IPP capabilities");
+               return TDM_ERROR_NO_CAPABILITY;
+       }
+
+       formats = calloc(caps_arg.formats_count, sizeof(*formats));
+       if (!formats) {
+               TDM_ERR("alloc failed");
+               return TDM_ERROR_OUT_OF_MEMORY;
+       }
+
+       caps_arg.formats_ptr = (unsigned long) formats;
+       if (ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_CAPS,
+                 &caps_arg)) {
+               TDM_ERR("failed to get IPP capabilities");
+               free(formats);
+               return TDM_ERROR_NO_CAPABILITY;
+       }
+
+       for (pp_formats = 0, i = 0; i < caps_arg.formats_count; i++)
+               if (formats[i].modifier == 0 &&
+                   tdm_exynos_format_to_tbm_format(formats[i].fourcc))
+                       pp_formats++;
+
+       caps->capabilities = TDM_PP_CAPABILITY_ASYNC;
+       caps->format_count = pp_formats;
+
+       /* will be freed in frontend */
+       caps->formats = calloc(pp_formats, sizeof(tbm_format));
+       if (!caps->formats) {
+               TDM_ERR("alloc failed");
+               free(formats);
+               return TDM_ERROR_OUT_OF_MEMORY;
+       }
+
+       for (pp_formats = 0, i = 0; i < caps_arg.formats_count; i++) {
+               tbm_format f;
+               f = tdm_exynos_format_to_tbm_format(formats[i].fourcc);
+               if (formats[i].modifier == 0 && f)
+                       caps->formats[pp_formats++] = f;
+       }
+
+       caps->min_w = 16;
+       caps->min_h = 8;
+       caps->max_w = -1;   /* not defined */
+       caps->max_h = -1;
+       caps->preferred_align = 16;
+
+       caps->max_attach_count = -1;
+
+       free(formats);
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_pp *
+tdm_exynos_pp_create(tdm_exynos_data *exynos_data, tdm_error *error)
+{
+       tdm_exynos_pp_data *pp_data = calloc(1, sizeof(tdm_exynos_pp_data));
+       if (!pp_data) {
+               TDM_ERR("alloc failed");
+               if (error)
+                       *error = TDM_ERROR_OUT_OF_MEMORY;
+               return NULL;
+       }
+
+       pp_data->exynos_data = exynos_data;
+
+       LIST_INITHEAD(&pp_data->pending_buffer_list);
+       LIST_INITHEAD(&pp_data->buffer_list);
+
+       if (!pp_list_init) {
+               pp_list_init = 1;
+               LIST_INITHEAD(&pp_list);
+       }
+       LIST_ADDTAIL(&pp_data->link, &pp_list);
+
+       return pp_data;
+}
+
+void
+exynos_pp_destroy(tdm_pp *pp)
+{
+       tdm_exynos_pp_data *pp_data = pp;
+       tdm_exynos_pp_buffer *b = NULL, *bb = NULL;
+
+       if (!pp_data)
+               return;
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->pending_buffer_list, link) {
+               LIST_DEL(&b->link);
+               free(b);
+       }
+       LIST_DEL(&pp_data->link);
+
+       free(pp_data);
+}
+
+tdm_error
+exynos_pp_set_info(tdm_pp *pp, tdm_info_pp *info)
+{
+       tdm_exynos_pp_data *pp_data = pp;
+
+       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
+
+       if (info->sync) {
+               TDM_ERR("not support sync mode currently");
+               return TDM_ERROR_INVALID_PARAMETER;
+       }
+
+       pp_data->info = *info;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst)
+{
+       tdm_exynos_pp_data *pp_data = pp;
+       tdm_exynos_pp_buffer *buffer;
+
+       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(src, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(dst, TDM_ERROR_INVALID_PARAMETER);
+
+       buffer = calloc(1, sizeof(tdm_exynos_pp_buffer));
+       if (!buffer) {
+               TDM_ERR("alloc failed");
+               return TDM_ERROR_NONE;
+       }
+
+       LIST_ADDTAIL(&buffer->link, &pp_data->pending_buffer_list);
+       buffer->src = src;
+       buffer->dst = dst;
+       buffer->pp_data = pp_data;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_pp_commit(tdm_pp *pp)
+{
+       tdm_exynos_pp_data *pp_data = pp;
+       tdm_exynos_pp_buffer *b = NULL, *bb = NULL;
+
+       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->pending_buffer_list, link) {
+               LIST_DEL(&b->link);
+               _tdm_exynos_pp_process(pp_data, b);
+               LIST_ADDTAIL(&b->link, &pp_data->buffer_list);
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_pp_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func,
+                                                                 void *user_data)
+{
+       tdm_exynos_pp_data *pp_data = pp;
+
+       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
+
+       pp_data->done_func = func;
+       pp_data->done_user_data = user_data;
+
+       return TDM_ERROR_NONE;
+}
diff --git a/src/libtdm-exynos/tdm_exynos_pp.h b/src/libtdm-exynos/tdm_exynos_pp.h
new file mode 100644 (file)
index 0000000..07d3d34
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _TDM_EXYNOS_PP_H_
+#define _TDM_EXYNOS_PP_H_
+
+#include "tdm_exynos.h"
+
+tdm_error    tdm_exynos_pp_init(tdm_exynos_data *exynos_data);
+tdm_error    tdm_exynos_pp_get_capability(tdm_exynos_data *exynos_data, tdm_caps_pp *caps);
+tdm_pp*      tdm_exynos_pp_create(tdm_exynos_data *exynos_data, tdm_error *error);
+void         tdm_exynos_pp_handler(unsigned int tv_sec, unsigned int tv_usec, void *data);
+#endif /* _TDM_EXYNOS_PP_H_ */
diff --git a/src/libtdm-exynos/tdm_exynos_pp_legacy.c b/src/libtdm-exynos/tdm_exynos_pp_legacy.c
new file mode 100644 (file)
index 0000000..13a7237
--- /dev/null
@@ -0,0 +1,451 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_exynos.h"
+
+typedef struct _tdm_exynos_pp_legacy_buffer {
+       int index;
+       tbm_surface_h src;
+       tbm_surface_h dst;
+
+       struct list_head link;
+} tdm_exynos_pp_legacy_buffer;
+
+typedef struct _tdm_exynos_pp_legacy_data {
+       tdm_exynos_data *exynos_data;
+
+       unsigned int prop_id;
+
+       tdm_info_pp info;
+       int info_changed;
+
+       struct list_head pending_buffer_list;
+       struct list_head buffer_list;
+
+       tdm_pp_done_handler done_func;
+       void *done_user_data;
+
+       int startd;
+       int first_event;
+
+       struct list_head link;
+} tdm_exynos_pp_legacy_data;
+
+
+static tbm_format pp_formats[] = {
+       TBM_FORMAT_ARGB8888,
+       TBM_FORMAT_XRGB8888,
+       TBM_FORMAT_NV12,
+       TBM_FORMAT_NV21,
+       TBM_FORMAT_YUV420,
+       TBM_FORMAT_YVU420,
+#ifdef HAVE_TILED_FORMAT
+       TBM_FORMAT_NV12MT,
+#endif
+};
+
+#define NUM_PP_FORMAT   (sizeof(pp_formats) / sizeof(pp_formats[0]))
+
+static int pp_list_init;
+static struct list_head pp_list;
+
+static int
+_get_index(tdm_exynos_pp_legacy_data *pp_data)
+{
+       tdm_exynos_pp_legacy_buffer *buffer = NULL;
+       int ret = 0;
+
+       while (1) {
+               int found = 0;
+               LIST_FOR_EACH_ENTRY(buffer, &pp_data->pending_buffer_list, link) {
+                       if (ret == buffer->index) {
+                               found = 1;
+                               break;
+                       }
+               }
+               if (!found)
+                       LIST_FOR_EACH_ENTRY(buffer, &pp_data->buffer_list, link) {
+                       if (ret == buffer->index) {
+                               found = 1;
+                               break;
+                       }
+               }
+               if (!found)
+                       break;
+               ret++;
+       }
+
+       return ret;
+}
+
+static tdm_error
+_tdm_exynos_pp_legacy_set(tdm_exynos_pp_legacy_data *pp_data)
+{
+       tdm_exynos_data *exynos_data = pp_data->exynos_data;
+       tdm_info_pp *info = &pp_data->info;
+       struct drm_exynos_ipp_property property;
+       int ret = 0;
+
+       CLEAR(property);
+       property.config[0].ops_id = EXYNOS_DRM_OPS_SRC;
+       property.config[0].fmt = tdm_exynos_format_to_drm_format(info->src_config.format);
+       memcpy(&property.config[0].sz, &info->src_config.size, sizeof(tdm_size));
+       memcpy(&property.config[0].pos, &info->src_config.pos, sizeof(tdm_pos));
+       property.config[1].ops_id = EXYNOS_DRM_OPS_DST;
+       property.config[1].degree = info->transform % 4;
+       property.config[1].flip = (info->transform > 3) ? EXYNOS_DRM_FLIP_HORIZONTAL : 0;
+       property.config[1].fmt = tdm_exynos_format_to_drm_format(info->dst_config.format);
+       memcpy(&property.config[1].sz, &info->dst_config.size, sizeof(tdm_size));
+       memcpy(&property.config[1].pos, &info->dst_config.pos, sizeof(tdm_pos));
+       property.cmd = IPP_CMD_M2M;
+       property.prop_id = pp_data->prop_id;
+
+       TDM_DBG("src : flip(%x) deg(%d) fmt(%c%c%c%c) sz(%dx%d) pos(%d,%d %dx%d)  ",
+                       property.config[0].flip, property.config[0].degree,
+                       FOURCC_STR(property.config[0].fmt),
+                       property.config[0].sz.hsize, property.config[0].sz.vsize,
+                       property.config[0].pos.x, property.config[0].pos.y, property.config[0].pos.w,
+                       property.config[0].pos.h);
+       TDM_DBG("dst : flip(%x) deg(%d) fmt(%c%c%c%c) sz(%dx%d) pos(%d,%d %dx%d)  ",
+                       property.config[1].flip, property.config[1].degree,
+                       FOURCC_STR(property.config[1].fmt),
+                       property.config[1].sz.hsize, property.config[1].sz.vsize,
+                       property.config[1].pos.x, property.config[1].pos.y, property.config[1].pos.w,
+                       property.config[1].pos.h);
+
+       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_SET_PROPERTY, &property);
+       if (ret) {
+               TDM_ERR("failed: %m");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       TDM_DBG("success. prop_id(%d) ", property.prop_id);
+       pp_data->prop_id = property.prop_id;
+       return TDM_ERROR_NONE;
+}
+
+static tdm_error
+_tdm_exynos_pp_legacy_queue(tdm_exynos_pp_legacy_data *pp_data, tdm_exynos_pp_legacy_buffer *buffer,
+                                                       enum drm_exynos_ipp_buf_type type)
+{
+       tdm_exynos_data *exynos_data = pp_data->exynos_data;
+       struct drm_exynos_ipp_queue_buf buf;
+       int i, bo_num, ret = 0;
+
+       CLEAR(buf);
+       buf.prop_id = pp_data->prop_id;
+       buf.ops_id = EXYNOS_DRM_OPS_SRC;
+       buf.buf_type = type;
+       buf.buf_id = buffer->index;
+       buf.user_data = (__u64)(uintptr_t)pp_data;
+       bo_num = tbm_surface_internal_get_num_bos(buffer->src);
+       for (i = 0; i < EXYNOS_DRM_PLANAR_MAX && i < bo_num; i++) {
+               tbm_bo bo = tbm_surface_internal_get_bo(buffer->src, i);
+               buf.handle[i] = (__u32)tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
+       }
+
+       TDM_DBG("prop_id(%d) ops_id(%d) ctrl(%d) id(%d) handles(%x %x %x). ",
+                       buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id,
+                       buf.handle[0], buf.handle[1], buf.handle[2]);
+
+       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
+       if (ret) {
+               TDM_ERR("src failed. prop_id(%d) op(%d) buf(%d) id(%d). %m",
+                               buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id);
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       CLEAR(buf);
+       buf.prop_id = pp_data->prop_id;
+       buf.ops_id = EXYNOS_DRM_OPS_DST;
+       buf.buf_type = type;
+       buf.buf_id = buffer->index;
+       buf.user_data = (__u64)(uintptr_t)pp_data;
+       bo_num = tbm_surface_internal_get_num_bos(buffer->dst);
+       for (i = 0; i < EXYNOS_DRM_PLANAR_MAX && i < bo_num; i++) {
+               tbm_bo bo = tbm_surface_internal_get_bo(buffer->dst, i);
+               buf.handle[i] = (__u32)tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
+       }
+
+       TDM_DBG("prop_id(%d) ops_id(%d) ctrl(%d) id(%d) handles(%x %x %x). ",
+                       buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id,
+                       buf.handle[0], buf.handle[1], buf.handle[2]);
+
+       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
+       if (ret) {
+               TDM_ERR("dst failed. prop_id(%d) op(%d) buf(%d) id(%d). %m",
+                               buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id);
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       TDM_DBG("success. prop_id(%d)", buf.prop_id);
+
+       return TDM_ERROR_NONE;
+}
+
+static tdm_error
+_tdm_exynos_pp_legacy_cmd(tdm_exynos_pp_legacy_data *pp_data, enum drm_exynos_ipp_ctrl cmd)
+{
+       tdm_exynos_data *exynos_data = pp_data->exynos_data;
+       struct drm_exynos_ipp_cmd_ctrl ctrl;
+       int ret = 0;
+
+       ctrl.prop_id = pp_data->prop_id;
+       ctrl.ctrl = cmd;
+
+       TDM_DBG("prop_id(%d) ctrl(%d). ", ctrl.prop_id, ctrl.ctrl);
+
+       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_CMD_CTRL, &ctrl);
+       if (ret) {
+               TDM_ERR("failed. prop_id(%d) ctrl(%d). %m", ctrl.prop_id, ctrl.ctrl);
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       TDM_DBG("success. prop_id(%d) ", ctrl.prop_id);
+
+       return TDM_ERROR_NONE;
+}
+
+void
+tdm_exynos_pp_legacy_cb(int fd, unsigned int prop_id, unsigned int *buf_idx,
+                                         unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+       tdm_exynos_pp_legacy_handler(prop_id, buf_idx, tv_sec, tv_usec, user_data);
+}
+
+void
+tdm_exynos_pp_legacy_handler(unsigned int prop_id, unsigned int *buf_idx,
+                                                       unsigned int tv_sec, unsigned int tv_usec, void *data)
+{
+       tdm_exynos_pp_legacy_data *found = NULL, *d = NULL, *pp_data = data;
+       tdm_exynos_pp_legacy_buffer *b = NULL, *bb = NULL, *dequeued_buffer = NULL;
+
+       if (!pp_data || !buf_idx) {
+               TDM_ERR("invalid params");
+               return;
+       }
+
+       if (!pp_list_init)
+               return;
+
+       LIST_FOR_EACH_ENTRY(d, &pp_list, link) {
+               if (d == pp_data) {
+                       found = d;
+                       break;
+               }
+       }
+       if (!found)
+               return;
+
+       TDM_DBG("pp_data(%p) index(%d, %d)", pp_data, buf_idx[0], buf_idx[1]);
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->buffer_list, link) {
+               if (buf_idx[0] == b->index) {
+                       dequeued_buffer = b;
+                       LIST_DEL(&dequeued_buffer->link);
+                       TDM_DBG("dequeued: %d", dequeued_buffer->index);
+                       break;
+               }
+       }
+
+       if (!dequeued_buffer) {
+               TDM_ERR("not found buffer index: %d", buf_idx[0]);
+               return;
+       }
+
+       if (!pp_data->first_event) {
+               TDM_DBG("pp(%p) got a first event. ", pp_data);
+               pp_data->first_event = 1;
+       }
+
+       if (pp_data->done_func)
+               pp_data->done_func(pp_data,
+                                                  dequeued_buffer->src,
+                                                  dequeued_buffer->dst,
+                                                  pp_data->done_user_data);
+       free(dequeued_buffer);
+}
+
+tdm_error
+tdm_exynos_pp_legacy_get_capability(tdm_exynos_data *exynos_data, tdm_caps_pp *caps)
+{
+       int i;
+
+       if (!caps) {
+               TDM_ERR("invalid params");
+               return TDM_ERROR_INVALID_PARAMETER;
+       }
+
+       caps->capabilities = TDM_PP_CAPABILITY_ASYNC;
+
+       caps->format_count = NUM_PP_FORMAT;
+
+       /* will be freed in frontend */
+       caps->formats = calloc(1, sizeof pp_formats);
+       if (!caps->formats) {
+               TDM_ERR("alloc failed");
+               return TDM_ERROR_OUT_OF_MEMORY;
+       }
+       for (i = 0; i < caps->format_count; i++)
+               caps->formats[i] = pp_formats[i];
+
+       caps->min_w = 16;
+       caps->min_h = 8;
+       caps->max_w = -1;   /* not defined */
+       caps->max_h = -1;
+       caps->preferred_align = 16;
+
+       caps->max_attach_count = -1;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_pp *
+tdm_exynos_pp_legacy_create(tdm_exynos_data *exynos_data, tdm_error *error)
+{
+       tdm_exynos_pp_legacy_data *pp_data = calloc(1, sizeof(tdm_exynos_pp_legacy_data));
+       if (!pp_data) {
+               TDM_ERR("alloc failed");
+               if (error)
+                       *error = TDM_ERROR_OUT_OF_MEMORY;
+               return NULL;
+       }
+
+       pp_data->exynos_data = exynos_data;
+
+       LIST_INITHEAD(&pp_data->pending_buffer_list);
+       LIST_INITHEAD(&pp_data->buffer_list);
+
+       if (!pp_list_init) {
+               pp_list_init = 1;
+               LIST_INITHEAD(&pp_list);
+       }
+       LIST_ADDTAIL(&pp_data->link, &pp_list);
+
+       return pp_data;
+}
+
+void
+exynos_pp_legacy_destroy(tdm_pp *pp)
+{
+       tdm_exynos_pp_legacy_data *pp_data = pp;
+       tdm_exynos_pp_legacy_buffer *b = NULL, *bb = NULL;
+
+       if (!pp_data)
+               return;
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->pending_buffer_list, link) {
+               LIST_DEL(&b->link);
+               free(b);
+       }
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->buffer_list, link) {
+               LIST_DEL(&b->link);
+               _tdm_exynos_pp_legacy_queue(pp_data, b, IPP_BUF_DEQUEUE);
+               free(b);
+       }
+
+       if (pp_data->prop_id)
+               _tdm_exynos_pp_legacy_cmd(pp_data, IPP_CTRL_STOP);
+
+       LIST_DEL(&pp_data->link);
+
+       free(pp_data);
+}
+
+tdm_error
+exynos_pp_legacy_set_info(tdm_pp *pp, tdm_info_pp *info)
+{
+       tdm_exynos_pp_legacy_data *pp_data = pp;
+
+       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
+
+       if (info->sync) {
+               TDM_ERR("not support sync mode currently");
+               return TDM_ERROR_INVALID_PARAMETER;
+       }
+
+       pp_data->info = *info;
+       pp_data->info_changed = 1;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_pp_legacy_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst)
+{
+       tdm_exynos_pp_legacy_data *pp_data = pp;
+       tdm_exynos_pp_legacy_buffer *buffer;
+
+       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(src, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(dst, TDM_ERROR_INVALID_PARAMETER);
+
+       buffer = calloc(1, sizeof(tdm_exynos_pp_legacy_buffer));
+       if (!buffer) {
+               TDM_ERR("alloc failed");
+               return TDM_ERROR_NONE;
+       }
+
+       LIST_ADDTAIL(&buffer->link, &pp_data->pending_buffer_list);
+       buffer->index = _get_index(pp_data);
+       buffer->src = src;
+       buffer->dst = dst;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_pp_legacy_commit(tdm_pp *pp)
+{
+       tdm_exynos_pp_legacy_data *pp_data = pp;
+       tdm_exynos_pp_legacy_buffer *b = NULL, *bb = NULL;
+       tdm_error ret;
+
+       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
+
+       if (pp_data->info_changed) {
+               if (pp_data->startd)
+                       _tdm_exynos_pp_legacy_cmd(pp_data, IPP_CTRL_PAUSE);
+
+               ret = _tdm_exynos_pp_legacy_set(pp_data);
+               if (ret < 0)
+                       return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->pending_buffer_list, link) {
+               LIST_DEL(&b->link);
+               _tdm_exynos_pp_legacy_queue(pp_data, b, IPP_BUF_ENQUEUE);
+               TDM_DBG("queued: %d", b->index);
+               LIST_ADDTAIL(&b->link, &pp_data->buffer_list);
+       }
+
+       if (pp_data->info_changed) {
+               pp_data->info_changed = 0;
+
+               if (!pp_data->startd) {
+                       pp_data->startd = 1;
+                       _tdm_exynos_pp_legacy_cmd(pp_data, IPP_CTRL_PLAY);
+               } else
+                       _tdm_exynos_pp_legacy_cmd(pp_data, IPP_CTRL_RESUME);
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+exynos_pp_legacy_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func,
+                                                                 void *user_data)
+{
+       tdm_exynos_pp_legacy_data *pp_data = pp;
+
+       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
+
+       pp_data->done_func = func;
+       pp_data->done_user_data = user_data;
+
+       return TDM_ERROR_NONE;
+}
diff --git a/src/libtdm-exynos/tdm_exynos_pp_legacy.h b/src/libtdm-exynos/tdm_exynos_pp_legacy.h
new file mode 100644 (file)
index 0000000..21354bf
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _TDM_EXYNOS_PP_LEGACY_H_
+#define _TDM_EXYNOS_PP_LEGACY_H_
+
+#include "tdm_exynos.h"
+
+tdm_error    tdm_exynos_pp_legacy_get_capability(tdm_exynos_data *exynos_data, tdm_caps_pp *caps);
+tdm_pp*      tdm_exynos_pp_legacy_create(tdm_exynos_data *exynos_data, tdm_error *error);
+void         tdm_exynos_pp_legacy_handler(unsigned int prop_id, unsigned int *buf_idx,
+                                                                                unsigned int tv_sec, unsigned int tv_usec, void *data);
+void         tdm_exynos_pp_legacy_cb(int fd, unsigned int prop_id, unsigned int *buf_idx,
+                                                                       unsigned int tv_sec, unsigned int tv_usec,
+                                                                       void *user_data);
+#endif /* _TDM_EXYNOS_PP_LEGACY_H_ */
diff --git a/src/libtdm-exynos/tdm_exynos_types.h b/src/libtdm-exynos/tdm_exynos_types.h
new file mode 100644 (file)
index 0000000..93bc57e
--- /dev/null
@@ -0,0 +1,239 @@
+#ifndef _TDM_EXYNOS_TYPES_H_
+#define _TDM_EXYNOS_TYPES_H_
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+#include <exynos_drm.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+#include <tdm_backend.h>
+#include <tdm_log.h>
+#include <tdm_list.h>
+
+#if HAVE_UDEV
+#include <libudev.h>
+#endif
+
+/* exynos module internal macros, structures */
+#define NEVER_GET_HERE() TDM_ERR("** NEVER GET HERE **")
+
+#define C(b, m)                (((b) >> (m)) & 0xFF)
+#define B(c, s)                ((((unsigned int)(c)) & 0xff) << (s))
+#define FOURCC(a, b, c, d)     (B(d, 24) | B(c, 16) | B(b, 8) | B(a, 0))
+#define FOURCC_STR(id)         C(id, 0), C(id, 8), C(id, 16), C(id, 24)
+
+#define IS_RGB(format)      (format == TBM_FORMAT_XRGB8888 || format == TBM_FORMAT_ARGB8888 || \
+                                                       format == TBM_FORMAT_XBGR8888 || format == TBM_FORMAT_ABGR8888)
+
+#define CLEAR(x) memset(&(x), 0, sizeof(x))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define SWAP(a, b)  ({ \
+                                               int t; \
+                                               t = a; \
+                                               a = b; \
+                                               b = t; \
+                                       })
+#define ROUNDUP(x)  (ceil(floor((float)(height) / 4)))
+
+#define ALIGN_TO_16B(x)    ((((x) + (1 <<  4) - 1) >>  4) <<  4)
+#define ALIGN_TO_32B(x)    ((((x) + (1 <<  5) - 1) >>  5) <<  5)
+#define ALIGN_TO_128B(x)   ((((x) + (1 <<  7) - 1) >>  7) <<  7)
+#define ALIGN_TO_2KB(x)    ((((x) + (1 << 11) - 1) >> 11) << 11)
+#define ALIGN_TO_8KB(x)    ((((x) + (1 << 13) - 1) >> 13) << 13)
+#define ALIGN_TO_64KB(x)   ((((x) + (1 << 16) - 1) >> 16) << 16)
+
+#define RETURN_IF_FAIL(cond) { \
+       if (!(cond)) { \
+               TDM_ERR("'%s' failed", #cond); \
+               return; \
+       } \
+}
+#define RETURN_VAL_IF_FAIL(cond, val) { \
+       if (!(cond)) { \
+               TDM_ERR("'%s' failed", #cond); \
+               return val; \
+       } \
+}
+
+typedef enum {
+       TDM_EXYNOS_EVENT_TYPE_WAIT,
+       TDM_EXYNOS_EVENT_TYPE_COMMIT,
+       TDM_EXYNOS_EVENT_TYPE_PAGEFLIP,
+} tdm_exynos_event_type;
+
+typedef struct _tdm_exynos_data tdm_exynos_data;
+typedef struct _tdm_exynos_output_data tdm_exynos_output_data;
+typedef struct _tdm_exynos_layer_data tdm_exynos_layer_data;
+typedef struct _tdm_exynos_hwc_data tdm_exynos_hwc_data;
+typedef struct _tdm_exynos_hwc_window_data tdm_exynos_hwc_window_data;
+typedef struct _tdm_exynos_event_data tdm_exynos_event_data;
+typedef struct _tdm_exynos_display_buffer tdm_exynos_display_buffer;
+
+struct _tdm_exynos_data {
+       tdm_display *dpy;
+
+       int drm_fd;
+
+#if HAVE_UDEV
+       struct udev_monitor *uevent_monitor;
+       tdm_event_loop_source *uevent_source;
+#endif
+
+       /* If true, it means that the device has many planes for one crtc. If false,
+        * planes are dedicated to specific crtc.
+        */
+       int has_zpos_info;
+
+       /* If has_zpos_info is false and is_immutable_zpos is true, it means that
+        * planes are dedicated to specific crtc.
+        */
+       int is_immutable_zpos;
+
+       drmModeResPtr mode_res;
+       drmModePlaneResPtr plane_res;
+
+       int hwc_mode;
+
+       struct list_head output_list;
+       struct list_head buffer_list;
+
+       int use_ippv2;
+       int ipp_module_id;
+};
+
+struct _tdm_exynos_output_data {
+       struct list_head link;
+
+       /* data which are fixed at initializing */
+       tdm_exynos_data *exynos_data;
+       uint32_t connector_id;
+       uint32_t encoder_id;
+       uint32_t crtc_id;
+       uint32_t pipe;
+       uint32_t dpms_prop_id;
+       int count_modes;
+       drmModeModeInfoPtr drm_modes;
+       tdm_output_mode *output_modes;
+       tdm_output_type connector_type;
+       unsigned int connector_type_id;
+       struct list_head layer_list;
+       tdm_exynos_layer_data *primary_layer;
+
+       /* not fixed data below */
+       tdm_output_vblank_handler vblank_func;
+       tdm_output_commit_handler commit_func;
+
+       tdm_output_conn_status status;
+       tdm_output_status_handler status_func;
+       void *status_user_data;
+
+       int mode_changed;
+       const tdm_output_mode *current_mode;
+
+       int crtc_set;
+
+       /* hwc data */
+       int hwc_enable;
+       tdm_exynos_hwc_data *hwc_data;
+};
+
+struct _tdm_exynos_layer_data {
+       struct list_head link;
+
+       /* data which are fixed at initializing */
+       tdm_exynos_data *exynos_data;
+       tdm_exynos_output_data *output_data;
+       uint32_t plane_id;
+       tdm_layer_capability capabilities;
+       int zpos;
+
+       /* not fixed data below */
+       tdm_info_layer info;
+       int info_changed;
+
+       tdm_exynos_display_buffer *display_buffer;
+       int display_buffer_changed;
+       int display_buffer_force_unset;
+
+       tbm_format *formats;
+       int format_count;
+
+       tdm_prop *props;
+       int prop_count;
+};
+
+struct _tdm_exynos_hwc_data {
+       tdm_exynos_hwc_window_data *target_hwc_window;
+
+       int need_validate;
+       int need_target_window;
+
+       int target_window_zpos;
+
+       tdm_exynos_output_data *output_data;
+       struct list_head hwc_window_list;
+
+       tdm_hwc_commit_handler commit_func;
+};
+
+struct _tdm_exynos_hwc_window_data {
+       struct list_head link;
+
+       /* data which are fixed at initializing */
+       tdm_exynos_hwc_data *hwc_data;
+
+       /* not fixed data below */
+       tdm_hwc_window_info info;
+       int info_changed;
+
+       tbm_surface_h surface;
+       int display_buffer_changed;
+       int enabled_flag;
+
+       /* client_type stores the initial type given to us by client(compositor),
+        *  validated_type stores the type after running Validate
+        */
+       tdm_hwc_window_composition client_type;
+       tdm_hwc_window_composition validated_type;
+
+       int candidate_layer_zpos;
+       int assigned_layer_zpos;
+};
+
+struct _tdm_exynos_display_buffer {
+       tdm_exynos_data *exynos_data;
+       unsigned int fb_id;
+       tbm_surface_h buffer;
+       int width;
+};
+
+struct _tdm_exynos_event_data {
+       tdm_exynos_event_type type;
+       tdm_exynos_output_data *output_data;
+       void *user_data;
+       int hwc_mode;
+};
+
+typedef struct _Drm_Event_Context {
+       void (*pageflip_handler)(int fd, unsigned int sequence, unsigned int tv_sec,
+                                                        unsigned int tv_usec, void *user_data);
+       void (*vblank_handler)(int fd, unsigned int sequence, unsigned int tv_sec,
+                                                  unsigned int tv_usec, void *user_data);
+       void (*pp_handler)(int fd, unsigned int  prop_id, unsigned int *buf_idx,
+                                          unsigned int  tv_sec, unsigned int  tv_usec, void *user_data);
+} Drm_Event_Context;
+
+#endif /* _TDM_EXYNOS_TYPES_H_ */
diff --git a/src/tdm_exynos.c b/src/tdm_exynos.c
deleted file mode 100644 (file)
index 67f87ac..0000000
+++ /dev/null
@@ -1,546 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#if HAVE_UDEV
-#include <libudev.h>
-#endif
-
-#include "tdm_exynos.h"
-#include <tdm_helper.h>
-#include <tbm_drm_helper.h>
-
-#define EXYNOS_DRM_NAME "exynos"
-
-static tdm_exynos_data *exynos_data;
-unsigned int exynos_screen_prerotation_hint;
-
-#ifdef HAVE_UDEV
-static tdm_error
-_tdm_exynos_udev_fd_handler(int fd, tdm_event_loop_mask mask, void *user_data)
-{
-       tdm_exynos_data *edata = (tdm_exynos_data*)user_data;
-       struct udev_device *dev;
-       const char *hotplug;
-       struct stat s;
-       dev_t udev_devnum;
-       int ret;
-
-       dev = udev_monitor_receive_device(edata->uevent_monitor);
-       if (!dev) {
-               TDM_ERR("couldn't receive device");
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       udev_devnum = udev_device_get_devnum(dev);
-
-       ret = fstat(edata->drm_fd, &s);
-       if (ret == -1) {
-               TDM_ERR("fstat failed");
-               udev_device_unref(dev);
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       hotplug = udev_device_get_property_value(dev, "HOTPLUG");
-
-       if (memcmp(&s.st_rdev, &udev_devnum, sizeof(dev_t)) == 0 &&
-                          hotplug && atoi(hotplug) == 1) {
-               TDM_INFO("HotPlug");
-               tdm_exynos_display_update_output_status(edata);
-       }
-
-       udev_device_unref(dev);
-
-       return TDM_ERROR_NONE;
-}
-
-static void
-_tdm_exynos_udev_init(tdm_exynos_data *edata)
-{
-       struct udev *u = NULL;
-       struct udev_monitor *mon = NULL;
-
-       u = udev_new();
-       if (!u) {
-               TDM_ERR("couldn't create udev");
-               goto failed;
-       }
-
-       mon = udev_monitor_new_from_netlink(u, "udev");
-       if (!mon) {
-               TDM_ERR("couldn't create udev monitor");
-               goto failed;
-       }
-
-       if (udev_monitor_filter_add_match_subsystem_devtype(mon, "drm", "drm_minor") > 0 ||
-           udev_monitor_enable_receiving(mon) < 0) {
-               TDM_ERR("add match subsystem failed");
-               goto failed;
-       }
-
-       edata->uevent_source =
-               tdm_event_loop_add_fd_handler(edata->dpy, udev_monitor_get_fd(mon),
-                                                                         TDM_EVENT_LOOP_READABLE,
-                                                                         _tdm_exynos_udev_fd_handler,
-                                                                         edata, NULL);
-       if (!edata->uevent_source) {
-               TDM_ERR("couldn't create udev event source");
-               goto failed;
-       }
-
-       edata->uevent_monitor = mon;
-
-       TDM_INFO("hotplug monitor created");
-
-       return;
-failed:
-       if (mon)
-               udev_monitor_unref(mon);
-       if (u)
-               udev_unref(u);
-}
-
-static void
-_tdm_exynos_udev_deinit(tdm_exynos_data *edata)
-{
-       if (edata->uevent_source) {
-               tdm_event_loop_source_remove(edata->uevent_source);
-               edata->uevent_source = NULL;
-       }
-
-       if (edata->uevent_monitor) {
-               struct udev *u = udev_monitor_get_udev(edata->uevent_monitor);
-               udev_monitor_unref(edata->uevent_monitor);
-               udev_unref(u);
-               edata->uevent_monitor = NULL;
-               TDM_INFO("hotplug monitor destroyed");
-       }
-}
-#endif
-
-static int
-_tdm_exynos_open_drm(void)
-{
-       int fd = -1;
-
-       fd = drmOpen(EXYNOS_DRM_NAME, NULL);
-       if (fd < 0)
-               TDM_ERR("Cannot open '%s' drm", EXYNOS_DRM_NAME);
-
-#ifdef HAVE_UDEV
-       if (fd < 0) {
-               struct udev *udev;
-               struct udev_enumerate *e;
-               struct udev_list_entry *entry;
-               struct udev_device *device, *drm_device, *device_parent;
-               const char *filename;
-
-               TDM_WRN("Cannot open drm device.. search by udev");
-               udev = udev_new();
-               if (!udev) {
-                       TDM_ERR("fail to initialize udev context\n");
-                       goto close_l;
-               }
-
-               /* Will try to find sys path /exynos-drm/drm/card0 */
-               e = udev_enumerate_new(udev);
-               udev_enumerate_add_match_subsystem(e, "drm");
-               udev_enumerate_add_match_sysname(e, "card[0-9]*");
-               udev_enumerate_scan_devices(e);
-
-               drm_device = NULL;
-               udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
-                       device = udev_device_new_from_syspath(udev_enumerate_get_udev(e),
-                                                                                                 udev_list_entry_get_name(entry));
-                       device_parent = udev_device_get_parent(device);
-                       /* Not need unref device_parent. device_parent and device have same refcnt */
-                       if (device_parent) {
-                               if (strcmp(udev_device_get_sysname(device_parent), "exynos-drm") == 0) {
-                                       drm_device = device;
-                                       TDM_DBG("Found drm device: '%s' (%s)\n",
-                                                       udev_device_get_syspath(drm_device),
-                                                       udev_device_get_sysname(device_parent));
-                                       break;
-                               }
-                       }
-                       udev_device_unref(device);
-               }
-
-               if (drm_device == NULL) {
-                       TDM_ERR("fail to find drm device\n");
-                       udev_enumerate_unref(e);
-                       udev_unref(udev);
-                       goto close_l;
-               }
-
-               filename = udev_device_get_devnode(drm_device);
-
-               fd = open(filename, O_RDWR | O_CLOEXEC);
-               if (fd < 0)
-                       TDM_ERR("Cannot open drm device(%s)\n", filename);
-               udev_device_unref(drm_device);
-               udev_enumerate_unref(e);
-               udev_unref(udev);
-       }
-close_l:
-#endif
-       return fd;
-}
-
-static int
-_tdm_exynos_drm_user_handler_legacy(struct drm_event *event)
-{
-       struct drm_exynos_ipp_event *ipp;
-
-       if (event->type != DRM_EXYNOS_IPP_EVENT)
-               return -1;
-
-       TDM_DBG("got ipp event");
-
-       ipp = (struct drm_exynos_ipp_event *)event;
-
-       if (tdm_exynos_capture_legacy_find_prop_id(ipp->prop_id))
-               tdm_exynos_capture_legacy_stream_pp_handler(ipp->prop_id, ipp->buf_id, ipp->tv_sec, ipp->tv_usec,
-                                                                                        (void *)(unsigned long)ipp->user_data);
-       else
-               tdm_exynos_pp_legacy_handler(ipp->prop_id, ipp->buf_id, ipp->tv_sec, ipp->tv_usec,
-                                                         (void *)(unsigned long)ipp->user_data);
-
-       return 0;
-}
-
-static int
-_tdm_exynos_drm_user_handler(struct drm_event *event)
-{
-       struct drm_exynos_ipp2_event *ipp;
-
-       if (event->type != DRM_EXYNOS_IPP2_EVENT)
-               return -1;
-
-       ipp = (struct drm_exynos_ipp2_event *)event;
-
-       tdm_exynos_pp_handler(ipp->tv_sec, ipp->tv_usec, (void *)(unsigned long)ipp->user_data);
-
-       return 0;
-}
-
-void
-tdm_exynos_deinit(tdm_backend_data *bdata)
-{
-       if (exynos_data != bdata)
-               return;
-
-       TDM_INFO("deinit");
-
-#ifdef HAVE_UDEV
-       _tdm_exynos_udev_deinit(exynos_data);
-#endif
-
-       if (exynos_data->use_ippv2)
-               drmRemoveUserHandler(exynos_data->drm_fd, _tdm_exynos_drm_user_handler);
-       else
-               drmRemoveUserHandler(exynos_data->drm_fd, _tdm_exynos_drm_user_handler_legacy);
-
-       tdm_exynos_display_destroy_output_list(exynos_data);
-
-       if (exynos_data->plane_res)
-               drmModeFreePlaneResources(exynos_data->plane_res);
-       if (exynos_data->mode_res)
-               drmModeFreeResources(exynos_data->mode_res);
-       if (exynos_data->drm_fd >= 0)
-               close(exynos_data->drm_fd);
-
-       free(exynos_data);
-       exynos_data = NULL;
-}
-
-tdm_backend_data *
-tdm_exynos_init(tdm_display *dpy, tdm_error *error)
-{
-       tdm_func_display exynos_func_display;
-       tdm_func_output exynos_func_output;
-       tdm_func_layer exynos_func_layer;
-       tdm_func_hwc exynos_func_hwc;
-       tdm_func_hwc_window exynos_func_hwc_window;
-       tdm_func_pp exynos_func_pp;
-       tdm_func_capture exynos_func_capture;
-       tdm_error ret;
-       const char *value;
-       drmVersionPtr drm_version;
-
-       value = (const char*)getenv("SCREEN_PREROTATION_HINT");
-       if (value) {
-               char *end;
-               exynos_screen_prerotation_hint = strtol(value, &end, 10);
-               TDM_INFO("SCREEN_PREROTATION_HINT = %d", exynos_screen_prerotation_hint);
-       }
-
-       if (!dpy) {
-               TDM_ERR("display is null");
-               if (error)
-                       *error = TDM_ERROR_INVALID_PARAMETER;
-               return NULL;
-       }
-
-       if (exynos_data) {
-               TDM_ERR("failed: init twice");
-               if (error)
-                       *error = TDM_ERROR_BAD_REQUEST;
-               return NULL;
-       }
-
-       exynos_data = calloc(1, sizeof(tdm_exynos_data));
-       if (!exynos_data) {
-               TDM_ERR("alloc failed");
-               if (error)
-                       *error = TDM_ERROR_OUT_OF_MEMORY;
-               return NULL;
-       }
-
-       exynos_data->dpy = dpy;
-
-       /* The drm master fd can be opened by a tbm backend module in
-        * tbm_bufmgr_init() time. In this case, we just get it from tbm.
-        */
-       exynos_data->drm_fd = tbm_drm_helper_get_master_fd();
-       if (exynos_data->drm_fd < 0) {
-               exynos_data->drm_fd = _tdm_exynos_open_drm();
-
-               if (exynos_data->drm_fd < 0) {
-                       ret = TDM_ERROR_OPERATION_FAILED;
-                       goto failed;
-               }
-
-               tbm_drm_helper_set_tbm_master_fd(exynos_data->drm_fd);
-       }
-
-       TDM_INFO("master fd(%d)", exynos_data->drm_fd);
-
-#ifdef HAVE_UDEV
-       _tdm_exynos_udev_init(exynos_data);
-#endif
-
-       drm_version = drmGetVersion(exynos_data->drm_fd);
-       if (!drm_version) {
-               TDM_ERR("no drm version: %m");
-               ret = TDM_ERROR_OPERATION_FAILED;
-               goto failed;
-       } else {
-               TDM_INFO("drm version: %d.%d.%d",
-                                drm_version->version_major,
-                                drm_version->version_minor,
-                                drm_version->version_patchlevel);
-               if (drm_version->version_major > 1 ||
-                       (drm_version->version_major == 1 && drm_version->version_minor >= 1))
-                       exynos_data->use_ippv2 = 1;
-               drmFreeVersion(drm_version);
-       }
-
-       value = getenv("TDM_HWC");
-       if (value)
-               exynos_data->hwc_mode = strtol(value, NULL, 10);
-
-       LIST_INITHEAD(&exynos_data->output_list);
-       LIST_INITHEAD(&exynos_data->buffer_list);
-
-       memset(&exynos_func_display, 0, sizeof(exynos_func_display));
-       exynos_func_display.display_get_capability = exynos_display_get_capability;
-       exynos_func_display.display_get_pp_capability = exynos_display_get_pp_capability;
-       exynos_func_display.display_get_capture_capability = exynos_display_get_capture_capability;
-       exynos_func_display.display_get_outputs = exynos_display_get_outputs;
-       exynos_func_display.display_get_fd = exynos_display_get_fd;
-       exynos_func_display.display_handle_events = exynos_display_handle_events;
-       exynos_func_display.display_create_pp = exynos_display_create_pp;
-
-       memset(&exynos_func_output, 0, sizeof(exynos_func_output));
-       exynos_func_output.output_get_capability = exynos_output_get_capability;
-       exynos_func_output.output_get_layers = exynos_output_get_layers;
-       exynos_func_output.output_set_property = exynos_output_set_property;
-       exynos_func_output.output_get_property = exynos_output_get_property;
-       exynos_func_output.output_wait_vblank = exynos_output_wait_vblank;
-       exynos_func_output.output_set_vblank_handler = exynos_output_set_vblank_handler;
-       exynos_func_output.output_commit = exynos_output_commit;
-       exynos_func_output.output_set_commit_handler = exynos_output_set_commit_handler;
-       exynos_func_output.output_set_dpms = exynos_output_set_dpms;
-       exynos_func_output.output_get_dpms = exynos_output_get_dpms;
-       exynos_func_output.output_set_mode = exynos_output_set_mode;
-       exynos_func_output.output_get_mode = exynos_output_get_mode;
-       exynos_func_output.output_create_capture = exynos_output_create_capture;
-#ifdef HAVE_UDEV
-       exynos_func_output.output_set_status_handler = exynos_output_set_status_handler;
-#endif
-       if (exynos_data->hwc_mode) {
-               exynos_func_output.output_get_hwc = exynos_output_get_hwc;
-
-               memset(&exynos_func_hwc, 0, sizeof(exynos_func_hwc));
-               exynos_func_hwc.hwc_create_window = exynos_hwc_create_window;
-               exynos_func_hwc.hwc_get_video_supported_formats = exynos_hwc_get_video_supported_formats;
-               exynos_func_hwc.hwc_get_capabilities = exynos_hwc_get_capabilities;
-               exynos_func_hwc.hwc_get_available_properties = exynos_hwc_get_available_properties;
-               exynos_func_hwc.hwc_get_client_target_buffer_queue = exynos_hwc_get_client_target_buffer_queue;
-               exynos_func_hwc.hwc_set_client_target_buffer = exynos_hwc_set_client_target_buffer;
-               exynos_func_hwc.hwc_validate = exynos_hwc_validate;
-               exynos_func_hwc.hwc_get_changed_composition_types = exynos_hwc_get_changed_composition_types;
-               exynos_func_hwc.hwc_accept_validation  = exynos_hwc_accept_validation;
-               exynos_func_hwc.hwc_commit = exynos_hwc_commit;
-               exynos_func_hwc.hwc_set_commit_handler = exynos_hwc_set_commit_handler;
-
-               memset(&exynos_func_hwc_window, 0, sizeof(exynos_func_hwc_window));
-               exynos_func_hwc_window.hwc_window_destroy = exynos_hwc_window_destroy;
-               exynos_func_hwc_window.hwc_window_acquire_buffer_queue = NULL;
-               exynos_func_hwc_window.hwc_window_release_buffer_queue = NULL;
-               exynos_func_hwc_window.hwc_window_set_composition_type = exynos_hwc_window_set_composition_type;
-               exynos_func_hwc_window.hwc_window_set_buffer_damage = exynos_hwc_window_set_buffer_damage;
-               exynos_func_hwc_window.hwc_window_set_info = exynos_hwc_window_set_info;
-               exynos_func_hwc_window.hwc_window_set_buffer = exynos_hwc_window_set_buffer;
-               exynos_func_hwc_window.hwc_window_set_property = exynos_hwc_window_set_property;
-               exynos_func_hwc_window.hwc_window_get_property = exynos_hwc_window_get_property;
-               exynos_func_hwc_window.hwc_window_get_constraints = exynos_hwc_window_get_constraints;
-       }
-
-       memset(&exynos_func_layer, 0, sizeof(exynos_func_layer));
-       exynos_func_layer.layer_get_capability = exynos_layer_get_capability;
-       exynos_func_layer.layer_set_property = exynos_layer_set_property;
-       exynos_func_layer.layer_get_property = exynos_layer_get_property;
-       exynos_func_layer.layer_set_info = exynos_layer_set_info;
-       exynos_func_layer.layer_get_info = exynos_layer_get_info;
-       exynos_func_layer.layer_set_buffer = exynos_layer_set_buffer;
-       exynos_func_layer.layer_unset_buffer = exynos_layer_unset_buffer;
-
-       memset(&exynos_func_pp, 0, sizeof(exynos_func_pp));
-       if (exynos_data->use_ippv2) {
-               exynos_func_pp.pp_destroy = exynos_pp_destroy;
-               exynos_func_pp.pp_set_info = exynos_pp_set_info;
-               exynos_func_pp.pp_attach = exynos_pp_attach;
-               exynos_func_pp.pp_commit = exynos_pp_commit;
-               exynos_func_pp.pp_set_done_handler = exynos_pp_set_done_handler;
-       } else {
-               exynos_func_pp.pp_destroy = exynos_pp_legacy_destroy;
-               exynos_func_pp.pp_set_info = exynos_pp_legacy_set_info;
-               exynos_func_pp.pp_attach = exynos_pp_legacy_attach;
-               exynos_func_pp.pp_commit = exynos_pp_legacy_commit;
-               exynos_func_pp.pp_set_done_handler = exynos_pp_legacy_set_done_handler;
-       }
-
-       memset(&exynos_func_capture, 0, sizeof(exynos_func_capture));
-       if (exynos_data->use_ippv2) {
-               exynos_func_capture.capture_destroy = exynos_capture_destroy;
-               exynos_func_capture.capture_set_info = exynos_capture_set_info;
-               exynos_func_capture.capture_attach = exynos_capture_attach;
-               exynos_func_capture.capture_commit = exynos_capture_commit;
-               exynos_func_capture.capture_set_done_handler = exynos_capture_set_done_handler;
-       } else {
-               exynos_func_capture.capture_destroy = exynos_capture_legacy_destroy;
-               exynos_func_capture.capture_set_info = exynos_capture_legacy_set_info;
-               exynos_func_capture.capture_attach = exynos_capture_legacy_attach;
-               exynos_func_capture.capture_commit = exynos_capture_legacy_commit;
-               exynos_func_capture.capture_set_done_handler = exynos_capture_legacy_set_done_handler;
-       }
-
-       ret = tdm_backend_register_func_display(dpy, &exynos_func_display);
-       if (ret != TDM_ERROR_NONE)
-               goto failed;
-
-       ret = tdm_backend_register_func_output(dpy, &exynos_func_output);
-       if (ret != TDM_ERROR_NONE)
-               goto failed;
-
-       ret = tdm_backend_register_func_layer(dpy, &exynos_func_layer);
-       if (ret != TDM_ERROR_NONE)
-               goto failed;
-
-       if (exynos_data->hwc_mode) {
-               ret = tdm_backend_register_func_hwc(dpy, &exynos_func_hwc);
-               if (ret != TDM_ERROR_NONE)
-                       goto failed;
-
-               ret = tdm_backend_register_func_hwc_window(dpy, &exynos_func_hwc_window);
-               if (ret != TDM_ERROR_NONE)
-                       goto failed;
-       }
-
-       ret = tdm_backend_register_func_pp(dpy, &exynos_func_pp);
-       if (ret != TDM_ERROR_NONE)
-               goto failed;
-
-       ret = tdm_backend_register_func_capture(dpy, &exynos_func_capture);
-       if (ret != TDM_ERROR_NONE)
-               goto failed;
-
-       if (exynos_data->use_ippv2)
-               drmAddUserHandler(exynos_data->drm_fd, _tdm_exynos_drm_user_handler);
-       else
-               drmAddUserHandler(exynos_data->drm_fd, _tdm_exynos_drm_user_handler_legacy);
-
-       if (drmSetClientCap(exynos_data->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) < 0)
-               TDM_WRN("Set DRM_CLIENT_CAP_UNIVERSAL_PLANES failed");
-
-       exynos_data->mode_res = drmModeGetResources(exynos_data->drm_fd);
-       if (!exynos_data->mode_res) {
-               TDM_ERR("no drm resource: %m");
-               ret = TDM_ERROR_OPERATION_FAILED;
-               goto failed;
-       }
-
-       exynos_data->plane_res = drmModeGetPlaneResources(exynos_data->drm_fd);
-       if (!exynos_data->plane_res) {
-               TDM_ERR("no drm plane resource: %m");
-               ret = TDM_ERROR_OPERATION_FAILED;
-               goto failed;
-       }
-
-       if (exynos_data->plane_res->count_planes <= 0) {
-               TDM_ERR("no drm plane resource");
-               ret = TDM_ERROR_OPERATION_FAILED;
-               goto failed;
-       }
-
-       ret = tdm_exynos_display_get_property(exynos_data,
-                                                                                 exynos_data->plane_res->planes[0],
-                                                                                 DRM_MODE_OBJECT_PLANE, "zpos", NULL,
-                                                                                 &exynos_data->is_immutable_zpos);
-       if (ret == TDM_ERROR_NONE) {
-               exynos_data->has_zpos_info = 1;
-               if (exynos_data->is_immutable_zpos)
-                       TDM_DBG("plane has immutable zpos info");
-       } else
-               TDM_DBG("plane doesn't have zpos info");
-
-       if (exynos_data->use_ippv2)
-               ret = tdm_exynos_pp_init(exynos_data);
-
-       if (ret != TDM_ERROR_NONE)
-               goto failed;
-
-       ret = tdm_exynos_display_create_output_list(exynos_data);
-       if (ret != TDM_ERROR_NONE)
-               goto failed;
-
-       ret = tdm_exynos_display_create_layer_list(exynos_data);
-       if (ret != TDM_ERROR_NONE)
-               goto failed;
-
-       if (error)
-               *error = TDM_ERROR_NONE;
-
-       TDM_INFO("init success!");
-
-       return (tdm_backend_data *)exynos_data;
-failed:
-       if (error)
-               *error = ret;
-
-       tdm_exynos_deinit(exynos_data);
-
-       TDM_ERR("init failed!");
-       return NULL;
-}
-
-tdm_backend_module tdm_backend_module_data = {
-       "exynos",
-       "Samsung",
-       TDM_BACKEND_SET_ABI_VERSION(2, 0),
-       tdm_exynos_init,
-       tdm_exynos_deinit
-};
-
diff --git a/src/tdm_exynos.h b/src/tdm_exynos.h
deleted file mode 100644 (file)
index 97ca58e..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-#ifndef _TDM_EXYNOS_H_
-#define _TDM_EXYNOS_H_
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <errno.h>
-#include <unistd.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-#include <exynos_drm.h>
-#include <tbm_surface.h>
-#include <tbm_surface_internal.h>
-#include <tbm_surface_queue.h>
-#include <tdm_backend.h>
-#include <tdm_log.h>
-#include <tdm_list.h>
-#include <tdm_helper.h>
-
-#include "tdm_exynos_types.h"
-#include "tdm_exynos_format.h"
-#include "tdm_exynos_display.h"
-#include "tdm_exynos_output.h"
-#include "tdm_exynos_layer.h"
-#include "tdm_exynos_hwc.h"
-#include "tdm_exynos_hwc_window.h"
-#include "tdm_exynos_pp_legacy.h"
-#include "tdm_exynos_capture_legacy.h"
-#include "tdm_exynos_pp.h"
-#include "tdm_exynos_capture.h"
-
-extern unsigned int exynos_screen_prerotation_hint;
-
-/* exynos backend functions */
-tdm_error    exynos_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps);
-tdm_error    exynos_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps);
-tdm_error    exynos_display_get_capture_capability(tdm_backend_data *bdata, tdm_caps_capture *caps);
-tdm_output** exynos_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error);
-tdm_error    exynos_display_get_fd(tdm_backend_data *bdata, int *fd);
-tdm_error    exynos_display_handle_events(tdm_backend_data *bdata);
-tdm_pp*      exynos_display_create_pp(tdm_backend_data *bdata, tdm_error *error);
-tdm_error    exynos_output_get_capability(tdm_output *output, tdm_caps_output *caps);
-tdm_layer**  exynos_output_get_layers(tdm_output *output, int *count, tdm_error *error);
-tdm_error    exynos_output_set_property(tdm_output *output, unsigned int id, tdm_value value);
-tdm_error    exynos_output_get_property(tdm_output *output, unsigned int id, tdm_value *value);
-tdm_error    exynos_output_wait_vblank(tdm_output *output, int interval, int sync, void *user_data);
-tdm_error    exynos_output_set_vblank_handler(tdm_output *output, tdm_output_vblank_handler func);
-tdm_error    exynos_output_commit(tdm_output *output, int sync, void *user_data);
-tdm_error    exynos_output_set_commit_handler(tdm_output *output, tdm_output_commit_handler func);
-tdm_error    exynos_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value);
-tdm_error    exynos_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value);
-tdm_error    exynos_output_set_mode(tdm_output *output, const tdm_output_mode *mode);
-tdm_error    exynos_output_get_mode(tdm_output *output, const tdm_output_mode **mode);
-tdm_capture* exynos_output_create_capture(tdm_output *output, tdm_error *error);
-tdm_error    exynos_output_set_status_handler(tdm_output *output, tdm_output_status_handler func, void *user_data);
-tdm_hwc     *exynos_output_get_hwc(tdm_output *output, tdm_error *error);
-tdm_error    exynos_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps);
-tdm_error    exynos_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value);
-tdm_error    exynos_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value);
-tdm_error    exynos_layer_set_info(tdm_layer *layer, tdm_info_layer *info);
-tdm_error    exynos_layer_get_info(tdm_layer *layer, tdm_info_layer *info);
-tdm_error    exynos_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer);
-tdm_error    exynos_layer_unset_buffer(tdm_layer *layer);
-
-tdm_hwc_window      *exynos_hwc_create_window(tdm_hwc *hwc, tdm_error *error);
-tdm_error            exynos_hwc_get_video_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count);
-tdm_error            exynos_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *capabilities);
-tdm_error            exynos_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count);
-tbm_surface_queue_h  exynos_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error);
-tdm_error            exynos_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage);
-tdm_error            exynos_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types);
-tdm_error            exynos_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements, tdm_hwc_window **hwc_wnds, tdm_hwc_window_composition *composition_types);
-tdm_error            exynos_hwc_accept_validation(tdm_hwc *hwc);
-tdm_error            exynos_hwc_commit(tdm_hwc *hwc, int sync, void *user_data);
-tdm_error            exynos_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func);
-
-void           exynos_hwc_window_destroy(tdm_hwc_window *hwc_window);
-tdm_error      exynos_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, tdm_hwc_window_composition composition_type);
-tdm_error      exynos_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage);
-tdm_error      exynos_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info);
-tdm_error      exynos_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface);
-tdm_error      exynos_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value);
-tdm_error      exynos_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value);
-tdm_error      exynos_hwc_window_get_constraints(tdm_hwc_window *hwc_window, int *constraints);
-
-void         exynos_pp_legacy_destroy(tdm_pp *pp);
-tdm_error    exynos_pp_legacy_set_info(tdm_pp *pp, tdm_info_pp *info);
-tdm_error    exynos_pp_legacy_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst);
-tdm_error    exynos_pp_legacy_commit(tdm_pp *pp);
-tdm_error    exynos_pp_legacy_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func, void *user_data);
-void         exynos_capture_legacy_destroy(tdm_capture *capture);
-tdm_error    exynos_capture_legacy_set_info(tdm_capture *capture, tdm_info_capture *info);
-tdm_error    exynos_capture_legacy_attach(tdm_capture *capture, tbm_surface_h buffer);
-tdm_error    exynos_capture_legacy_commit(tdm_capture *capture);
-tdm_error    exynos_capture_legacy_set_done_handler(tdm_pp *pp, tdm_capture_done_handler func, void *user_data);
-
-void         exynos_pp_destroy(tdm_pp *pp);
-tdm_error    exynos_pp_set_info(tdm_pp *pp, tdm_info_pp *info);
-tdm_error    exynos_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst);
-tdm_error    exynos_pp_commit(tdm_pp *pp);
-tdm_error    exynos_pp_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func, void *user_data);
-void         exynos_capture_destroy(tdm_capture *capture);
-tdm_error    exynos_capture_set_info(tdm_capture *capture, tdm_info_capture *info);
-tdm_error    exynos_capture_attach(tdm_capture *capture, tbm_surface_h buffer);
-tdm_error    exynos_capture_commit(tdm_capture *capture);
-tdm_error    exynos_capture_set_done_handler(tdm_pp *pp, tdm_capture_done_handler func, void *user_data);
-
-#endif /* _TDM_EXYNOS_H_ */
diff --git a/src/tdm_exynos_capture.c b/src/tdm_exynos_capture.c
deleted file mode 100644 (file)
index 74eb457..0000000
+++ /dev/null
@@ -1,454 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_exynos.h"
-
-typedef struct _tdm_exynos_capture_buffer {
-       int index;
-       tbm_surface_h ui_buffer;
-       tbm_surface_h buffer;
-       struct list_head link;
-} tdm_exynos_capture_buffer;
-
-typedef struct _tdm_exynos_pp_data {
-       tdm_exynos_data *exynos_data;
-
-       tdm_exynos_output_data *output_data;
-
-       tdm_info_capture info;
-       int info_changed;
-
-       struct list_head pending_buffer_list;
-       struct list_head buffer_list;
-
-       struct {
-               tdm_event_loop_source *timer_source;
-
-               int startd;
-               int first_event;
-       } stream;
-
-       tdm_capture_done_handler done_func;
-       void *done_user_data;
-
-       struct list_head link;
-} tdm_exynos_capture_data;
-
-static tbm_format capture_formats[] = {
-       TBM_FORMAT_ARGB8888,
-       TBM_FORMAT_XRGB8888,
-};
-
-#define NUM_CAPTURE_FORMAT   (sizeof(capture_formats) / sizeof(capture_formats[0]))
-
-static int capture_list_init;
-static struct list_head capture_list;
-
-static int
-_get_index(tdm_exynos_capture_data *capture_data)
-{
-       tdm_exynos_capture_buffer *b = NULL;
-       int ret = 0;
-
-       while (1) {
-               int found = 0;
-               LIST_FOR_EACH_ENTRY(b, &capture_data->pending_buffer_list, link) {
-                       if (ret == b->index) {
-                               found = 1;
-                               break;
-                       }
-               }
-               if (!found)
-                       LIST_FOR_EACH_ENTRY(b, &capture_data->buffer_list, link) {
-                       if (ret == b->index) {
-                               found = 1;
-                               break;
-                       }
-               }
-               if (!found)
-                       break;
-               ret++;
-       }
-
-       return ret;
-}
-
-static void
-_tdm_exynos_capture_oneshot_center_rect(int src_w, int src_h, int dst_w, int dst_h, tdm_pos *fit)
-{
-       float rw = (float)src_w / dst_w;
-       float rh = (float)src_h / dst_h;
-
-       fit->x = fit->y = 0;
-
-       if (rw > rh) {
-               fit->w = dst_w;
-               fit->h = src_h / rw;
-               fit->y = (dst_h - fit->h) / 2;
-       } else if (rw < rh) {
-               fit->w = src_w / rh;
-               fit->h = dst_h;
-               fit->x = (dst_w - fit->w) / 2;
-       } else {
-               fit->w = dst_w;
-               fit->h = dst_h;
-       }
-
-       fit->x = fit->x & ~0x1;
-}
-
-static void
-_tdm_exynos_capture_oneshot_rect_scale(int src_w, int src_h, int dst_w, int dst_h, tdm_pos *scale)
-{
-       float ratio;
-       tdm_pos center = {0,};
-
-       _tdm_exynos_capture_oneshot_center_rect(src_w, src_h, dst_w, dst_h, &center);
-
-       ratio = (float)center.w / src_w;
-       scale->x = scale->x * ratio + center.x;
-       scale->y = scale->y * ratio + center.y;
-       scale->w = scale->w * ratio;
-       scale->h = scale->h * ratio;
-}
-
-static void
-_tdm_exynos_capture_oneshot_get_showing_rect(tdm_pos *out_rect, tdm_pos *dst_rect, tdm_pos *showing_rect)
-{
-       showing_rect->x = dst_rect->x;
-       showing_rect->y = dst_rect->y;
-
-       if (dst_rect->x >= out_rect->w)
-               showing_rect->w = 0;
-       else if (dst_rect->x + dst_rect->w > out_rect->w)
-               showing_rect->w = out_rect->w - dst_rect->x;
-       else
-               showing_rect->w = dst_rect->w;
-
-       if (dst_rect->y >= out_rect->h)
-               showing_rect->h = 0;
-       else if (dst_rect->y + dst_rect->h > out_rect->h)
-               showing_rect->h = out_rect->h - dst_rect->y;
-       else
-               showing_rect->h = dst_rect->h;
-}
-
-static void
-_tdm_exynos_capture_oneshot_get_src_crop_info(tdm_exynos_capture_data *capture_data,
-                                                                                         tdm_exynos_layer_data *layer_data, tdm_pos *src_crop, tdm_pos *showing_rect)
-{
-       tdm_exynos_output_data *output_data = capture_data->output_data;
-       float ratio_x, ratio_y;
-       tdm_pos out_rect;
-       tdm_pos dst_rect;
-
-       out_rect.x = 0;
-       out_rect.y = 0;
-       out_rect.w = output_data->current_mode->hdisplay;
-       out_rect.h = output_data->current_mode->vdisplay;
-
-       dst_rect.x = layer_data->info.dst_pos.x;
-       dst_rect.y = layer_data->info.dst_pos.y;
-       dst_rect.w = layer_data->info.dst_pos.w;
-       dst_rect.h = layer_data->info.dst_pos.h;
-
-       _tdm_exynos_capture_oneshot_get_showing_rect(&out_rect, &dst_rect, showing_rect);
-
-       src_crop->x = layer_data->info.src_config.pos.x;
-       src_crop->y = layer_data->info.src_config.pos.y;
-
-       if (layer_data->info.transform % 2 == 0) {
-               ratio_x = (float)layer_data->info.src_config.pos.w / dst_rect.w;
-               ratio_y = (float)layer_data->info.src_config.pos.h / dst_rect.h;
-
-               src_crop->w = showing_rect->w * ratio_x;
-               src_crop->h = showing_rect->h * ratio_y;
-       } else {
-               ratio_x = (float)layer_data->info.src_config.pos.w / dst_rect.h;
-               ratio_y = (float)layer_data->info.src_config.pos.h / dst_rect.w;
-
-               src_crop->w = showing_rect->h * ratio_x;
-               src_crop->h = showing_rect->w * ratio_y;
-       }
-}
-
-static void
-_tdm_exynos_capture_oneshot_get_dst_crop_info(tdm_exynos_capture_data *capture_data, tdm_exynos_layer_data *layer_data,
-                                                                                         tdm_pos *dst_pos, tdm_pos *showing_pos, tdm_pos *dst_crop,
-                                                                                         tdm_transform transform)
-{
-       tdm_exynos_output_data *output_data = capture_data->output_data;
-
-       if (layer_data->info.src_config.pos.w == output_data->current_mode->hdisplay &&
-               layer_data->info.src_config.pos.h == output_data->current_mode->vdisplay &&
-               dst_pos->x == 0 && dst_pos->y == 0 &&
-               dst_pos->w == capture_data->info.dst_config.size.h &&
-               dst_pos->h == capture_data->info.dst_config.size.v) {
-               dst_crop->x = dst_pos->x;
-               dst_crop->y = dst_pos->y;
-               dst_crop->w = dst_pos->w;
-               dst_crop->h = dst_pos->h;
-       } else if ((output_data->current_mode->hdisplay == dst_pos->w) &&
-                          (output_data->current_mode->vdisplay == dst_pos->h) &&
-                          (showing_pos->w == dst_pos->w) && (showing_pos->h == dst_pos->h)) {
-               dst_crop->x = layer_data->info.dst_pos.x + dst_pos->x;
-               dst_crop->y = layer_data->info.dst_pos.y + dst_pos->y;
-               dst_crop->w = layer_data->info.dst_pos.w;
-               dst_crop->h = layer_data->info.dst_pos.h;
-       } else if (transform == TDM_TRANSFORM_NORMAL || transform == TDM_TRANSFORM_FLIPPED) {
-               dst_crop->x = showing_pos->x * dst_pos->w / output_data->current_mode->hdisplay + dst_pos->x;
-               dst_crop->y = showing_pos->y * dst_pos->h / output_data->current_mode->vdisplay + dst_pos->y;
-               dst_crop->w = showing_pos->w * dst_pos->w / output_data->current_mode->hdisplay;
-               dst_crop->h = showing_pos->h * dst_pos->h / output_data->current_mode->vdisplay;
-       } else if (transform == TDM_TRANSFORM_90 || transform == TDM_TRANSFORM_FLIPPED_90) {
-               dst_crop->x = (output_data->current_mode->vdisplay - showing_pos->y - showing_pos->h) *
-                                         dst_pos->w / output_data->current_mode->vdisplay + dst_pos->x;
-               dst_crop->y = showing_pos->x * dst_pos->h / output_data->current_mode->hdisplay + dst_pos->y;
-               dst_crop->w = showing_pos->h * dst_pos->w / output_data->current_mode->vdisplay;
-               dst_crop->h = showing_pos->w * dst_pos->h / output_data->current_mode->hdisplay;
-       } else if (transform == TDM_TRANSFORM_180 || transform == TDM_TRANSFORM_FLIPPED_180) {
-               dst_crop->x = (output_data->current_mode->hdisplay - showing_pos->x - showing_pos->w) *
-                                         dst_pos->w / output_data->current_mode->hdisplay + dst_pos->x;
-               dst_crop->y = (output_data->current_mode->vdisplay - showing_pos->y - showing_pos->h) *
-                                         dst_pos->h / output_data->current_mode->vdisplay + dst_pos->y;
-               dst_crop->w = showing_pos->w * dst_pos->w / output_data->current_mode->hdisplay;
-               dst_crop->h = showing_pos->h * dst_pos->h / output_data->current_mode->vdisplay;
-       } else if (transform == TDM_TRANSFORM_270 || transform == TDM_TRANSFORM_FLIPPED_270) {
-               dst_crop->x = showing_pos->y * dst_pos->w / output_data->current_mode->vdisplay + dst_pos->x;
-               dst_crop->y = (output_data->current_mode->hdisplay - showing_pos->x - showing_pos->w) *
-                                         dst_pos->h / output_data->current_mode->hdisplay + dst_pos->y;
-               dst_crop->w = showing_pos->h * dst_pos->w / output_data->current_mode->vdisplay;
-               dst_crop->h = showing_pos->w * dst_pos->h / output_data->current_mode->hdisplay;
-       } else {
-               dst_crop->x = dst_pos->x;
-               dst_crop->y = dst_pos->y;
-               dst_crop->w = dst_pos->w;
-               dst_crop->h = dst_pos->h;
-               TDM_ERR("oneshot: get_crop unknown case error");
-       }
-}
-
-static void
-_tdm_exynos_capture_oneshot_composite_layers_sw(tdm_exynos_capture_data *capture_data, tbm_surface_h buffer)
-{
-       tdm_exynos_output_data *output_data = capture_data->output_data;
-       tdm_exynos_layer_data *layer_data = NULL;
-       tbm_surface_info_s buf_info;
-       int err;
-
-       err = tbm_surface_get_info(buffer, &buf_info);
-       RETURN_IF_FAIL(err == TBM_SURFACE_ERROR_NONE);
-
-       LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
-               tbm_surface_h buf;
-               tdm_pos dst_pos;
-               tdm_pos showing_pos;
-               tdm_pos src_crop;
-               tdm_pos dst_crop;
-               tdm_transform transform = TDM_TRANSFORM_NORMAL;
-
-               if (!layer_data->display_buffer)
-                       continue;
-
-               buf = layer_data->display_buffer->buffer;
-
-               if (capture_data->info.dst_config.pos.w == 0 ||
-                       capture_data->info.dst_config.pos.h == 0) {
-                       dst_pos = layer_data->info.dst_pos;
-                       _tdm_exynos_capture_oneshot_rect_scale(output_data->current_mode->hdisplay,
-                                                                                                  output_data->current_mode->vdisplay,
-                                                                                                  buf_info.width, buf_info.height, &dst_pos);
-               } else {
-                       dst_pos = capture_data->info.dst_config.pos;
-                       transform = capture_data->info.transform;
-               }
-
-               _tdm_exynos_capture_oneshot_get_src_crop_info(capture_data, layer_data, &src_crop, &showing_pos);
-               _tdm_exynos_capture_oneshot_get_dst_crop_info(capture_data, layer_data, &dst_pos, &showing_pos, &dst_crop, transform);
-
-               TDM_DBG("oneshot convert buff: src_crop(%dx%d, %dx%d), dst_crop(%dx%d, %dx%d)\n",
-                               src_crop.x, src_crop.y, src_crop.w, src_crop.h,
-                               dst_crop.x, dst_crop.y, dst_crop.w, dst_crop.h);
-
-               tdm_helper_convert_buffer(buf, buffer,
-                                                                 &src_crop, &dst_crop, transform, 1);
-       }
-}
-
-static tdm_error
-_tdm_exynos_capture_commit_oneshot(tdm_exynos_capture_data *capture_data)
-{
-       tdm_exynos_capture_buffer *b = NULL, *bb = NULL;
-
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &capture_data->pending_buffer_list, link) {
-               LIST_DEL(&b->link);
-
-               /* TODO: need to improve the performance with hardware */
-               _tdm_exynos_capture_oneshot_composite_layers_sw(capture_data, b->buffer);
-
-               if (capture_data->done_func)
-                       capture_data->done_func(capture_data,
-                                                                       b->buffer,
-                                                                       capture_data->done_user_data);
-               free(b);
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-tdm_exynos_capture_get_capability(tdm_exynos_data *exynos_data, tdm_caps_capture *caps)
-{
-       int i;
-
-       if (!caps) {
-               TDM_ERR("invalid params");
-               return TDM_ERROR_INVALID_PARAMETER;
-       }
-
-       caps->capabilities = TDM_CAPTURE_CAPABILITY_OUTPUT|
-                                                TDM_CAPTURE_CAPABILITY_ONESHOT;
-
-       caps->format_count = NUM_CAPTURE_FORMAT;
-       caps->formats = NULL;
-       if (NUM_CAPTURE_FORMAT) {
-               /* will be freed in frontend */
-               caps->formats = calloc(1, sizeof capture_formats);
-               if (!caps->formats) {
-                       TDM_ERR("alloc failed");
-                       return TDM_ERROR_OUT_OF_MEMORY;
-               }
-               for (i = 0; i < caps->format_count; i++)
-                       caps->formats[i] = capture_formats[i];
-       }
-
-       caps->min_w = 16;
-       caps->min_h = 8;
-       caps->preferred_align = 2;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_capture*
-tdm_exynos_capture_create_output(tdm_exynos_data *exynos_data, tdm_output *output, tdm_error *error)
-{
-       tdm_exynos_capture_data *capture_data = calloc(1, sizeof(tdm_exynos_capture_data));
-       if (!capture_data) {
-               TDM_ERR("alloc failed");
-               if (error)
-                       *error = TDM_ERROR_OUT_OF_MEMORY;
-               return NULL;
-       }
-
-       capture_data->exynos_data = exynos_data;
-       capture_data->output_data = output;
-
-       LIST_INITHEAD(&capture_data->pending_buffer_list);
-       LIST_INITHEAD(&capture_data->buffer_list);
-
-       if (!capture_list_init) {
-               capture_list_init = 1;
-               LIST_INITHEAD(&capture_list);
-       }
-       LIST_ADDTAIL(&capture_data->link, &capture_list);
-
-       TDM_DBG("capture(%p) create", capture_data);
-
-       return capture_data;
-}
-
-void
-exynos_capture_destroy(tdm_capture *capture)
-{
-       tdm_exynos_capture_data *capture_data = capture;
-       tdm_exynos_capture_buffer *b = NULL, *bb = NULL;
-
-       if (!capture_data)
-               return;
-
-       TDM_DBG("capture(%p) destroy", capture_data);
-
-       if (capture_data->stream.timer_source)
-               tdm_event_loop_source_remove(capture_data->stream.timer_source);
-
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &capture_data->pending_buffer_list, link) {
-               LIST_DEL(&b->link);
-               free(b);
-       }
-
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &capture_data->buffer_list, link) {
-               LIST_DEL(&b->link);
-               tdm_buffer_unref_backend(b->ui_buffer);
-               free(b);
-       }
-
-       LIST_DEL(&capture_data->link);
-
-       free(capture_data);
-}
-
-tdm_error
-exynos_capture_set_info(tdm_capture *capture, tdm_info_capture *info)
-{
-       tdm_exynos_capture_data *capture_data = capture;
-
-       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
-
-       capture_data->info = *info;
-       capture_data->info_changed = 1;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_capture_attach(tdm_capture *capture, tbm_surface_h buffer)
-{
-       tdm_exynos_capture_data *capture_data = capture;
-       tdm_exynos_capture_buffer *b;
-
-       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(buffer, TDM_ERROR_INVALID_PARAMETER);
-
-       b = calloc(1, sizeof(tdm_exynos_capture_buffer));
-       if (!b) {
-               TDM_ERR("alloc failed");
-               return TDM_ERROR_NONE;
-       }
-
-       LIST_ADDTAIL(&b->link, &capture_data->pending_buffer_list);
-
-       b->index = _get_index(capture_data);
-       b->buffer = buffer;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_capture_commit(tdm_capture *capture)
-{
-       tdm_exynos_capture_data *capture_data = capture;
-       tdm_error ret = TDM_ERROR_INVALID_PARAMETER;
-
-       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
-
-       if (capture_data->info.type == TDM_CAPTURE_TYPE_ONESHOT)
-               ret = _tdm_exynos_capture_commit_oneshot(capture_data);
-
-       return ret;
-}
-
-tdm_error
-exynos_capture_set_done_handler(tdm_capture *capture, tdm_capture_done_handler func, void *user_data)
-{
-       tdm_exynos_capture_data *capture_data = capture;
-
-       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
-
-       capture_data->done_func = func;
-       capture_data->done_user_data = user_data;
-
-       return TDM_ERROR_NONE;
-}
diff --git a/src/tdm_exynos_capture.h b/src/tdm_exynos_capture.h
deleted file mode 100644 (file)
index 9e77206..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _TDM_EXYNOS_CAPTURE_H_
-#define _TDM_EXYNOS_CAPTURE_H_
-
-#include "tdm_exynos.h"
-
-tdm_error    tdm_exynos_capture_get_capability(tdm_exynos_data *exynos_data, tdm_caps_capture *caps);
-tdm_pp*      tdm_exynos_capture_create_output(tdm_exynos_data *exynos_data, tdm_output *output, tdm_error *error);
-
-#endif /* _TDM_EXYNOS_CAPTURE_H_ */
diff --git a/src/tdm_exynos_capture_legacy.c b/src/tdm_exynos_capture_legacy.c
deleted file mode 100644 (file)
index 0fc4651..0000000
+++ /dev/null
@@ -1,742 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_exynos.h"
-
-typedef struct _tdm_exynos_capture_legacy_buffer {
-       int index;
-       tbm_surface_h ui_buffer;
-       tbm_surface_h buffer;
-       struct list_head link;
-} tdm_exynos_capture_legacy_buffer;
-
-typedef struct _tdm_exynos_pp_legacy_data {
-       tdm_exynos_data *exynos_data;
-
-       tdm_exynos_output_data *output_data;
-
-       tdm_info_capture info;
-       int info_changed;
-
-       struct list_head pending_buffer_list;
-       struct list_head buffer_list;
-
-       struct {
-               tdm_event_loop_source *timer_source;
-
-               unsigned int prop_id;
-
-               int startd;
-               int first_event;
-       } stream;
-
-       tdm_capture_done_handler done_func;
-       void *done_user_data;
-
-       struct list_head link;
-} tdm_exynos_capture_legacy_data;
-
-static tbm_format capture_formats[] = {
-       TBM_FORMAT_ARGB8888,
-       TBM_FORMAT_XRGB8888,
-};
-
-#define NUM_CAPTURE_FORMAT   (sizeof(capture_formats) / sizeof(capture_formats[0]))
-
-static int capture_list_init;
-static struct list_head capture_list;
-
-int
-tdm_exynos_capture_legacy_find_prop_id(unsigned int prop_id)
-{
-       tdm_exynos_capture_legacy_data *capture_data = NULL;
-
-       if (!capture_list_init) {
-               capture_list_init = 1;
-               LIST_INITHEAD(&capture_list);
-       }
-
-       if (LIST_IS_EMPTY(&capture_list))
-               return 0;
-
-       LIST_FOR_EACH_ENTRY(capture_data, &capture_list, link) {
-               if (capture_data->stream.prop_id == prop_id)
-                       return 1;
-       }
-
-       return 0;
-}
-
-static int
-_get_index(tdm_exynos_capture_legacy_data *capture_data)
-{
-       tdm_exynos_capture_legacy_buffer *b = NULL;
-       int ret = 0;
-
-       while (1) {
-               int found = 0;
-               LIST_FOR_EACH_ENTRY(b, &capture_data->pending_buffer_list, link) {
-                       if (ret == b->index) {
-                               found = 1;
-                               break;
-                       }
-               }
-               if (!found)
-                       LIST_FOR_EACH_ENTRY(b, &capture_data->buffer_list, link) {
-                       if (ret == b->index) {
-                               found = 1;
-                               break;
-                       }
-               }
-               if (!found)
-                       break;
-               ret++;
-       }
-
-       return ret;
-}
-
-static tdm_error
-_tdm_exynos_capture_legacy_stream_pp_set(tdm_exynos_capture_legacy_data *capture_data, tbm_surface_h ui_buffer)
-{
-       tdm_exynos_data *exynos_data = capture_data->exynos_data;
-       tdm_info_capture *info = &capture_data->info;
-       struct drm_exynos_ipp_property property;
-       unsigned int width, height, stride = 0;
-       int ret = 0;
-
-       tbm_surface_internal_get_plane_data(ui_buffer, 0, NULL, NULL, &stride);
-       width = tbm_surface_get_width(ui_buffer);
-       height = tbm_surface_get_height(ui_buffer);
-
-       CLEAR(property);
-
-       property.config[0].ops_id = EXYNOS_DRM_OPS_SRC;
-       property.config[0].fmt = tdm_exynos_format_to_drm_format(tbm_surface_get_format(ui_buffer));
-       property.config[0].sz.hsize = stride >> 2;
-       property.config[0].sz.vsize = height;
-       property.config[0].pos.w = width;
-       property.config[0].pos.h = height;
-
-       property.config[1].ops_id = EXYNOS_DRM_OPS_DST;
-       property.config[1].degree = info->transform % 4;
-       property.config[1].flip = (info->transform > 3) ? EXYNOS_DRM_FLIP_HORIZONTAL : 0;
-       property.config[1].fmt = tdm_exynos_format_to_drm_format(info->dst_config.format);
-       memcpy(&property.config[1].sz, &info->dst_config.size, sizeof(tdm_size));
-       memcpy(&property.config[1].pos, &info->dst_config.pos, sizeof(tdm_pos));
-       property.cmd = IPP_CMD_M2M;
-       property.prop_id = capture_data->stream.prop_id;
-
-       TDM_DBG("src : flip(%x) deg(%d) fmt(%c%c%c%c) sz(%dx%d) pos(%d,%d %dx%d)  ",
-                       property.config[0].flip, property.config[0].degree,
-                       FOURCC_STR(property.config[0].fmt),
-                       property.config[0].sz.hsize, property.config[0].sz.vsize,
-                       property.config[0].pos.x, property.config[0].pos.y, property.config[0].pos.w,
-                       property.config[0].pos.h);
-       TDM_DBG("dst : flip(%x) deg(%d) fmt(%c%c%c%c) sz(%dx%d) pos(%d,%d %dx%d)  ",
-                       property.config[1].flip, property.config[1].degree,
-                       FOURCC_STR(property.config[1].fmt),
-                       property.config[1].sz.hsize, property.config[1].sz.vsize,
-                       property.config[1].pos.x, property.config[1].pos.y, property.config[1].pos.w,
-                       property.config[1].pos.h);
-
-       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_SET_PROPERTY, &property);
-       if (ret) {
-               TDM_ERR("failed: %m");
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       TDM_DBG("success. prop_id(%d) ", property.prop_id);
-       capture_data->stream.prop_id = property.prop_id;
-       return TDM_ERROR_NONE;
-}
-
-static tdm_error
-_tdm_exynos_capture_legacy_stream_pp_queue(tdm_exynos_capture_legacy_data *capture_data,
-                                                                       tdm_exynos_capture_legacy_buffer *b,
-                                                                       enum drm_exynos_ipp_buf_type type)
-{
-       tdm_exynos_data *exynos_data = capture_data->exynos_data;
-       struct drm_exynos_ipp_queue_buf buf;
-       int i, bo_num, ret = 0;
-
-       CLEAR(buf);
-       buf.prop_id = capture_data->stream.prop_id;
-       buf.ops_id = EXYNOS_DRM_OPS_SRC;
-       buf.buf_type = type;
-       buf.buf_id = b->index;
-       buf.user_data = (__u64)(uintptr_t)capture_data;
-       bo_num = tbm_surface_internal_get_num_bos(b->ui_buffer);
-       for (i = 0; i < EXYNOS_DRM_PLANAR_MAX && i < bo_num; i++) {
-               tbm_bo bo = tbm_surface_internal_get_bo(b->ui_buffer, i);
-               buf.handle[i] = (__u32)tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
-       }
-
-       TDM_DBG("prop_id(%d) ops_id(%d) ctrl(%d) id(%d) handles(%x %x %x). ",
-                       buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id,
-                       buf.handle[0], buf.handle[1], buf.handle[2]);
-
-       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
-       if (ret) {
-               TDM_ERR("src failed. prop_id(%d) op(%d) buf(%d) id(%d). %m",
-                               buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id);
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       CLEAR(buf);
-       buf.prop_id = capture_data->stream.prop_id;
-       buf.ops_id = EXYNOS_DRM_OPS_DST;
-       buf.buf_type = type;
-       buf.buf_id = b->index;
-       buf.user_data = (__u64)(uintptr_t)capture_data;
-       bo_num = tbm_surface_internal_get_num_bos(b->buffer);
-       for (i = 0; i < EXYNOS_DRM_PLANAR_MAX && i < bo_num; i++) {
-               tbm_bo bo = tbm_surface_internal_get_bo(b->buffer, i);
-               buf.handle[i] = (__u32)tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
-       }
-
-       TDM_DBG("prop_id(%d) ops_id(%d) ctrl(%d) id(%d) handles(%x %x %x). ",
-                       buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id,
-                       buf.handle[0], buf.handle[1], buf.handle[2]);
-
-       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
-       if (ret) {
-               TDM_ERR("dst failed. prop_id(%d) op(%d) buf(%d) id(%d). %m",
-                               buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id);
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       TDM_DBG("success. prop_id(%d)", buf.prop_id);
-
-       return TDM_ERROR_NONE;
-}
-
-static tdm_error
-_tdm_exynos_capture_legacy_stream_pp_cmd(tdm_exynos_capture_legacy_data *capture_data, enum drm_exynos_ipp_ctrl cmd)
-{
-       tdm_exynos_data *exynos_data = capture_data->exynos_data;
-       struct drm_exynos_ipp_cmd_ctrl ctrl;
-       int ret = 0;
-
-       ctrl.prop_id = capture_data->stream.prop_id;
-       ctrl.ctrl = cmd;
-
-       TDM_DBG("prop_id(%d) ctrl(%d). ", ctrl.prop_id, ctrl.ctrl);
-
-       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_CMD_CTRL, &ctrl);
-       if (ret) {
-               TDM_ERR("failed. prop_id(%d) ctrl(%d). %m", ctrl.prop_id, ctrl.ctrl);
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       TDM_DBG("success. prop_id(%d) ", ctrl.prop_id);
-
-       return TDM_ERROR_NONE;
-}
-
-void
-tdm_exynos_capture_legacy_stream_pp_handler(unsigned int prop_id, unsigned int *buf_idx,
-                                                                        unsigned int tv_sec, unsigned int tv_usec, void *data)
-{
-       tdm_exynos_capture_legacy_data *found = NULL, *d = NULL, *capture_data = data;
-       tdm_exynos_capture_legacy_buffer *b = NULL, *bb = NULL, *dequeued_buffer = NULL;
-
-       if (!capture_data || !buf_idx) {
-               TDM_ERR("invalid params");
-               return;
-       }
-
-       LIST_FOR_EACH_ENTRY(d, &capture_list, link) {
-               if (d == capture_data) {
-                       found = d;
-                       break;
-               }
-       }
-       if (!found)
-               return;
-
-       TDM_DBG("capture_data(%p) index(%d, %d)", capture_data, buf_idx[0], buf_idx[1]);
-
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &capture_data->buffer_list, link) {
-               if (buf_idx[0] == b->index) {
-                       dequeued_buffer = b;
-                       LIST_DEL(&dequeued_buffer->link);
-                       TDM_DBG("dequeued: %d", dequeued_buffer->index);
-                       break;
-               }
-       }
-
-       if (!dequeued_buffer) {
-               TDM_ERR("not found buffer index: %d", buf_idx[0]);
-               return;
-       }
-
-       if (!capture_data->stream.first_event) {
-               TDM_DBG("capture(%p) got a first event. ", capture_data);
-               capture_data->stream.first_event = 1;
-       }
-
-       if (capture_data->done_func)
-               capture_data->done_func(capture_data,
-                                                               dequeued_buffer->buffer,
-                                                               capture_data->done_user_data);
-
-       tdm_buffer_unref_backend(dequeued_buffer->ui_buffer);
-
-       free(dequeued_buffer);
-}
-
-static tdm_error
-_tdm_exynos_capture_legacy_stream_timer_handler(void *user_data)
-{
-       tdm_exynos_capture_legacy_data *capture_data = user_data;
-       unsigned int ms = 1000 / capture_data->info.frequency;
-       tdm_exynos_capture_legacy_buffer *b = NULL;
-       tbm_surface_h ui_buffer = NULL;
-       tdm_error ret;
-
-       tdm_event_loop_source_timer_update(capture_data->stream.timer_source, ms);
-
-       if (capture_data->output_data->primary_layer->display_buffer)
-               ui_buffer = capture_data->output_data->primary_layer->display_buffer->buffer;
-
-       if (!ui_buffer)
-               return TDM_ERROR_NONE;
-
-       if (capture_data->info_changed) {
-               if (capture_data->stream.startd)
-                       _tdm_exynos_capture_legacy_stream_pp_cmd(capture_data, IPP_CTRL_PAUSE);
-
-               ret = _tdm_exynos_capture_legacy_stream_pp_set(capture_data, ui_buffer);
-               if (ret < 0)
-                       return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       b = LIST_FIRST_ENTRY(&capture_data->pending_buffer_list, tdm_exynos_capture_legacy_buffer, link);
-       RETURN_VAL_IF_FAIL(b != NULL, TDM_ERROR_OPERATION_FAILED);
-
-       LIST_DEL(&b->link);
-       b->ui_buffer = tdm_buffer_ref_backend(ui_buffer);
-       _tdm_exynos_capture_legacy_stream_pp_queue(capture_data, b, IPP_BUF_ENQUEUE);
-       TDM_DBG("queued: %d", b->index);
-       LIST_ADDTAIL(&b->link, &capture_data->buffer_list);
-
-       if (capture_data->info_changed) {
-               capture_data->info_changed = 0;
-
-               if (!capture_data->stream.startd) {
-                       capture_data->stream.startd = 1;
-                       _tdm_exynos_capture_legacy_stream_pp_cmd(capture_data, IPP_CTRL_PLAY);
-               } else
-                       _tdm_exynos_capture_legacy_stream_pp_cmd(capture_data, IPP_CTRL_RESUME);
-       }
-
-
-       return TDM_ERROR_NONE;
-}
-
-
-static tdm_error
-_tdm_exynos_capture_legacy_commit_stream(tdm_exynos_capture_legacy_data *capture_data)
-{
-       unsigned int ms = 1000 / capture_data->info.frequency;
-
-       if (!capture_data->stream.timer_source) {
-               capture_data->stream.timer_source =
-                       tdm_event_loop_add_timer_handler(capture_data->exynos_data->dpy,
-                                                                                        _tdm_exynos_capture_legacy_stream_timer_handler,
-                                                                                        capture_data, NULL);
-                       RETURN_VAL_IF_FAIL(capture_data->stream.timer_source != NULL, TDM_ERROR_OUT_OF_MEMORY);
-       }
-
-       tdm_event_loop_source_timer_update(capture_data->stream.timer_source, ms);
-
-       return TDM_ERROR_NONE;
-}
-
-static void
-_tdm_exynos_capture_legacy_oneshot_center_rect(int src_w, int src_h, int dst_w, int dst_h, tdm_pos *fit)
-{
-       float rw = (float)src_w / dst_w;
-       float rh = (float)src_h / dst_h;
-
-       fit->x = fit->y = 0;
-
-       if (rw > rh) {
-               fit->w = dst_w;
-               fit->h = src_h / rw;
-               fit->y = (dst_h - fit->h) / 2;
-       } else if (rw < rh) {
-               fit->w = src_w / rh;
-               fit->h = dst_h;
-               fit->x = (dst_w - fit->w) / 2;
-       } else {
-               fit->w = dst_w;
-               fit->h = dst_h;
-       }
-
-       fit->x = fit->x & ~0x1;
-}
-
-static void
-_tdm_exynos_capture_legacy_oneshot_rect_scale(int src_w, int src_h, int dst_w, int dst_h, tdm_pos *scale)
-{
-       float ratio;
-       tdm_pos center = {0,};
-
-       _tdm_exynos_capture_legacy_oneshot_center_rect(src_w, src_h, dst_w, dst_h, &center);
-
-       ratio = (float)center.w / src_w;
-       scale->x = scale->x * ratio + center.x;
-       scale->y = scale->y * ratio + center.y;
-       scale->w = scale->w * ratio;
-       scale->h = scale->h * ratio;
-}
-
-static void
-_tdm_exynos_capture_legacy_oneshot_get_showing_rect(tdm_pos *out_rect, tdm_pos *dst_rect, tdm_pos *showing_rect)
-{
-       showing_rect->x = dst_rect->x;
-       showing_rect->y = dst_rect->y;
-
-       if (dst_rect->x >= out_rect->w)
-               showing_rect->w = 0;
-       else if (dst_rect->x + dst_rect->w > out_rect->w)
-               showing_rect->w = out_rect->w - dst_rect->x;
-       else
-               showing_rect->w = dst_rect->w;
-
-       if (dst_rect->y >= out_rect->h)
-               showing_rect->h = 0;
-       else if (dst_rect->y + dst_rect->h > out_rect->h)
-               showing_rect->h = out_rect->h - dst_rect->y;
-       else
-               showing_rect->h = dst_rect->h;
-}
-
-static void
-_tdm_exynos_capture_legacy_oneshot_get_src_crop_info(tdm_exynos_capture_legacy_data *capture_data,
-                                                                                         tdm_exynos_layer_data *layer_data, tdm_pos *src_crop, tdm_pos *showing_rect)
-{
-       tdm_exynos_output_data *output_data = capture_data->output_data;
-       float ratio_x, ratio_y;
-       tdm_pos out_rect;
-       tdm_pos dst_rect;
-
-       out_rect.x = 0;
-       out_rect.y = 0;
-       out_rect.w = output_data->current_mode->hdisplay;
-       out_rect.h = output_data->current_mode->vdisplay;
-
-       dst_rect.x = layer_data->info.dst_pos.x;
-       dst_rect.y = layer_data->info.dst_pos.y;
-       dst_rect.w = layer_data->info.dst_pos.w;
-       dst_rect.h = layer_data->info.dst_pos.h;
-
-       _tdm_exynos_capture_legacy_oneshot_get_showing_rect(&out_rect, &dst_rect, showing_rect);
-
-       src_crop->x = layer_data->info.src_config.pos.x;
-       src_crop->y = layer_data->info.src_config.pos.y;
-
-       if (layer_data->info.transform % 2 == 0) {
-               ratio_x = (float)layer_data->info.src_config.pos.w / dst_rect.w;
-               ratio_y = (float)layer_data->info.src_config.pos.h / dst_rect.h;
-
-               src_crop->w = showing_rect->w * ratio_x;
-               src_crop->h = showing_rect->h * ratio_y;
-       } else {
-               ratio_x = (float)layer_data->info.src_config.pos.w / dst_rect.h;
-               ratio_y = (float)layer_data->info.src_config.pos.h / dst_rect.w;
-
-               src_crop->w = showing_rect->h * ratio_x;
-               src_crop->h = showing_rect->w * ratio_y;
-       }
-}
-
-static void
-_tdm_exynos_capture_legacy_oneshot_get_dst_crop_info(tdm_exynos_capture_legacy_data *capture_data, tdm_exynos_layer_data *layer_data,
-                                                                                         tdm_pos *dst_pos, tdm_pos *showing_pos, tdm_pos *dst_crop,
-                                                                                         tdm_transform transform)
-{
-       tdm_exynos_output_data *output_data = capture_data->output_data;
-
-       if (layer_data->info.src_config.pos.w == output_data->current_mode->hdisplay &&
-               layer_data->info.src_config.pos.h == output_data->current_mode->vdisplay &&
-               dst_pos->x == 0 && dst_pos->y == 0 &&
-               dst_pos->w == capture_data->info.dst_config.size.h &&
-               dst_pos->h == capture_data->info.dst_config.size.v) {
-               dst_crop->x = dst_pos->x;
-               dst_crop->y = dst_pos->y;
-               dst_crop->w = dst_pos->w;
-               dst_crop->h = dst_pos->h;
-       } else if ((output_data->current_mode->hdisplay == dst_pos->w) &&
-                          (output_data->current_mode->vdisplay == dst_pos->h) &&
-                          (showing_pos->w == dst_pos->w) && (showing_pos->h == dst_pos->h)) {
-               dst_crop->x = layer_data->info.dst_pos.x + dst_pos->x;
-               dst_crop->y = layer_data->info.dst_pos.y + dst_pos->y;
-               dst_crop->w = layer_data->info.dst_pos.w;
-               dst_crop->h = layer_data->info.dst_pos.h;
-       } else if (transform == TDM_TRANSFORM_NORMAL || transform == TDM_TRANSFORM_FLIPPED) {
-               dst_crop->x = showing_pos->x * dst_pos->w / output_data->current_mode->hdisplay + dst_pos->x;
-               dst_crop->y = showing_pos->y * dst_pos->h / output_data->current_mode->vdisplay + dst_pos->y;
-               dst_crop->w = showing_pos->w * dst_pos->w / output_data->current_mode->hdisplay;
-               dst_crop->h = showing_pos->h * dst_pos->h / output_data->current_mode->vdisplay;
-       } else if (transform == TDM_TRANSFORM_90 || transform == TDM_TRANSFORM_FLIPPED_90) {
-               dst_crop->x = (output_data->current_mode->vdisplay - showing_pos->y - showing_pos->h) *
-                                         dst_pos->w / output_data->current_mode->vdisplay + dst_pos->x;
-               dst_crop->y = showing_pos->x * dst_pos->h / output_data->current_mode->hdisplay + dst_pos->y;
-               dst_crop->w = showing_pos->h * dst_pos->w / output_data->current_mode->vdisplay;
-               dst_crop->h = showing_pos->w * dst_pos->h / output_data->current_mode->hdisplay;
-       } else if (transform == TDM_TRANSFORM_180 || transform == TDM_TRANSFORM_FLIPPED_180) {
-               dst_crop->x = (output_data->current_mode->hdisplay - showing_pos->x - showing_pos->w) *
-                                         dst_pos->w / output_data->current_mode->hdisplay + dst_pos->x;
-               dst_crop->y = (output_data->current_mode->vdisplay - showing_pos->y - showing_pos->h) *
-                                         dst_pos->h / output_data->current_mode->vdisplay + dst_pos->y;
-               dst_crop->w = showing_pos->w * dst_pos->w / output_data->current_mode->hdisplay;
-               dst_crop->h = showing_pos->h * dst_pos->h / output_data->current_mode->vdisplay;
-       } else if (transform == TDM_TRANSFORM_270 || transform == TDM_TRANSFORM_FLIPPED_270) {
-               dst_crop->x = showing_pos->y * dst_pos->w / output_data->current_mode->vdisplay + dst_pos->x;
-               dst_crop->y = (output_data->current_mode->hdisplay - showing_pos->x - showing_pos->w) *
-                                         dst_pos->h / output_data->current_mode->hdisplay + dst_pos->y;
-               dst_crop->w = showing_pos->h * dst_pos->w / output_data->current_mode->vdisplay;
-               dst_crop->h = showing_pos->w * dst_pos->h / output_data->current_mode->hdisplay;
-       } else {
-               dst_crop->x = dst_pos->x;
-               dst_crop->y = dst_pos->y;
-               dst_crop->w = dst_pos->w;
-               dst_crop->h = dst_pos->h;
-               TDM_ERR("oneshot: get_crop unknown case error");
-       }
-}
-
-static void
-_tdm_exynos_capture_legacy_oneshot_composite_layers_sw(tdm_exynos_capture_legacy_data *capture_data, tbm_surface_h buffer)
-{
-       tdm_exynos_output_data *output_data = capture_data->output_data;
-       tdm_exynos_layer_data *layer_data = NULL;
-       tbm_surface_info_s buf_info;
-       int err;
-
-       err = tbm_surface_get_info(buffer, &buf_info);
-       RETURN_IF_FAIL(err == TBM_SURFACE_ERROR_NONE);
-
-       LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
-               tbm_surface_h buf;
-               tdm_pos dst_pos;
-               tdm_pos showing_pos;
-               tdm_pos src_crop;
-               tdm_pos dst_crop;
-               tdm_transform transform = TDM_TRANSFORM_NORMAL;
-
-               if (!layer_data->display_buffer)
-                       continue;
-
-               buf = layer_data->display_buffer->buffer;
-
-               if (capture_data->info.dst_config.pos.w == 0 ||
-                       capture_data->info.dst_config.pos.h == 0) {
-                       dst_pos = layer_data->info.dst_pos;
-                       _tdm_exynos_capture_legacy_oneshot_rect_scale(output_data->current_mode->hdisplay,
-                                                                                                  output_data->current_mode->vdisplay,
-                                                                                                  buf_info.width, buf_info.height, &dst_pos);
-               } else {
-                       dst_pos = capture_data->info.dst_config.pos;
-                       transform = capture_data->info.transform;
-               }
-
-               _tdm_exynos_capture_legacy_oneshot_get_src_crop_info(capture_data, layer_data, &src_crop, &showing_pos);
-               _tdm_exynos_capture_legacy_oneshot_get_dst_crop_info(capture_data, layer_data, &dst_pos, &showing_pos, &dst_crop, transform);
-
-               TDM_DBG("oneshot convert buff: src_crop(%dx%d, %dx%d), dst_crop(%dx%d, %dx%d)\n",
-                               src_crop.x, src_crop.y, src_crop.w, src_crop.h,
-                               dst_crop.x, dst_crop.y, dst_crop.w, dst_crop.h);
-
-               tdm_helper_convert_buffer(buf, buffer,
-                                                                 &src_crop, &dst_crop, transform, 1);
-       }
-}
-
-static tdm_error
-_tdm_exynos_capture_legacy_commit_oneshot(tdm_exynos_capture_legacy_data *capture_data)
-{
-       tdm_exynos_capture_legacy_buffer *b = NULL, *bb = NULL;
-
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &capture_data->pending_buffer_list, link) {
-               LIST_DEL(&b->link);
-
-               /* TODO: need to improve the performance with hardware */
-               _tdm_exynos_capture_legacy_oneshot_composite_layers_sw(capture_data, b->buffer);
-
-               if (capture_data->done_func)
-                       capture_data->done_func(capture_data,
-                                                                       b->buffer,
-                                                                       capture_data->done_user_data);
-               free(b);
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-tdm_exynos_capture_legacy_get_capability(tdm_exynos_data *exynos_data, tdm_caps_capture *caps)
-{
-       int i;
-
-       if (!caps) {
-               TDM_ERR("invalid params");
-               return TDM_ERROR_INVALID_PARAMETER;
-       }
-
-       caps->capabilities = TDM_CAPTURE_CAPABILITY_OUTPUT|
-                                                TDM_CAPTURE_CAPABILITY_ONESHOT|
-                                                TDM_CAPTURE_CAPABILITY_STREAM;
-
-       caps->format_count = NUM_CAPTURE_FORMAT;
-       caps->formats = NULL;
-       if (NUM_CAPTURE_FORMAT) {
-               /* will be freed in frontend */
-               caps->formats = calloc(1, sizeof capture_formats);
-               if (!caps->formats) {
-                       TDM_ERR("alloc failed");
-                       return TDM_ERROR_OUT_OF_MEMORY;
-               }
-               for (i = 0; i < caps->format_count; i++)
-                       caps->formats[i] = capture_formats[i];
-       }
-
-       caps->min_w = 16;
-       caps->min_h = 8;
-       caps->preferred_align = 2;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_capture*
-tdm_exynos_capture_legacy_create_output(tdm_exynos_data *exynos_data, tdm_output *output, tdm_error *error)
-{
-       tdm_exynos_capture_legacy_data *capture_data = calloc(1, sizeof(tdm_exynos_capture_legacy_data));
-       if (!capture_data) {
-               TDM_ERR("alloc failed");
-               if (error)
-                       *error = TDM_ERROR_OUT_OF_MEMORY;
-               return NULL;
-       }
-
-       capture_data->exynos_data = exynos_data;
-       capture_data->output_data = output;
-
-       LIST_INITHEAD(&capture_data->pending_buffer_list);
-       LIST_INITHEAD(&capture_data->buffer_list);
-
-       if (!capture_list_init) {
-               capture_list_init = 1;
-               LIST_INITHEAD(&capture_list);
-       }
-       LIST_ADDTAIL(&capture_data->link, &capture_list);
-
-       TDM_DBG("capture(%p) create", capture_data);
-
-       return capture_data;
-}
-
-void
-exynos_capture_legacy_destroy(tdm_capture *capture)
-{
-       tdm_exynos_capture_legacy_data *capture_data = capture;
-       tdm_exynos_capture_legacy_buffer *b = NULL, *bb = NULL;
-
-       if (!capture_data)
-               return;
-
-       TDM_DBG("capture(%p) destroy", capture_data);
-
-       if (capture_data->stream.timer_source)
-               tdm_event_loop_source_remove(capture_data->stream.timer_source);
-
-       if (capture_data->stream.prop_id)
-               _tdm_exynos_capture_legacy_stream_pp_cmd(capture_data, IPP_CTRL_STOP);
-
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &capture_data->pending_buffer_list, link) {
-               LIST_DEL(&b->link);
-               free(b);
-       }
-
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &capture_data->buffer_list, link) {
-               LIST_DEL(&b->link);
-               tdm_buffer_unref_backend(b->ui_buffer);
-               _tdm_exynos_capture_legacy_stream_pp_queue(capture_data, b, IPP_BUF_DEQUEUE);
-               free(b);
-       }
-
-       LIST_DEL(&capture_data->link);
-
-       free(capture_data);
-}
-
-tdm_error
-exynos_capture_legacy_set_info(tdm_capture *capture, tdm_info_capture *info)
-{
-       tdm_exynos_capture_legacy_data *capture_data = capture;
-
-       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
-
-       capture_data->info = *info;
-       capture_data->info_changed = 1;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_capture_legacy_attach(tdm_capture *capture, tbm_surface_h buffer)
-{
-       tdm_exynos_capture_legacy_data *capture_data = capture;
-       tdm_exynos_capture_legacy_buffer *b;
-
-       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(buffer, TDM_ERROR_INVALID_PARAMETER);
-
-       b = calloc(1, sizeof(tdm_exynos_capture_legacy_buffer));
-       if (!b) {
-               TDM_ERR("alloc failed");
-               return TDM_ERROR_NONE;
-       }
-
-       LIST_ADDTAIL(&b->link, &capture_data->pending_buffer_list);
-
-       b->index = _get_index(capture_data);
-       b->buffer = buffer;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_capture_legacy_commit(tdm_capture *capture)
-{
-       tdm_exynos_capture_legacy_data *capture_data = capture;
-       tdm_error ret;
-
-       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
-
-       if (capture_data->info.type == TDM_CAPTURE_TYPE_ONESHOT)
-               ret = _tdm_exynos_capture_legacy_commit_oneshot(capture_data);
-       else
-               ret = _tdm_exynos_capture_legacy_commit_stream(capture_data);
-
-       return ret;
-}
-
-tdm_error
-exynos_capture_legacy_set_done_handler(tdm_capture *capture, tdm_capture_done_handler func, void *user_data)
-{
-       tdm_exynos_capture_legacy_data *capture_data = capture;
-
-       RETURN_VAL_IF_FAIL(capture_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
-
-       capture_data->done_func = func;
-       capture_data->done_user_data = user_data;
-
-       return TDM_ERROR_NONE;
-}
diff --git a/src/tdm_exynos_capture_legacy.h b/src/tdm_exynos_capture_legacy.h
deleted file mode 100644 (file)
index dfcc01c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _TDM_EXYNOS_CAPTURE_LEGACY_H_
-#define _TDM_EXYNOS_CAPTURE_LEGACY_H_
-
-#include "tdm_exynos.h"
-
-tdm_error    tdm_exynos_capture_legacy_get_capability(tdm_exynos_data *exynos_data, tdm_caps_capture *caps);
-tdm_pp*      tdm_exynos_capture_legacy_create_output(tdm_exynos_data *exynos_data, tdm_output *output, tdm_error *error);
-void         tdm_exynos_capture_legacy_stream_pp_handler(unsigned int prop_id, unsigned int *buf_idx,
-                                                                                                 unsigned int tv_sec, unsigned int tv_usec, void *data);
-int          tdm_exynos_capture_legacy_find_prop_id(unsigned int prop_id);
-
-#endif /* _TDM_EXYNOS_CAPTURE_LEGACY_H_ */
diff --git a/src/tdm_exynos_display.c b/src/tdm_exynos_display.c
deleted file mode 100644 (file)
index a5993fb..0000000
+++ /dev/null
@@ -1,740 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <drm_fourcc.h>
-#include <tdm_helper.h>
-#include "tdm_exynos.h"
-
-#define LAYER_COUNT_FOR_NOT_FIXED           2
-#define LAYER_PRIMARY_INDEX_FOR_NOT_FIXED   1
-
-static tdm_error
-_tdm_exynos_display_create_layer_list_type(tdm_exynos_data *exynos_data)
-{
-       tdm_error ret;
-       int i;
-
-       for (i = 0; i < exynos_data->plane_res->count_planes; i++) {
-               tdm_exynos_output_data *output_data = NULL;
-               tdm_exynos_layer_data *layer_data;
-               drmModePlanePtr plane;
-               unsigned int type = 0;
-               int output_find = 0;
-
-               plane = drmModeGetPlane(exynos_data->drm_fd, exynos_data->plane_res->planes[i]);
-               if (!plane) {
-                       TDM_ERR("no plane");
-                       continue;
-               }
-
-               ret = tdm_exynos_display_get_property(exynos_data,
-                                                                                         exynos_data->plane_res->planes[i],
-                                                                                         DRM_MODE_OBJECT_PLANE, "type", &type, NULL);
-               if (ret != TDM_ERROR_NONE) {
-                       TDM_ERR("plane(%d) doesn't have 'type' info",
-                                       exynos_data->plane_res->planes[i]);
-                       drmModeFreePlane(plane);
-                       continue;
-               }
-
-               layer_data = calloc(1, sizeof(tdm_exynos_layer_data));
-               if (!layer_data) {
-                       TDM_ERR("alloc failed");
-                       drmModeFreePlane(plane);
-                       continue;
-               }
-
-               LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link) {
-                       if (plane->possible_crtcs & (1 << output_data->pipe)) {
-                               output_find = 1;
-                               break;
-                       }
-               }
-
-               if (!output_find) {
-                       TDM_ERR("plane(%d) couldn't found proper output", plane->plane_id);
-                       drmModeFreePlane(plane);
-                       free(layer_data);
-                       continue;
-               }
-
-               layer_data->exynos_data = exynos_data;
-               layer_data->output_data = output_data;
-               layer_data->plane_id = exynos_data->plane_res->planes[i];
-
-               if (type == DRM_PLANE_TYPE_CURSOR) {
-                       layer_data->capabilities = TDM_LAYER_CAPABILITY_CURSOR |
-                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
-                       layer_data->zpos = 2;
-               } else if (type == DRM_PLANE_TYPE_OVERLAY) {
-                       layer_data->capabilities = TDM_LAYER_CAPABILITY_OVERLAY |
-                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
-                       layer_data->zpos = 1;
-               } else if (type == DRM_PLANE_TYPE_PRIMARY) {
-                       layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY |
-                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
-                       layer_data->zpos = 0;
-                       output_data->primary_layer = layer_data;
-               } else {
-                       drmModeFreePlane(plane);
-                       free(layer_data);
-                       continue;
-               }
-
-               TDM_DBG("layer_data(%p) plane_id(%d) crtc_id(%d) zpos(%d) capabilities(%x)",
-                               layer_data, layer_data->plane_id, layer_data->output_data->crtc_id,
-                               layer_data->zpos, layer_data->capabilities);
-
-               LIST_ADDTAIL(&layer_data->link, &output_data->layer_list);
-
-               drmModeFreePlane(plane);
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-static tdm_error
-_tdm_exynos_display_create_layer_list_immutable_zpos(tdm_exynos_data *exynos_data)
-{
-       tdm_error ret;
-       int i;
-
-       for (i = 0; i < exynos_data->plane_res->count_planes; i++) {
-               tdm_exynos_output_data *output_data = NULL;
-               tdm_exynos_layer_data *layer_data;
-               drmModePlanePtr plane;
-               unsigned int type = 0, zpos = 0;
-               int output_find = 0;
-
-               plane = drmModeGetPlane(exynos_data->drm_fd, exynos_data->plane_res->planes[i]);
-               if (!plane) {
-                       TDM_ERR("no plane");
-                       continue;
-               }
-
-               ret = tdm_exynos_display_get_property(exynos_data,
-                                                                                         exynos_data->plane_res->planes[i],
-                                                                                         DRM_MODE_OBJECT_PLANE, "type", &type, NULL);
-               if (ret != TDM_ERROR_NONE) {
-                       TDM_ERR("plane(%d) doesn't have 'type' info",
-                                       exynos_data->plane_res->planes[i]);
-                       drmModeFreePlane(plane);
-                       continue;
-               }
-
-               ret = tdm_exynos_display_get_property(exynos_data,
-                                                                                         exynos_data->plane_res->planes[i],
-                                                                                         DRM_MODE_OBJECT_PLANE, "zpos", &zpos, NULL);
-               if (ret != TDM_ERROR_NONE) {
-                       TDM_ERR("plane(%d) doesn't have 'zpos' info",
-                                       exynos_data->plane_res->planes[i]);
-                       drmModeFreePlane(plane);
-                       continue;
-               }
-
-               layer_data = calloc(1, sizeof(tdm_exynos_layer_data));
-               if (!layer_data) {
-                       TDM_ERR("alloc failed");
-                       drmModeFreePlane(plane);
-                       continue;
-               }
-
-               LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link) {
-                       if (plane->possible_crtcs & (1 << output_data->pipe)) {
-                               output_find = 1;
-                               break;
-                       }
-               }
-
-               if (!output_find) {
-                       TDM_ERR("plane(%d) couldn't found proper output", plane->plane_id);
-                       drmModeFreePlane(plane);
-                       free(layer_data);
-                       continue;
-               }
-
-               layer_data->exynos_data = exynos_data;
-               layer_data->output_data = output_data;
-               layer_data->plane_id = exynos_data->plane_res->planes[i];
-               layer_data->zpos = zpos;
-
-               if (type == DRM_PLANE_TYPE_CURSOR)
-                       layer_data->capabilities = TDM_LAYER_CAPABILITY_CURSOR |
-                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
-               else if (type == DRM_PLANE_TYPE_OVERLAY)
-                       layer_data->capabilities = TDM_LAYER_CAPABILITY_OVERLAY |
-                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
-               else if (type == DRM_PLANE_TYPE_PRIMARY) {
-                       layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY |
-                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
-                       output_data->primary_layer = layer_data;
-               } else {
-                       drmModeFreePlane(plane);
-                       free(layer_data);
-                       continue;
-               }
-
-               TDM_DBG("layer_data(%p) plane_id(%d) crtc_id(%d) zpos(%d) capabilities(%x)",
-                               layer_data, layer_data->plane_id, layer_data->output_data->crtc_id,
-                               layer_data->zpos, layer_data->capabilities);
-
-               LIST_ADDTAIL(&layer_data->link, &output_data->layer_list);
-
-               drmModeFreePlane(plane);
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-/* Only in case of 1 output and 5 layers. For other cases, kernel should give
- * the proper information. And _tdm_exynos_display_create_layer_list_immutable_zpos
- * should be called.
- */
-static tdm_error
-_tdm_exynos_display_create_layer_list_not_fixed(tdm_exynos_data *exynos_data)
-{
-       int find_pipe = -1;
-       int zpos = 0;
-       int output_count, i;
-
-       output_count = LIST_LENGTH(&exynos_data->output_list);
-
-       if (exynos_data->plane_res->count_planes < (output_count * LAYER_COUNT_FOR_NOT_FIXED)) {
-               TDM_ERR("not enough layers");
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       for (i = 0; i < exynos_data->plane_res->count_planes; i++) {
-               tdm_exynos_output_data *output_data = NULL;
-               tdm_exynos_layer_data *layer_data;
-               drmModePlanePtr plane;
-
-               plane = drmModeGetPlane(exynos_data->drm_fd, exynos_data->plane_res->planes[i]);
-               if (!plane) {
-                       TDM_ERR("no plane");
-                       continue;
-               }
-
-               layer_data = calloc(1, sizeof(tdm_exynos_layer_data));
-               if (!layer_data) {
-                       TDM_ERR("alloc failed");
-                       drmModeFreePlane(plane);
-                       continue;
-               }
-
-               if (i % LAYER_COUNT_FOR_NOT_FIXED == 0) {
-                       find_pipe++;
-                       zpos = 0;
-               }
-
-               LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link) {
-                       if (output_data->pipe == find_pipe)
-                               break;
-               }
-
-               layer_data->exynos_data = exynos_data;
-               layer_data->output_data = output_data;
-               layer_data->plane_id = exynos_data->plane_res->planes[i];
-
-               layer_data->zpos = zpos++;
-
-               if (layer_data->zpos == LAYER_PRIMARY_INDEX_FOR_NOT_FIXED) {
-                       layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY |
-                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
-                       output_data->primary_layer = layer_data;
-               } else {
-                       tdm_error ret;
-
-                       layer_data->capabilities = TDM_LAYER_CAPABILITY_OVERLAY |
-                                                                          TDM_LAYER_CAPABILITY_GRAPHIC;
-
-                       ret = tdm_exynos_display_set_property(exynos_data, layer_data->plane_id,
-                                                                                                 DRM_MODE_OBJECT_PLANE, "zpos", layer_data->zpos);
-                       if (ret != TDM_ERROR_NONE) {
-                               drmModeFreePlane(plane);
-                               free(layer_data);
-                               return TDM_ERROR_OPERATION_FAILED;
-                       }
-               }
-
-               TDM_DBG("layer_data(%p) plane_id(%d) crtc_id(%d) zpos(%d) capabilities(%x)",
-                               layer_data, layer_data->plane_id, layer_data->output_data->crtc_id,
-                               layer_data->zpos, layer_data->capabilities);
-
-               LIST_ADDTAIL(&layer_data->link, &output_data->layer_list);
-
-               drmModeFreePlane(plane);
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-void
-tdm_exynos_display_to_tdm_mode(drmModeModeInfoPtr drm_mode,
-                                                                               tdm_output_mode *tdm_mode)
-{
-       tdm_mode->clock = drm_mode->clock;
-       if (exynos_screen_prerotation_hint % 180) {
-               tdm_mode->hdisplay = drm_mode->vdisplay;
-               tdm_mode->hsync_start = drm_mode->vsync_start;
-               tdm_mode->hsync_end = drm_mode->vsync_end;
-               tdm_mode->htotal = drm_mode->vtotal;
-               tdm_mode->vdisplay = drm_mode->hdisplay;
-               tdm_mode->vsync_start = drm_mode->hsync_start;
-               tdm_mode->vsync_end = drm_mode->hsync_end;
-               tdm_mode->vtotal = drm_mode->htotal;
-       } else {
-               tdm_mode->hdisplay = drm_mode->hdisplay;
-               tdm_mode->hsync_start = drm_mode->hsync_start;
-               tdm_mode->hsync_end = drm_mode->hsync_end;
-               tdm_mode->htotal = drm_mode->htotal;
-               tdm_mode->vdisplay = drm_mode->vdisplay;
-               tdm_mode->vsync_start = drm_mode->vsync_start;
-               tdm_mode->vsync_end = drm_mode->vsync_end;
-               tdm_mode->vtotal = drm_mode->vtotal;
-       }
-       tdm_mode->hskew = drm_mode->hskew;
-       tdm_mode->vscan = drm_mode->vscan;
-       tdm_mode->vrefresh = drm_mode->vrefresh;
-       tdm_mode->flags = drm_mode->flags;
-       tdm_mode->type = drm_mode->type;
-       snprintf(tdm_mode->name, TDM_NAME_LEN, "%s", drm_mode->name);
-}
-
-tdm_error
-tdm_exynos_display_create_layer_list(tdm_exynos_data *exynos_data)
-{
-       tdm_exynos_output_data *output_data = NULL;
-       tdm_error ret;
-
-       if (!exynos_data->has_zpos_info)
-               ret = _tdm_exynos_display_create_layer_list_type(exynos_data);
-       else if (exynos_data->is_immutable_zpos)
-               ret = _tdm_exynos_display_create_layer_list_immutable_zpos(exynos_data);
-       else
-               ret = _tdm_exynos_display_create_layer_list_not_fixed(exynos_data);
-
-       if (ret != TDM_ERROR_NONE)
-               return ret;
-
-       LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link) {
-               if (!output_data->primary_layer) {
-                       TDM_ERR("output(%d) no primary layer", output_data->pipe);
-                       return TDM_ERROR_OPERATION_FAILED;
-               }
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-void
-tdm_exynos_display_destroy_output_list(tdm_exynos_data *exynos_data)
-{
-       tdm_exynos_output_data *o = NULL, *oo = NULL;
-
-       if (LIST_IS_EMPTY(&exynos_data->output_list))
-               return;
-
-       LIST_FOR_EACH_ENTRY_SAFE(o, oo, &exynos_data->output_list, link) {
-               LIST_DEL(&o->link);
-               if (!LIST_IS_EMPTY(&o->layer_list)) {
-                       tdm_exynos_layer_data *l = NULL, *ll = NULL;
-                       LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link) {
-                               LIST_DEL(&l->link);
-                               if (l->display_buffer)
-                                       tbm_surface_internal_unref(l->display_buffer->buffer);
-                               if (l->formats)
-                                       free(l->formats);
-                               if (l->props)
-                                       free(l->props);
-                               free(l);
-                       }
-               }
-               free(o->drm_modes);
-               free(o->output_modes);
-               free(o);
-       }
-}
-
-void
-tdm_exynos_display_update_output_status(tdm_exynos_data *exynos_data)
-{
-       tdm_exynos_output_data *output_data = NULL;
-
-       if (LIST_IS_EMPTY(&exynos_data->output_list))
-               return;
-
-       LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link) {
-               drmModeConnectorPtr connector;
-               tdm_output_conn_status new_status;
-
-               connector = drmModeGetConnector(exynos_data->drm_fd,
-                                                                               output_data->connector_id);
-               if (!connector) {
-                       TDM_ERR("no connector: %d", output_data->connector_id);
-                       continue;
-               }
-
-               if (connector->connection == DRM_MODE_CONNECTED)
-                       new_status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
-               else
-                       new_status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
-
-               tdm_exynos_output_update_status(output_data, new_status);
-
-               drmModeFreeConnector(connector);
-       }
-}
-
-tdm_error
-tdm_exynos_display_create_output_list(tdm_exynos_data *exynos_data)
-{
-       tdm_exynos_output_data *output_data;
-       int i;
-       tdm_error ret;
-       int allocated = 0;
-
-       RETURN_VAL_IF_FAIL(LIST_IS_EMPTY(&exynos_data->output_list),
-                                          TDM_ERROR_OPERATION_FAILED);
-
-       for (i = 0; i < exynos_data->mode_res->count_connectors; i++) {
-               drmModeConnectorPtr connector;
-               drmModeEncoderPtr encoder;
-               int crtc_id = 0, c, j;
-
-               connector = drmModeGetConnector(exynos_data->drm_fd,
-                                                                               exynos_data->mode_res->connectors[i]);
-               if (!connector) {
-                       TDM_ERR("no connector");
-                       ret = TDM_ERROR_OPERATION_FAILED;
-                       goto failed_create;
-               }
-
-               if (connector->count_encoders != 1) {
-                       TDM_ERR("too many encoders: %d", connector->count_encoders);
-                       drmModeFreeConnector(connector);
-                       ret = TDM_ERROR_OPERATION_FAILED;
-                       goto failed_create;
-               }
-
-               encoder = drmModeGetEncoder(exynos_data->drm_fd, connector->encoders[0]);
-               if (!encoder) {
-                       TDM_ERR("no encoder");
-                       drmModeFreeConnector(connector);
-                       ret = TDM_ERROR_OPERATION_FAILED;
-                       goto failed_create;
-               }
-
-               for (c = 0; c < exynos_data->mode_res->count_crtcs; c++) {
-                       if (allocated & (1 << c))
-                               continue;
-
-                       if ((encoder->possible_crtcs & (1 << c)) == 0)
-                               continue;
-
-                       crtc_id = exynos_data->mode_res->crtcs[c];
-                       allocated |= (1 << c);
-                       break;
-               }
-
-               if (crtc_id == 0) {
-                       TDM_ERR("no possible crtc");
-                       drmModeFreeConnector(connector);
-                       drmModeFreeEncoder(encoder);
-                       ret = TDM_ERROR_OPERATION_FAILED;
-                       goto failed_create;
-               }
-
-               output_data = calloc(1, sizeof(tdm_exynos_output_data));
-               if (!output_data) {
-                       TDM_ERR("alloc failed");
-                       drmModeFreeConnector(connector);
-                       drmModeFreeEncoder(encoder);
-                       ret = TDM_ERROR_OUT_OF_MEMORY;
-                       goto failed_create;
-               }
-
-               LIST_INITHEAD(&output_data->layer_list);
-
-               output_data->exynos_data = exynos_data;
-               output_data->connector_id = exynos_data->mode_res->connectors[i];
-               output_data->encoder_id = encoder->encoder_id;
-               output_data->crtc_id = crtc_id;
-               output_data->pipe = c;
-               output_data->connector_type = connector->connector_type;
-               output_data->connector_type_id = connector->connector_type_id;
-
-               if (connector->connection == DRM_MODE_CONNECTED)
-                       output_data->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
-               else
-                       output_data->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
-
-               for (j = 0; j < connector->count_props; j++) {
-                       drmModePropertyPtr prop = drmModeGetProperty(exynos_data->drm_fd,
-                                                                                                                connector->props[j]);
-                       if (!prop)
-                               continue;
-                       if (!strcmp(prop->name, "DPMS")) {
-                               output_data->dpms_prop_id = connector->props[j];
-                               drmModeFreeProperty(prop);
-                               break;
-                       }
-                       drmModeFreeProperty(prop);
-               }
-
-               output_data->count_modes = connector->count_modes;
-               output_data->drm_modes = calloc(connector->count_modes, sizeof(drmModeModeInfo));
-               if (!output_data->drm_modes) {
-                       TDM_ERR("alloc failed");
-                       free(output_data);
-                       drmModeFreeConnector(connector);
-                       drmModeFreeEncoder(encoder);
-                       ret = TDM_ERROR_OUT_OF_MEMORY;
-                       goto failed_create;
-               }
-               output_data->output_modes = calloc(connector->count_modes, sizeof(tdm_output_mode));
-               if (!output_data->output_modes) {
-                       TDM_ERR("alloc failed");
-                       free(output_data->drm_modes);
-                       free(output_data);
-                       drmModeFreeConnector(connector);
-                       drmModeFreeEncoder(encoder);
-                       ret = TDM_ERROR_OUT_OF_MEMORY;
-                       goto failed_create;
-               }
-               for (j = 0; j < connector->count_modes; j++) {
-                       output_data->drm_modes[j] = connector->modes[j];
-                       tdm_exynos_display_to_tdm_mode(&output_data->drm_modes[j],
-                                                                                  &output_data->output_modes[j]);
-               }
-
-               /* now E20 supported HWC API only for the main output */
-               if (output_data->exynos_data->hwc_mode &&
-                       output_data->connector_type == TDM_OUTPUT_TYPE_DSI) {
-                       output_data->hwc_enable = 1;
-               }
-
-               LIST_ADDTAIL(&output_data->link, &exynos_data->output_list);
-
-               TDM_DBG("output_data(%p) connector_id(%d:%d:%d-%d) encoder_id(%d) crtc_id(%d) pipe(%d) dpms_id(%d)",
-                               output_data, output_data->connector_id, output_data->status,
-                               output_data->connector_type,
-                               output_data->connector_type_id, output_data->encoder_id, output_data->crtc_id,
-                               output_data->pipe, output_data->dpms_prop_id);
-
-               drmModeFreeEncoder(encoder);
-               drmModeFreeConnector(connector);
-       }
-
-       TDM_DBG("output count: %d", exynos_data->mode_res->count_connectors);
-
-       return TDM_ERROR_NONE;
-failed_create:
-       tdm_exynos_display_destroy_output_list(exynos_data);
-       return ret;
-}
-
-tdm_error
-tdm_exynos_display_set_property(tdm_exynos_data *exynos_data,
-                                                                          unsigned int obj_id, unsigned int obj_type,
-                                                                          const char *name, unsigned int value)
-{
-       drmModeObjectPropertiesPtr props = NULL;
-       unsigned int i;
-
-       props = drmModeObjectGetProperties(exynos_data->drm_fd, obj_id, obj_type);
-       if (!props) {
-               TDM_ERR("drmModeObjectGetProperties failed: %m");
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-       for (i = 0; i < props->count_props; i++) {
-               drmModePropertyPtr prop = drmModeGetProperty(exynos_data->drm_fd,
-                                                                                                        props->props[i]);
-               int ret;
-               if (!prop) {
-                       TDM_ERR("drmModeGetProperty failed: %m");
-                       drmModeFreeObjectProperties(props);
-                       return TDM_ERROR_OPERATION_FAILED;
-               }
-               if (!strcmp(prop->name, name)) {
-                       ret = drmModeObjectSetProperty(exynos_data->drm_fd, obj_id, obj_type,
-                                                                                  prop->prop_id, value);
-                       if (ret < 0) {
-                               TDM_ERR("drmModeObjectSetProperty failed: %m");
-                               drmModeFreeProperty(prop);
-                               drmModeFreeObjectProperties(props);
-                               return TDM_ERROR_OPERATION_FAILED;
-                       }
-                       drmModeFreeProperty(prop);
-                       drmModeFreeObjectProperties(props);
-                       return TDM_ERROR_NONE;
-               }
-               drmModeFreeProperty(prop);
-       }
-
-       TDM_ERR("not found '%s' property", name);
-
-       drmModeFreeObjectProperties(props);
-       /* TODO
-       * kernel info error
-       * it must be changed to 'return TDM_ERROR_OPERATION_FAILED' after kernel fix.
-       */
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-tdm_exynos_display_get_property(tdm_exynos_data *exynos_data,
-                                                                          unsigned int obj_id, unsigned int obj_type,
-                                                                          const char *name, unsigned int *value, int *is_immutable)
-{
-       drmModeObjectPropertiesPtr props = NULL;
-       int i;
-
-       props = drmModeObjectGetProperties(exynos_data->drm_fd, obj_id, obj_type);
-       if (!props)
-               return TDM_ERROR_OPERATION_FAILED;
-
-       for (i = 0; i < props->count_props; i++) {
-               drmModePropertyPtr prop = drmModeGetProperty(exynos_data->drm_fd,
-                                                                                                        props->props[i]);
-
-               if (!prop)
-                       continue;
-
-               if (!strcmp(prop->name, name)) {
-                       if (is_immutable)
-                               *is_immutable = prop->flags & DRM_MODE_PROP_IMMUTABLE;
-                       if (value)
-                               *value = (unsigned int)props->prop_values[i];
-                       drmModeFreeProperty(prop);
-                       drmModeFreeObjectProperties(props);
-                       return TDM_ERROR_NONE;
-               }
-
-               drmModeFreeProperty(prop);
-       }
-       drmModeFreeObjectProperties(props);
-       TDM_DBG("coundn't find '%s' property", name);
-       return TDM_ERROR_OPERATION_FAILED;
-}
-
-tdm_error
-exynos_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps)
-{
-       RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
-
-       caps->max_layer_count = -1; /* not defined */
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps)
-{
-       tdm_exynos_data *exynos_data = bdata;
-       if (exynos_data->use_ippv2)
-               return tdm_exynos_pp_get_capability(bdata, caps);
-       else
-               return tdm_exynos_pp_legacy_get_capability(bdata, caps);
-}
-
-tdm_error
-exynos_display_get_capture_capability(tdm_backend_data *bdata, tdm_caps_capture *caps)
-{
-       tdm_exynos_data *exynos_data = bdata;
-       if (exynos_data->use_ippv2)
-               return tdm_exynos_capture_get_capability(bdata, caps);
-       else
-               return tdm_exynos_capture_legacy_get_capability(bdata, caps);
-}
-
-tdm_output **
-exynos_display_get_outputs(tdm_backend_data *bdata, int *count,
-                                                                tdm_error *error)
-{
-       tdm_exynos_data *exynos_data = bdata;
-       tdm_exynos_output_data *output_data = NULL;
-       tdm_output **outputs;
-       tdm_error ret;
-       int i;
-
-       RETURN_VAL_IF_FAIL(exynos_data, NULL);
-       RETURN_VAL_IF_FAIL(count, NULL);
-
-       *count = 0;
-       LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link)
-       (*count)++;
-
-       if (*count == 0) {
-               ret = TDM_ERROR_NONE;
-               goto failed_get;
-       }
-
-       /* will be freed in frontend */
-       outputs = calloc(*count, sizeof(tdm_exynos_output_data *));
-       if (!outputs) {
-               TDM_ERR("failed: alloc memory");
-               *count = 0;
-               ret = TDM_ERROR_OUT_OF_MEMORY;
-               goto failed_get;
-       }
-
-       i = 0;
-       LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link)
-       outputs[i++] = output_data;
-
-       if (error)
-               *error = TDM_ERROR_NONE;
-
-       return outputs;
-failed_get:
-       if (error)
-               *error = ret;
-       return NULL;
-}
-
-tdm_error
-exynos_display_get_fd(tdm_backend_data *bdata, int *fd)
-{
-       tdm_exynos_data *exynos_data = bdata;
-
-       RETURN_VAL_IF_FAIL(exynos_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(fd, TDM_ERROR_INVALID_PARAMETER);
-
-       *fd = exynos_data->drm_fd;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_display_handle_events(tdm_backend_data *bdata)
-{
-       tdm_exynos_data *exynos_data = bdata;
-       drmEventContext ctx;
-
-       RETURN_VAL_IF_FAIL(exynos_data, TDM_ERROR_INVALID_PARAMETER);
-
-       memset(&ctx, 0, sizeof(drmEventContext));
-
-       ctx.version = DRM_EVENT_CONTEXT_VERSION;
-       ctx.page_flip_handler = tdm_exynos_output_cb_event;
-       ctx.vblank_handler = tdm_exynos_output_cb_event;
-
-       drmHandleEvent(exynos_data->drm_fd, &ctx);
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_pp *
-exynos_display_create_pp(tdm_backend_data *bdata, tdm_error *error)
-{
-       tdm_exynos_data *exynos_data = bdata;
-
-       RETURN_VAL_IF_FAIL(exynos_data, NULL);
-
-       if (exynos_data->use_ippv2)
-               return tdm_exynos_pp_create(exynos_data, error);
-       else
-               return tdm_exynos_pp_legacy_create(exynos_data, error);
-}
diff --git a/src/tdm_exynos_display.h b/src/tdm_exynos_display.h
deleted file mode 100644 (file)
index 94a1fe9..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _TDM_EXYNOS_DISPLAY_H_
-#define _TDM_EXYNOS_DISPLAY_H_
-
-#include "tdm_exynos.h"
-
-void         tdm_exynos_display_update_output_status(tdm_exynos_data *exynos_data);
-tdm_error    tdm_exynos_display_create_output_list(tdm_exynos_data *exynos_data);
-void         tdm_exynos_display_destroy_output_list(tdm_exynos_data *exynos_data);
-tdm_error    tdm_exynos_display_create_layer_list(tdm_exynos_data *exynos_data);
-tdm_error    tdm_exynos_display_set_property(tdm_exynos_data *exynos_data,
-                                                                                                       unsigned int obj_id, unsigned int obj_type,
-                                                                                                       const char *name, unsigned int value);
-tdm_error    tdm_exynos_display_get_property(tdm_exynos_data *exynos_data,
-                                                                                                       unsigned int obj_id, unsigned int obj_type,
-                                                                                                       const char *name, unsigned int *value, int *is_immutable);
-void         tdm_exynos_display_to_tdm_mode(drmModeModeInfoPtr drm_mode, tdm_output_mode *tdm_mode);
-
-
-#endif /* _TDM_EXYNOS_DISPLAY_H_ */
diff --git a/src/tdm_exynos_format.c b/src/tdm_exynos_format.c
deleted file mode 100644 (file)
index 9a030ad..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <drm_fourcc.h>
-#include <tbm_surface.h>
-
-#include "tdm_exynos.h"
-
-#ifndef TBM_FORMAT_NV12MT
-#define TBM_FORMAT_NV12MT   FOURCC('T', 'M', '1', '2')
-#endif
-
-#ifndef DRM_FORMAT_12MT
-#define DRM_FORMAT_12MT     FOURCC('T', 'M', '1', '2')
-#endif
-
-typedef struct {
-       tbm_format  tbm_format;
-       uint32_t    drm_format;
-} tbm_exynos_format_data;
-
-static const tbm_exynos_format_data formats[] = {
-       {TBM_FORMAT_C8, DRM_FORMAT_C8},
-       {TBM_FORMAT_RGB332, DRM_FORMAT_RGB332},
-       {TBM_FORMAT_BGR233, DRM_FORMAT_BGR233},
-       {TBM_FORMAT_XRGB4444, DRM_FORMAT_XRGB4444},
-       {TBM_FORMAT_XBGR4444, DRM_FORMAT_XBGR4444},
-       {TBM_FORMAT_RGBX4444, DRM_FORMAT_RGBX4444},
-       {TBM_FORMAT_BGRX4444, DRM_FORMAT_BGRX4444},
-       {TBM_FORMAT_ARGB4444, DRM_FORMAT_ARGB4444},
-       {TBM_FORMAT_ABGR4444, DRM_FORMAT_ABGR4444},
-       {TBM_FORMAT_RGBA4444, DRM_FORMAT_RGBA4444},
-       {TBM_FORMAT_BGRA4444, DRM_FORMAT_BGRA4444},
-       {TBM_FORMAT_XRGB1555, DRM_FORMAT_XRGB1555},
-       {TBM_FORMAT_XBGR1555, DRM_FORMAT_XBGR1555},
-       {TBM_FORMAT_RGBX5551, DRM_FORMAT_RGBX5551},
-       {TBM_FORMAT_BGRX5551, DRM_FORMAT_BGRX5551},
-       {TBM_FORMAT_ARGB1555, DRM_FORMAT_ARGB1555},
-       {TBM_FORMAT_ABGR1555, DRM_FORMAT_ABGR1555},
-       {TBM_FORMAT_RGBA5551, DRM_FORMAT_RGBA5551},
-       {TBM_FORMAT_BGRA5551, DRM_FORMAT_BGRA5551},
-       {TBM_FORMAT_RGB565, DRM_FORMAT_RGB565},
-       {TBM_FORMAT_BGR565, DRM_FORMAT_BGR565},
-       {TBM_FORMAT_RGB888, DRM_FORMAT_RGB888},
-       {TBM_FORMAT_BGR888, DRM_FORMAT_BGR888},
-       {TBM_FORMAT_XRGB8888, DRM_FORMAT_XRGB8888},
-       {TBM_FORMAT_XBGR8888, DRM_FORMAT_XBGR8888},
-       {TBM_FORMAT_RGBX8888, DRM_FORMAT_RGBX8888},
-       {TBM_FORMAT_BGRX8888, DRM_FORMAT_BGRX8888},
-       {TBM_FORMAT_ARGB8888, DRM_FORMAT_ARGB8888},
-       {TBM_FORMAT_ABGR8888, DRM_FORMAT_ABGR8888},
-       {TBM_FORMAT_RGBA8888, DRM_FORMAT_RGBA8888},
-       {TBM_FORMAT_BGRA8888, DRM_FORMAT_BGRA8888},
-       {TBM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB2101010},
-       {TBM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR2101010},
-       {TBM_FORMAT_RGBX1010102, DRM_FORMAT_RGBX1010102},
-       {TBM_FORMAT_BGRX1010102, DRM_FORMAT_BGRX1010102},
-       {TBM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB2101010},
-       {TBM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR2101010},
-       {TBM_FORMAT_RGBA1010102, DRM_FORMAT_RGBA1010102},
-       {TBM_FORMAT_BGRA1010102, DRM_FORMAT_BGRA1010102},
-       {TBM_FORMAT_YUYV, DRM_FORMAT_YUYV},
-       {TBM_FORMAT_YVYU, DRM_FORMAT_YVYU},
-       {TBM_FORMAT_UYVY, DRM_FORMAT_UYVY},
-       {TBM_FORMAT_VYUY, DRM_FORMAT_VYUY},
-       {TBM_FORMAT_AYUV, DRM_FORMAT_AYUV},
-       {TBM_FORMAT_NV12, DRM_FORMAT_NV12},
-       {TBM_FORMAT_NV21, DRM_FORMAT_NV21},
-       {TBM_FORMAT_NV16, DRM_FORMAT_NV16},
-       {TBM_FORMAT_NV61, DRM_FORMAT_NV61},
-       {TBM_FORMAT_YUV410, DRM_FORMAT_YUV410},
-       {TBM_FORMAT_YVU410, DRM_FORMAT_YVU410},
-       {TBM_FORMAT_YUV411, DRM_FORMAT_YUV411},
-       {TBM_FORMAT_YVU411, DRM_FORMAT_YVU411},
-       {TBM_FORMAT_YUV420, DRM_FORMAT_YUV420},
-       {TBM_FORMAT_YVU420, DRM_FORMAT_YVU420},
-       {TBM_FORMAT_YUV422, DRM_FORMAT_YUV422},
-       {TBM_FORMAT_YVU422, DRM_FORMAT_YVU422},
-       {TBM_FORMAT_YUV444, DRM_FORMAT_YUV444},
-       {TBM_FORMAT_YVU444, DRM_FORMAT_YVU444},
-       {TBM_FORMAT_NV12MT, DRM_FORMAT_12MT},
-};
-
-#define NUM_FORMATS (sizeof(formats) / sizeof(formats[0]))
-
-uint32_t
-tdm_exynos_format_to_drm_format(tbm_format format)
-{
-       int i;
-
-       for (i = 0; i < NUM_FORMATS; i++)
-               if (formats[i].tbm_format == format)
-                       return formats[i].drm_format;
-
-       TDM_ERR("tbm format '%c%c%c%c' not found", FOURCC_STR(format));
-
-       return 0;
-}
-
-tbm_format
-tdm_exynos_format_to_tbm_format(uint32_t format)
-{
-       int i;
-
-       for (i = 0; i < NUM_FORMATS; i++)
-               if (formats[i].drm_format == format)
-                       return formats[i].tbm_format;
-
-       TDM_ERR("drm format '%c%c%c%c' not found", FOURCC_STR(format));
-
-       return 0;
-}
diff --git a/src/tdm_exynos_format.h b/src/tdm_exynos_format.h
deleted file mode 100644 (file)
index f41400c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _TDM_EXYNOS_FORMAT_H_
-#define _TDM_EXYNOS_FORMAT_H_
-
-#include "tdm_exynos.h"
-
-uint32_t     tdm_exynos_format_to_drm_format(tbm_format format);
-tbm_format   tdm_exynos_format_to_tbm_format(uint32_t format);
-
-#endif /* _TDM_EXYNOS_FORMAT_H_ */
diff --git a/src/tdm_exynos_hwc.c b/src/tdm_exynos_hwc.c
deleted file mode 100644 (file)
index b8a5bc6..0000000
+++ /dev/null
@@ -1,714 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <tdm_helper.h>
-#include "tdm_exynos.h"
-
-#define MIN_WIDTH   32
-
-tdm_hwc_window *
-_exynos_hwc_create_window(tdm_hwc *hwc, tdm_hwc_window_info *info,
-                                                                tdm_error *error);
-
-const char *
-_comp_to_str(tdm_hwc_window_composition composition_type)
-{
-       if (composition_type == TDM_HWC_WIN_COMPOSITION_CLIENT)
-               return "CLIENT";
-       else if (composition_type == TDM_HWC_WIN_COMPOSITION_DEVICE)
-               return "DEVICE";
-       else if (composition_type == TDM_HWC_WIN_COMPOSITION_CURSOR)
-               return "CURSOR";
-       else if (composition_type == TDM_HWC_WIN_COMPOSITION_VIDEO)
-               return "VIDEO";
-       else if (composition_type == TDM_HWC_WIN_COMPOSITION_NONE)
-               return "SKIP";
-
-       return "unknown";
-}
-
-static int
-_can_set_hwc_window_on_hw_layer(tdm_exynos_hwc_window_data *hwc_window_data)
-{
-       if (!hwc_window_data->surface)
-               return 0;
-
-       if (hwc_window_data->info.transform != TDM_TRANSFORM_NORMAL)
-               return 0;
-
-       if (hwc_window_data->info.src_config.pos.w != hwc_window_data->info.dst_pos.w)
-               return 0;
-
-       if (hwc_window_data->info.src_config.pos.h != hwc_window_data->info.dst_pos.h)
-               return 0;
-
-       if (!IS_RGB(hwc_window_data->info.src_config.format))
-               return 0;
-
-       if (hwc_window_data->info.dst_pos.x > hwc_window_data->hwc_data->output_data->current_mode->hdisplay ||
-               hwc_window_data->info.dst_pos.y > hwc_window_data->hwc_data->output_data->current_mode->vdisplay)
-               return 0;
-
-       if (hwc_window_data->info.src_config.size.h < MIN_WIDTH || hwc_window_data->info.src_config.size.h % 2)
-               return 0;
-
-       return 1;
-}
-
-tdm_exynos_layer_data *
-_exynos_hwc_get_layer(tdm_exynos_hwc_data *hwc_data, int zpos)
-{
-       tdm_exynos_output_data *output_data = hwc_data->output_data;
-       tdm_exynos_layer_data *l = NULL;
-
-       LIST_FOR_EACH_ENTRY(l, &output_data->layer_list, link)
-               if (l->zpos == zpos)
-                       return l;
-
-       return NULL;
-}
-
-static tdm_error
-_set_hwc_window_buffer_to_layer(tdm_exynos_layer_data *layer_data,
-                                                               tdm_exynos_hwc_window_data *hwc_window_data)
-{
-       tdm_error ret;
-
-       if (hwc_window_data == NULL || !hwc_window_data->surface) {
-               ret = exynos_layer_unset_buffer(layer_data);
-       } else {
-               ret = exynos_layer_set_buffer(layer_data, hwc_window_data->surface);
-       }
-
-       RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
-
-       return ret;
-}
-
-static tdm_exynos_hwc_window_data *
-_find_maped_hwc_window_to_layer(struct list_head *hwc_wnds, int layer_zpos)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-
-       LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
-               if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
-                       continue;
-
-               if (hwc_window_data->assigned_layer_zpos == layer_zpos &&
-                       (hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_DEVICE ||
-                        hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_CURSOR ||
-                        hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_VIDEO)) {
-                               TDM_DBG(" window(%p) type: %s -> %s : candidate_zpos:%d assigned_zpos:%d", hwc_window_data,
-                                               _comp_to_str(hwc_window_data->client_type), _comp_to_str(hwc_window_data->validated_type),
-                                               hwc_window_data->candidate_layer_zpos, hwc_window_data->assigned_layer_zpos);
-                               return hwc_window_data;
-                }
-       }
-
-       return NULL;
-}
-
-static void
-_update_layers_info(tdm_exynos_hwc_data *hwc_data)
-{
-       tdm_exynos_layer_data *layer = NULL;
-       tdm_exynos_output_data *output_data = hwc_data->output_data;
-       tdm_exynos_hwc_window_data *hwc_window_data;
-       tdm_error ret;
-
-       LIST_FOR_EACH_ENTRY(layer, &output_data->layer_list, link) {
-               if (hwc_data->need_target_window && layer->zpos == hwc_data->target_window_zpos)
-                       hwc_window_data = hwc_data->target_hwc_window;
-               else
-                       hwc_window_data = _find_maped_hwc_window_to_layer(&hwc_data->hwc_window_list, layer->zpos);
-
-               if (hwc_window_data) {
-                       ret = exynos_layer_set_info((tdm_layer *)layer, (tdm_info_layer *)&(hwc_window_data->info));
-                       if (ret != TDM_ERROR_NONE)
-                               TDM_ERR("cannot set info to layer with %d zpos", layer->zpos);
-               }
-       }
-}
-
-static tdm_exynos_hwc_window_data *
-_exynos_hwc_find_assigned_hwc_window(struct list_head *hwc_wnds, int layer_zpos)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-
-       LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
-               if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
-                       continue;
-
-               if (hwc_window_data->assigned_layer_zpos == layer_zpos) {
-                       return hwc_window_data;
-               }
-       }
-
-       return NULL;
-}
-
-static tdm_error
-_exynos_hwc_prepare_commit(tdm_exynos_hwc_data *hwc_data) {
-       tdm_exynos_layer_data *layer = NULL;
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-       tdm_exynos_output_data *output_data = hwc_data->output_data;
-
-       _update_layers_info(hwc_data);
-
-       /* set target hwc window */
-       if (hwc_data->need_target_window) {
-               layer = _exynos_hwc_get_layer(hwc_data, hwc_data->target_window_zpos);
-               _set_hwc_window_buffer_to_layer(layer, hwc_data->target_hwc_window);
-       }
-
-       LIST_FOR_EACH_ENTRY(layer, &output_data->layer_list, link) {
-               if (hwc_data->need_target_window && layer == output_data->primary_layer)
-                       continue;
-
-               hwc_window_data = _exynos_hwc_find_assigned_hwc_window(&hwc_data->hwc_window_list, layer->zpos);
-               if (hwc_window_data) {
-                       _set_hwc_window_buffer_to_layer(layer, hwc_window_data);
-               } else {
-                       /* do not set the null on the primary layer */
-                       if (layer != output_data->primary_layer)
-                               _set_hwc_window_buffer_to_layer(layer, NULL);
-               }
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-static int
-_exynos_hwc_get_primary_layer_zpos(tdm_exynos_hwc_data *hwc_data)
-{
-       tdm_exynos_output_data *output_data = hwc_data->output_data;
-       tdm_exynos_layer_data *layer = NULL;
-
-       LIST_FOR_EACH_ENTRY(layer, &output_data->layer_list, link) {
-               if (layer->capabilities & TDM_LAYER_CAPABILITY_PRIMARY)
-                       return layer->zpos;
-       }
-
-       return 0;
-}
-
-/* decide the validated_types and the assigned_layer_zpos of the hwc_windows */
-static void
-_exynos_hwc_adapt_policy(tdm_exynos_hwc_data *hwc_data , tdm_hwc_window **composited_wnds, uint32_t num_wnds)
-{
-       tdm_exynos_output_data *output_data = hwc_data->output_data;
-       tdm_exynos_hwc_window_data **composited_list = NULL;
-       int num_visible_windows = num_wnds;
-       int available_layers = LIST_LENGTH(&output_data->layer_list);
-       int num_videos = 0, num_clients = 0;
-       int min_zpos = 0, max_zpos = 0;
-       int i;
-
-       composited_list = (tdm_exynos_hwc_window_data**)composited_wnds;
-
-       TDM_DBG("1. available_layers=%d, primary_layer_zpos=%d, num_visible_windows=%d",
-                       available_layers, _exynos_hwc_get_primary_layer_zpos(hwc_data), num_visible_windows);
-
-       if (output_data->status != TDM_OUTPUT_CONN_STATUS_MODE_SETTED) {
-               hwc_data->target_window_zpos = _exynos_hwc_get_primary_layer_zpos(hwc_data);
-               hwc_data->need_target_window = 1;
-               goto set_all_client_types;
-       } else {
-               /* initialize the zpos of the target_window */
-               hwc_data->target_window_zpos = _exynos_hwc_get_primary_layer_zpos(hwc_data);
-               hwc_data->need_target_window = 0;
-       }
-
-       /* need_target_window is true and return when there are no visible windows */
-       if (!num_visible_windows) {
-               hwc_data->need_target_window = 1;
-               return;
-       }
-
-       /* reset the validated_type and hw layer policy */
-       for (i = 0; i < num_wnds; i++) {
-               if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_VIDEO) {
-                       composited_list[i]->validated_type = composited_list[i]->client_type;
-                       composited_list[i]->candidate_layer_zpos = 0;
-                       ++num_videos;
-                       /* The video window occupies the bottom layer */
-                       ++min_zpos;
-                       --available_layers;
-                       continue;
-               }
-
-               composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CLIENT;
-               composited_list[i]->candidate_layer_zpos = -1;
-
-               /* The validate type of all windows below this window are TDM_HWC_WIN_COMPOSITION_CLIENT
-                * if the upper window is TDM_COMPSITION_CLIENT type.
-                */
-               if (num_clients > 0) {
-                       ++num_clients;
-                       continue;
-               }
-
-               /* increase the num_clients when the type of the window is TDM_COMPOSITE_CLIENT. */
-               if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_CLIENT) {
-                       ++num_clients;
-                       /* need target_window to composite */
-                       ++min_zpos;
-                       --available_layers;
-                       hwc_data->need_target_window = 1;
-               }
-       }
-
-       /* calculate the num windows which can be the candidates */
-       num_visible_windows = num_visible_windows - num_clients - num_videos;
-       if (num_visible_windows > available_layers) {
-               /* need target_window to composite if need_target_window is not set above */
-               if (hwc_data->need_target_window == 0) {
-                       if (num_videos > 0) {
-                               ++min_zpos;
-                               --available_layers;
-                       } else {
-                                min_zpos = min_zpos + 2;
-                                available_layers = available_layers - 2;
-                       }
-                       hwc_data->need_target_window = 1;
-               }
-               max_zpos = LIST_LENGTH(&output_data->layer_list) - 1;
-       } else {
-               if (num_visible_windows == 1)
-                       max_zpos = 1;
-               else
-                       max_zpos = min_zpos + num_visible_windows - 1;
-       }
-
-       TDM_DBG("2. available_layers=%d, max_zpos=%d, num_visible_windows=%d", available_layers, max_zpos, num_visible_windows);
-
-       /* assgin the hw layers to the ui windows from the top to the bottom */
-       for (i = 0; i < num_wnds; i++) {
-               if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_VIDEO)
-                       continue;
-               if (available_layers == 0)
-                       break;
-
-               if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_DEVICE ||
-                   composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_CURSOR) {
-                       if (_can_set_hwc_window_on_hw_layer(composited_list[i])) {
-                               composited_list[i]->validated_type = composited_list[i]->client_type;
-                               composited_list[i]->candidate_layer_zpos = max_zpos;
-                               max_zpos--;
-                               available_layers--;
-                       } else
-                               goto set_all_client_types;
-               }
-       }
-
-       return;
-
-set_all_client_types:
-       TDM_DBG("Set all windows to be CLIENT type due to hw restriction.!!");
-
-       for (i = 0; i < num_wnds; i++) {
-               if (composited_list[i]->client_type == TDM_HWC_WIN_COMPOSITION_VIDEO)
-                       continue;
-
-               composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CLIENT;
-               composited_list[i]->candidate_layer_zpos = -1;
-       }
-
-       hwc_data->need_target_window = 1;
-       hwc_data->target_window_zpos = _exynos_hwc_get_primary_layer_zpos(hwc_data);;
-}
-
-static void
-_print_validate_result(tdm_exynos_hwc_data *hwc_data)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-       int primary_layer_zpos = _exynos_hwc_get_primary_layer_zpos(hwc_data);
-
-       LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
-               if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
-                       continue;
-
-               if (hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_DEVICE ||
-                   hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_CURSOR ||
-                       hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_VIDEO)
-                       TDM_DBG(" window(%p) type: %s -> %s : is mapped to layer with %d zpos", hwc_window_data,
-                                       _comp_to_str(hwc_window_data->client_type), _comp_to_str(hwc_window_data->validated_type),
-                                       hwc_window_data->candidate_layer_zpos);
-               else
-                       TDM_DBG(" window(%p) type: %s -> %s : is composited to layer with %d zpos. need_target_window: %d", hwc_window_data,
-                                       _comp_to_str(hwc_window_data->client_type), _comp_to_str(hwc_window_data->validated_type),
-                                       primary_layer_zpos, hwc_data->need_target_window);
-       }
-}
-
-static void
-_exynos_hwc_assigned_layer_zpos_update(tdm_exynos_hwc_data *hwc_data)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-
-       LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
-               if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
-                       continue;
-
-               if (hwc_window_data->candidate_layer_zpos == -1) {
-                       hwc_window_data->assigned_layer_zpos = -1;
-                       continue;
-               }
-
-               hwc_window_data->assigned_layer_zpos = hwc_window_data->candidate_layer_zpos;
-
-               TDM_DBG(" window(%p) type: %s -> %s : candidate_zpos:%d assigned_zpos:%d", hwc_window_data,
-                               _comp_to_str(hwc_window_data->client_type), _comp_to_str(hwc_window_data->validated_type),
-                               hwc_window_data->candidate_layer_zpos, hwc_window_data->assigned_layer_zpos);
-       }
-}
-
-static int
-_exynos_hwc_get_changed_number(tdm_exynos_hwc_data *hwc_data)
-{
-       int num = 0;
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-
-       LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
-               if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
-                       continue;
-               if (hwc_window_data->client_type != hwc_window_data->validated_type)
-                       num++;
-       }
-
-       return num;
-}
-
-#if 0
-static int
-_exynos_hwc_exynos_hwc_get_primary_layer_zpos(tdm_exynos_hwc_data *hwc_data)
-{
-       tdm_exynos_output_data *output_data = hwc_data->output_data;
-       tdm_exynos_layer_data *layer = NULL;
-
-       LIST_FOR_EACH_ENTRY(layer, &output_data->layer_list, link) {
-               if (layer->capabilities & TDM_LAYER_CAPABILITY_PRIMARY)
-                       return layer->zpos;
-       }
-
-       return 0;
-}
-#endif
-
-static tbm_surface_queue_h
-_exynos_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-       tbm_surface_queue_h tqueue = NULL;
-       int width, height;
-       tbm_format format;
-
-       if (error)
-               *error = TDM_ERROR_INVALID_PARAMETER;
-
-       RETURN_VAL_IF_FAIL(hwc_window != NULL, NULL);
-
-       hwc_window_data = hwc_window;
-
-       width = hwc_window_data->info.src_config.size.h;
-       height = hwc_window_data->info.src_config.size.v;
-       format = hwc_window_data->info.src_config.format;
-
-       tqueue = tbm_surface_queue_create(3, width, height, format, TBM_BO_SCANOUT);
-       if (error)
-               *error = TDM_ERROR_OPERATION_FAILED;
-       RETURN_VAL_IF_FAIL(tqueue != NULL, NULL);
-
-       if (error)
-               *error = TDM_ERROR_NONE;
-
-       return tqueue;
-
-}
-
-tdm_hwc_window *
-_exynos_hwc_create_window(tdm_hwc *hwc, tdm_hwc_window_info *info, tdm_error *error)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-       tdm_exynos_hwc_data *hwc_data = hwc;
-
-       if (error)
-               *error = TDM_ERROR_NONE;
-
-       if (!hwc_data) {
-               TDM_ERR("invalid params");
-               if (error)
-                       *error = TDM_ERROR_INVALID_PARAMETER;
-               return NULL;
-       }
-
-       hwc_window_data = calloc(1, sizeof(tdm_exynos_hwc_window_data));
-       if (!hwc_window_data) {
-               TDM_ERR("alloc failed");
-               if (error)
-                       *error = TDM_ERROR_OUT_OF_MEMORY;
-               return NULL;
-       }
-
-       hwc_window_data->client_type = TDM_HWC_WIN_COMPOSITION_NONE;
-       hwc_window_data->validated_type = -1;
-       hwc_window_data->assigned_layer_zpos = -1;
-
-       hwc_window_data->hwc_data = hwc_data;
-
-       if (info)
-               memcpy(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info));
-
-       LIST_INITHEAD(&hwc_window_data->link);
-
-       return hwc_window_data;
-}
-
-tdm_error
-exynos_hwc_initailize_target_window(tdm_exynos_hwc_data *hwc_data, int width, int height)
-{
-       tdm_hwc_window_info info = {0};
-       tdm_error ret = TDM_ERROR_NONE;
-       tdm_exynos_hwc_window_data *target_hwc_window;
-
-       RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
-
-       info.dst_pos.x = 0;
-       info.dst_pos.y = 0;
-       info.dst_pos.h = height;
-       info.dst_pos.w = width;
-
-       info.src_config.pos.x = 0;
-       info.src_config.pos.y = 0;
-       info.src_config.pos.h = height;
-       info.src_config.pos.w = width;
-
-       info.src_config.size.h = width;
-       info.src_config.size.v = height;
-       info.src_config.format = TBM_FORMAT_ARGB8888;
-
-       target_hwc_window = _exynos_hwc_create_window(hwc_data, &info, &ret);
-       if (target_hwc_window == NULL) {
-               TDM_ERR("create target hwc window failed (%d)", ret);
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       if (hwc_data->target_hwc_window)
-               exynos_hwc_window_destroy(hwc_data->target_hwc_window);
-
-       hwc_data->target_hwc_window = target_hwc_window;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_hwc_window *
-exynos_hwc_create_window(tdm_hwc *hwc, tdm_error *error)
-{
-       tdm_exynos_hwc_data *hwc_data = hwc;
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-
-       hwc_window_data = _exynos_hwc_create_window(hwc_data, NULL, error);
-       if (hwc_window_data == NULL)
-               return NULL;
-
-       LIST_ADDTAIL(&hwc_window_data->link, &hwc_data->hwc_window_list);
-
-       TDM_DBG("hwc_window_data(%p) create", hwc_window_data);
-       if (error)
-               *error = TDM_ERROR_NONE;
-
-       return hwc_window_data;
-}
-
-tdm_error
-exynos_hwc_get_video_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count)
-{
-       tdm_exynos_hwc_data *hwc_data = hwc;
-
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       // TODO:
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *capabilities)
-{
-       tdm_exynos_hwc_data *hwc_data = hwc;
-
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       *capabilities = 0;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count)
-{
-       tdm_exynos_hwc_data *hwc_data = hwc;
-
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       // TODO:
-
-       return TDM_ERROR_NONE;
-}
-
-tbm_surface_queue_h
-exynos_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error)
-{
-       tdm_exynos_hwc_data *hwc_data = hwc;
-       tbm_surface_queue_h tqueue = NULL;
-
-       if (error)
-               *error = TDM_ERROR_INVALID_PARAMETER;
-
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, NULL);
-
-       if (hwc_data->target_hwc_window == NULL) {
-               if (error)
-                       *error = TDM_ERROR_OPERATION_FAILED;
-               return NULL;
-       }
-
-       tqueue = _exynos_hwc_window_get_tbm_buffer_queue(hwc_data->target_hwc_window, error);
-       RETURN_VAL_IF_FAIL(tqueue, NULL);
-
-       if (error)
-               *error = TDM_ERROR_NONE;
-
-       return tqueue;
-}
-
-tdm_error
-exynos_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer,
-                                                                       tdm_region damage)
-{
-       tdm_exynos_hwc_data *hwc_data = hwc;
-       tdm_error err;
-
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window  != NULL, TDM_ERROR_OPERATION_FAILED);
-
-       err = exynos_hwc_window_set_buffer(hwc_data->target_hwc_window, buffer);
-       RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
-
-       err = exynos_hwc_window_set_buffer_damage(hwc_data->target_hwc_window, damage);
-       RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds,    uint32_t num_wnds, uint32_t *num_types)
-{
-       tdm_exynos_hwc_data *hwc_data = hwc;
-
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       _exynos_hwc_adapt_policy(hwc_data, composited_wnds, num_wnds);
-
-       TDM_DBG(" ==============Validate=================================");
-       *num_types = _exynos_hwc_get_changed_number(hwc_data);
-       if (*num_types == 0) {
-               hwc_data->need_validate = 0;
-               _exynos_hwc_assigned_layer_zpos_update(hwc_data);
-               _print_validate_result(hwc_data);
-       } else {
-               _print_validate_result(hwc_data);
-               TDM_DBG(" !!!!!!! BUT NEED TO ACCEPT CHANES.!!!!!!!!");
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements, tdm_hwc_window **hwc_wnds,
-                                                                       tdm_hwc_window_composition *composition_types)
-{
-       tdm_exynos_hwc_data *hwc_data = hwc;
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-       int num = 0;
-
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(num_elements != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       if ((hwc_wnds == NULL) || (composition_types == NULL)) {
-               *num_elements = _exynos_hwc_get_changed_number(hwc_data);
-               return TDM_ERROR_NONE;
-       }
-
-       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
-               if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE)
-                       continue;
-
-               if (num >= *num_elements)
-                       break;
-
-               if (hwc_window_data->client_type != hwc_window_data->validated_type) {
-                       composition_types[num] = hwc_window_data->validated_type;
-                       hwc_wnds[num] = hwc_window_data;
-                       num++;
-               }
-       }
-
-       /* set real num of changed composition types */
-       *num_elements = num;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_hwc_accept_validation(tdm_hwc *hwc)
-{
-       tdm_exynos_hwc_data *hwc_data = hwc;
-
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       TDM_DBG(" ==============Accept Changes Done=================================");
-
-       _exynos_hwc_assigned_layer_zpos_update(hwc_data);
-       hwc_data->need_validate = 0;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_hwc_commit(tdm_hwc *hwc, int sync, void *user_data)
-{
-       tdm_exynos_hwc_data *hwc_data = hwc;
-       tdm_exynos_output_data *output_data = NULL;
-       tdm_error ret;
-
-       RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
-
-       output_data = hwc_data->output_data;
-
-       ret = _exynos_hwc_prepare_commit(hwc_data);
-       RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
-
-       ret = exynos_output_commit(output_data, sync, user_data);
-       RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func)
-{
-       tdm_exynos_hwc_data *hwc_data = hwc;
-
-       RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
-
-       hwc_data->commit_func = func;
-
-       return TDM_ERROR_NONE;
-}
\ No newline at end of file
diff --git a/src/tdm_exynos_hwc.h b/src/tdm_exynos_hwc.h
deleted file mode 100644 (file)
index f14053c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _TDM_EXYNOS_HWC_H_
-#define _TDM_EXYNOS_HWC_H_
-
-#include "tdm_exynos.h"
-
-tdm_error exynos_hwc_initailize_target_window(tdm_exynos_hwc_data *hwc_data, int width, int height);
-
-#endif /* _TDM_EXYNOS_HWC_H_ */
diff --git a/src/tdm_exynos_hwc_window.c b/src/tdm_exynos_hwc_window.c
deleted file mode 100644 (file)
index 23b352a..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_exynos.h"
-
-tdm_exynos_layer_data *
-_exynos_output_get_layer(tdm_exynos_output_data *output_data, int index);
-
-void
-exynos_hwc_window_destroy(tdm_hwc_window *hwc_window)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
-
-       RETURN_IF_FAIL(hwc_window_data != NULL);
-
-       LIST_DEL(&hwc_window_data->link);
-
-       free(hwc_window_data);
-}
-
-tdm_error
-exynos_hwc_window_set_composition_type(tdm_hwc_window *hwc_window,
-                                                                       tdm_hwc_window_composition comp_type)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
-       tdm_exynos_hwc_data *hwc_data = hwc_window_data->hwc_data;
-
-       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       /* change the client_type when it is different from one which has before */
-       if (hwc_window_data->client_type == comp_type)
-               return TDM_ERROR_NONE;
-
-       hwc_window_data->client_type = comp_type;
-
-       /* if the type is none, reset all status */
-       if (hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_NONE) {
-               hwc_window_data->client_type = TDM_HWC_WIN_COMPOSITION_NONE;
-               hwc_window_data->validated_type = -1;
-               hwc_window_data->candidate_layer_zpos = -1;
-               hwc_window_data->assigned_layer_zpos = -1;
-       }
-
-       hwc_data->need_validate = 1;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
-       tdm_exynos_hwc_data *hwc_data = hwc_window_data->hwc_data;
-
-       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       /* TODO:: */
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
-       tdm_exynos_hwc_data *hwc_data;
-
-       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       hwc_data = hwc_window_data->hwc_data;
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       if (!memcmp(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info)))
-               return TDM_ERROR_NONE;
-
-       hwc_window_data->info = *info;
-       hwc_data->need_validate = 1;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
-       tdm_error err = TDM_ERROR_OPERATION_FAILED;
-
-       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, err);
-
-       if (hwc_window_data->surface == surface)
-               return TDM_ERROR_NONE;
-
-       hwc_window_data->surface = surface;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
-
-       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-#if 0
-       output_data = hwc_window_data->output_data;
-       RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       layer_data = _exynos_output_get_layer(output_data, hwc_window_data->assigned_layer_zpos);
-
-       return exynos_layer_set_property(layer_data, id, value);
-#endif
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
-
-       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-#if 0
-       output_data = hwc_window_data->output_data;
-       RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       layer_data = _exynos_output_get_layer(output_data, hwc_window_data->assigned_layer_zpos);
-
-       return exynos_layer_get_property(layer_data, id, value);
-#endif
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_hwc_window_get_constraints(tdm_hwc_window *hwc_window, int *constraints)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
-
-       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       return TDM_ERROR_NONE;
-}
diff --git a/src/tdm_exynos_hwc_window.h b/src/tdm_exynos_hwc_window.h
deleted file mode 100644 (file)
index 4237eb7..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _TDM_EXYNOS_HWC_WINDOW_H_
-#define _TDM_EXYNOS_HWC_WINDOW_H_
-
-#include "tdm_exynos.h"
-
-#endif /* _TDM_EXYNOS_HWC_WINDOW_H_ */
diff --git a/src/tdm_exynos_layer.c b/src/tdm_exynos_layer.c
deleted file mode 100644 (file)
index cb326e4..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <drm_fourcc.h>
-#include <tdm_helper.h>
-#include "tdm_exynos.h"
-
-static int tdm_exynos_buffer_key;
-#define TDM_EXYNOS_BUFFER_KEY ((unsigned long)&tdm_exynos_buffer_key)
-
-static void
-_tdm_exynos_display_buffer_destroy(void *user_data)
-{
-       tdm_exynos_display_buffer *display_buffer = (tdm_exynos_display_buffer *)user_data;
-
-       if (display_buffer->fb_id > 0) {
-               int ret = drmModeRmFB(display_buffer->exynos_data->drm_fd, display_buffer->fb_id);
-               if (ret < 0) {
-                       TDM_ERR("rm fb failed");
-                       return;
-               }
-               TDM_DBG("drmModeRmFB success!!! fb_id:%d", display_buffer->fb_id);
-       } else
-               TDM_DBG("drmModeRmFB not called fb_id:%d", display_buffer->fb_id);
-
-       free(display_buffer);
-}
-
-static tdm_exynos_display_buffer *
-_tdm_exynos_display_get_buffer(tdm_exynos_data *exynos_data, tbm_surface_h buffer)
-{
-       tdm_exynos_display_buffer *display_buffer = NULL;
-
-       if (!tbm_surface_internal_get_user_data(buffer, TDM_EXYNOS_BUFFER_KEY, (void **)&display_buffer)) {
-               unsigned int width;
-               unsigned int height;
-               unsigned int format;
-               unsigned int handles[4] = {0,};
-               unsigned int pitches[4] = {0,};
-               unsigned int offsets[4] = {0,};
-               unsigned int size;
-               tbm_bo bo;
-               int i, count, ret;
-
-               display_buffer = calloc(1, sizeof(tdm_exynos_display_buffer));
-               RETURN_VAL_IF_FAIL(display_buffer != NULL, NULL);
-
-               if (!tbm_surface_internal_add_user_data(buffer, TDM_EXYNOS_BUFFER_KEY, _tdm_exynos_display_buffer_destroy)) {
-                       TDM_ERR("FAIL to create user_data for surface %p", buffer);
-                       free(display_buffer);
-                       return NULL;
-               }
-               if (!tbm_surface_internal_set_user_data(buffer, TDM_EXYNOS_BUFFER_KEY, display_buffer)) {
-                       TDM_ERR("FAIL to set user_data for surface %p", buffer);
-                       tbm_surface_internal_delete_user_data(buffer, TDM_EXYNOS_BUFFER_KEY);
-                       free(display_buffer);
-                       return NULL;
-               }
-
-               display_buffer->exynos_data = exynos_data;
-               display_buffer->buffer = buffer;
-
-               width = tbm_surface_get_width(buffer);
-               height = tbm_surface_get_height(buffer);
-               format = tbm_surface_get_format(buffer);
-               count = tbm_surface_internal_get_num_planes(format);
-               bo = tbm_surface_internal_get_bo(buffer, 0);
-               handles[0] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
-               for (i = 1; i < count; i++)
-                       handles[i] = handles[0];
-
-               for (i = 0; i < count; i++)
-                       tbm_surface_internal_get_plane_data(buffer, i, &size, &offsets[i], &pitches[i]);
-
-               ret = drmModeAddFB2(exynos_data->drm_fd, width, height, format,
-                                                       handles, pitches, offsets, &display_buffer->fb_id, 0);
-               if (ret < 0) {
-                       TDM_ERR("add fb failed: %m");
-                       free(display_buffer);
-                       return NULL;
-               }
-               TDM_DBG("exynos_data->drm_fd : %d, display_buffer->fb_id:%u", exynos_data->drm_fd,
-                               display_buffer->fb_id);
-
-               if (IS_RGB(format))
-                       display_buffer->width = pitches[0] >> 2;
-               else
-                       display_buffer->width = pitches[0];
-       }
-
-       return display_buffer;
-}
-
-tdm_error
-exynos_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps)
-{
-       tdm_exynos_layer_data *layer_data = layer;
-       tdm_exynos_data *exynos_data;
-       drmModePlanePtr plane = NULL;
-       drmModeObjectPropertiesPtr props = NULL;
-       int i, fmt_count;
-       tdm_error ret;
-
-       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
-
-       memset(caps, 0, sizeof(tdm_caps_layer));
-
-       exynos_data = layer_data->exynos_data;
-       plane = drmModeGetPlane(exynos_data->drm_fd, layer_data->plane_id);
-       if (!plane) {
-               TDM_ERR("get plane failed: %m");
-               ret = TDM_ERROR_OPERATION_FAILED;
-               goto failed_get;
-       }
-
-       caps->capabilities = layer_data->capabilities;
-       caps->zpos = layer_data->zpos;  /* if VIDEO layer, zpos is -1 */
-
-       caps->formats = calloc(1, sizeof(tbm_format) * plane->count_formats);
-       if (!caps->formats) {
-               ret = TDM_ERROR_OUT_OF_MEMORY;
-               TDM_ERR("alloc failed\n");
-               goto failed_get;
-       }
-
-       fmt_count = 0;
-       for (i = 0; i < plane->count_formats; i++) {
-               /* TODO: kernel reports wrong formats */
-               if (plane->formats[i] != DRM_FORMAT_XRGB8888 &&
-                   plane->formats[i] != DRM_FORMAT_ARGB8888)
-                       continue;
-               caps->formats[fmt_count] = tdm_exynos_format_to_tbm_format(plane->formats[i]);
-               fmt_count++;
-       }
-       caps->format_count = fmt_count;
-
-       props = drmModeObjectGetProperties(exynos_data->drm_fd, layer_data->plane_id,
-                                                                          DRM_MODE_OBJECT_PLANE);
-       if (!props) {
-               ret = TDM_ERROR_OPERATION_FAILED;
-               TDM_ERR("get plane properties failed: %m\n");
-               goto failed_get;
-       }
-
-       caps->props = calloc(1, sizeof(tdm_prop) * props->count_props);
-       if (!caps->props) {
-               ret = TDM_ERROR_OUT_OF_MEMORY;
-               TDM_ERR("alloc failed\n");
-               goto failed_get;
-       }
-
-       caps->prop_count = 0;
-       for (i = 0; i < props->count_props; i++) {
-               drmModePropertyPtr prop = drmModeGetProperty(exynos_data->drm_fd,
-                                                                                                        props->props[i]);
-               if (!prop)
-                       continue;
-               if (!strncmp(prop->name, "type", TDM_NAME_LEN)) {
-                       drmModeFreeProperty(prop);
-                       continue;
-               }
-               if (!strncmp(prop->name, "zpos", TDM_NAME_LEN)) {
-                       drmModeFreeProperty(prop);
-                       continue;
-               }
-               snprintf(caps->props[caps->prop_count].name, TDM_NAME_LEN, "%s", prop->name);
-               caps->props[caps->prop_count].id = props->props[i];
-               caps->prop_count++;
-               drmModeFreeProperty(prop);
-       }
-
-       drmModeFreeObjectProperties(props);
-       drmModeFreePlane(plane);
-
-       return TDM_ERROR_NONE;
-failed_get:
-       drmModeFreeObjectProperties(props);
-       drmModeFreePlane(plane);
-       free(caps->formats);
-       free(caps->props);
-       memset(caps, 0, sizeof(tdm_caps_layer));
-       return ret;
-}
-
-tdm_error
-exynos_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
-{
-       tdm_exynos_layer_data *layer_data = layer;
-       tdm_exynos_data *exynos_data;
-       int ret;
-
-       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(layer_data->plane_id > 0, TDM_ERROR_INVALID_PARAMETER);
-
-       exynos_data = layer_data->exynos_data;
-       ret = drmModeObjectSetProperty(exynos_data->drm_fd,
-                                                                  layer_data->plane_id, DRM_MODE_OBJECT_PLANE,
-                                                                  id, value.u32);
-       if (ret < 0) {
-               TDM_ERR("set property failed: %m");
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
-{
-       tdm_exynos_layer_data *layer_data = layer;
-       tdm_exynos_data *exynos_data;
-       drmModeObjectPropertiesPtr props;
-       tdm_error ret = TDM_ERROR_INVALID_PARAMETER;
-       int i;
-
-       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(layer_data->plane_id > 0, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(value, TDM_ERROR_INVALID_PARAMETER);
-
-       exynos_data = layer_data->exynos_data;
-       props = drmModeObjectGetProperties(exynos_data->drm_fd, layer_data->plane_id,
-                                                                          DRM_MODE_OBJECT_PLANE);
-       if (props == NULL) {
-               TDM_ERR("get property failed: %m");
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       for (i = 0; i < props->count_props; i++)
-               if (props->props[i] == id) {
-                       (*value).u32 = (uint)props->prop_values[i];
-                       ret = TDM_ERROR_NONE;
-                       break;
-               }
-
-       drmModeFreeObjectProperties(props);
-
-       if (ret != TDM_ERROR_NONE)
-               TDM_ERR("unknown property id: %ud", id);
-
-       return ret;
-}
-
-tdm_error
-exynos_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
-{
-       tdm_exynos_layer_data *layer_data = layer;
-
-       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
-
-       layer_data->info = *info;
-       layer_data->info_changed = 1;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
-{
-       tdm_exynos_layer_data *layer_data = layer;
-
-       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
-
-       *info = layer_data->info;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
-{
-       tdm_exynos_layer_data *layer_data = layer;
-       tdm_exynos_data *exynos_data;
-       tdm_exynos_display_buffer *display_buffer;
-
-       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(buffer, TDM_ERROR_INVALID_PARAMETER);
-
-       exynos_data = layer_data->exynos_data;
-
-       display_buffer = _tdm_exynos_display_get_buffer(exynos_data, buffer);
-       if (!display_buffer) {
-               TDM_ERR("alloc failed");
-               return TDM_ERROR_OUT_OF_MEMORY;
-       }
-
-       if (layer_data->display_buffer)
-               tbm_surface_internal_unref(layer_data->display_buffer->buffer);
-
-       layer_data->display_buffer = display_buffer;
-       tbm_surface_internal_ref(layer_data->display_buffer->buffer);
-
-       layer_data->display_buffer_changed = 1;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_layer_unset_buffer(tdm_layer *layer)
-{
-       tdm_exynos_layer_data *layer_data = layer;
-
-       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
-
-       if (layer_data->display_buffer &&
-               (!(layer_data->capabilities & TDM_LAYER_CAPABILITY_PRIMARY) || layer_data->display_buffer_force_unset)) {
-               layer_data->display_buffer_force_unset = 0;
-               tbm_surface_internal_unref(layer_data->display_buffer->buffer);
-               layer_data->display_buffer = NULL;
-       }
-       layer_data->display_buffer_changed = 1;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-tdm_exynos_layer_get_supported_format(tdm_layer *layer, const tbm_format **out_formats,
-                                                                         int *out_format_count)
-{
-       tdm_exynos_layer_data *layer_data = layer;
-       tdm_exynos_data *exynos_data;
-       drmModePlanePtr plane = NULL;
-       int i, j;
-       tdm_error ret;
-       tbm_format *formats = NULL;
-       int format_count = 0;
-
-       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(out_formats, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(out_format_count, TDM_ERROR_INVALID_PARAMETER);
-
-       if (layer_data->formats) {
-               *out_formats = layer_data->formats;
-               *out_format_count = layer_data->format_count;
-
-               return TDM_ERROR_NONE;
-       }
-
-       exynos_data = layer_data->exynos_data;
-       plane = drmModeGetPlane(exynos_data->drm_fd, layer_data->plane_id);
-       if (!plane) {
-               TDM_ERR("get plane failed: %m");
-               ret = TDM_ERROR_OPERATION_FAILED;
-               goto failed_get;
-       }
-
-       for (i = 0; i < plane->count_formats; i++) {
-               /* TODO: kernel reports wrong formats */
-               if (plane->formats[i] != DRM_FORMAT_XRGB8888 &&
-                   plane->formats[i] != DRM_FORMAT_ARGB8888)
-                       continue;
-               format_count++;
-       }
-
-       formats = calloc(1, sizeof(tbm_format) * format_count);
-       if (!formats) {
-               ret = TDM_ERROR_OUT_OF_MEMORY;
-               TDM_ERR("alloc failed\n");
-               goto failed_get;
-       }
-
-       for (i = 0, j = 0; j < plane->count_formats; j++) {
-               /* TODO: kernel reports wrong formats */
-               if (plane->formats[j] != DRM_FORMAT_XRGB8888 &&
-                   plane->formats[j] != DRM_FORMAT_ARGB8888)
-                       continue;
-               formats[i++] = tdm_exynos_format_to_tbm_format(plane->formats[j]);
-       }
-
-       drmModeFreePlane(plane);
-
-       layer_data->formats = formats;
-       layer_data->format_count = format_count;
-
-       *out_formats = layer_data->formats;
-       *out_format_count = layer_data->format_count;
-
-       return TDM_ERROR_NONE;
-failed_get:
-       drmModeFreePlane(plane);
-       free(formats);
-       *out_formats = NULL;
-       *out_format_count = 0;
-       return ret;
-}
-
-tdm_error
-exynos_layer_get_available_properties(tdm_layer *layer, const tdm_prop **out_props,
-                                                                         int *out_prop_count)
-{
-       tdm_exynos_layer_data *layer_data = layer;
-       tdm_exynos_data *exynos_data;
-       drmModePlanePtr plane = NULL;
-       drmModeObjectPropertiesPtr props = NULL;
-       int i;
-       tdm_error ret;
-       tdm_prop *tdm_props = NULL;
-       int prop_count;
-
-       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(out_props, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(out_prop_count, TDM_ERROR_INVALID_PARAMETER);
-
-       if (layer_data->props) {
-               *out_props = layer_data->props;
-               *out_prop_count = layer_data->prop_count;
-
-               return TDM_ERROR_NONE;
-       }
-
-       exynos_data = layer_data->exynos_data;
-       plane = drmModeGetPlane(exynos_data->drm_fd, layer_data->plane_id);
-       if (!plane) {
-               TDM_ERR("get plane failed: %m");
-               ret = TDM_ERROR_OPERATION_FAILED;
-               goto failed_get;
-       }
-
-       props = drmModeObjectGetProperties(exynos_data->drm_fd, layer_data->plane_id,
-                                                                          DRM_MODE_OBJECT_PLANE);
-       if (!props) {
-               ret = TDM_ERROR_OPERATION_FAILED;
-               TDM_ERR("get plane properties failed: %m\n");
-               goto failed_get;
-       }
-
-       tdm_props = calloc(1, sizeof(tdm_prop) * props->count_props);
-       if (!tdm_props) {
-               ret = TDM_ERROR_OUT_OF_MEMORY;
-               TDM_ERR("alloc failed\n");
-               goto failed_get;
-       }
-
-       prop_count = 0;
-       for (i = 0; i < props->count_props; i++) {
-               drmModePropertyPtr prop = drmModeGetProperty(exynos_data->drm_fd,
-                                                                                                        props->props[i]);
-               if (!prop)
-                       continue;
-               if (!strncmp(prop->name, "type", TDM_NAME_LEN)) {
-                       drmModeFreeProperty(prop);
-                       continue;
-               }
-               if (!strncmp(prop->name, "zpos", TDM_NAME_LEN)) {
-                       drmModeFreeProperty(prop);
-                       continue;
-               }
-               snprintf(tdm_props[prop_count].name, TDM_NAME_LEN, "%s", prop->name);
-               tdm_props[prop_count].id = props->props[i];
-               prop_count++;
-               drmModeFreeProperty(prop);
-       }
-
-       drmModeFreeObjectProperties(props);
-       drmModeFreePlane(plane);
-
-       layer_data->props = tdm_props;
-       layer_data->prop_count = prop_count;
-
-       *out_props = layer_data->props;
-       *out_prop_count = layer_data->prop_count;
-
-       return TDM_ERROR_NONE;
-failed_get:
-       drmModeFreeObjectProperties(props);
-       drmModeFreePlane(plane);
-       *out_props = NULL;
-       *out_prop_count = 0;
-
-       return ret;
-}
diff --git a/src/tdm_exynos_layer.h b/src/tdm_exynos_layer.h
deleted file mode 100644 (file)
index cad66b4..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _TDM_EXYNOS_LAYER_H_
-#define _TDM_EXYNOS_LAYER_H_
-
-#include "tdm_exynos.h"
-
-tdm_error
-tdm_exynos_layer_get_supported_format(tdm_layer *layer, const tbm_format **out_formats,
-                                                                         int *out_format_count);
-tdm_error
-exynos_layer_get_available_properties(tdm_layer *layer, const tdm_prop **out_props,
-                                                                         int *out_prop_count);
-
-#endif /* _TDM_EXYNOS_LAYER_H_ */
diff --git a/src/tdm_exynos_output.c b/src/tdm_exynos_output.c
deleted file mode 100644 (file)
index acf2a42..0000000
+++ /dev/null
@@ -1,1085 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <drm_fourcc.h>
-#include <tdm_helper.h>
-#include "tdm_exynos.h"
-
-#define MIN_WIDTH   32
-
-#define LIST_INSERT_AFTER(__after, __item) \
-               (__item)->prev = (__after); \
-               (__item)->next = (__after)->next; \
-               (__after)->next->prev = (__item); \
-               (__after)->next = (__item);
-
-static tdm_error
-check_hw_restriction_crtc(unsigned int crtc_w,
-                                                         unsigned int buf_w, unsigned int buf_h,
-                                                         unsigned int src_x, unsigned int src_y,
-                                                         unsigned int src_w, unsigned int src_h,
-                                                         unsigned int dst_w, unsigned int dst_h,
-                                                         unsigned int *new_x, unsigned int *new_y)
-{
-       int tmp;
-       int dx = 1, dy = 1;
-       int changed_x = 0;
-       int changed_y = 0;
-
-       (void) crtc_w;
-       (void) dst_w;
-       (void) dst_h;
-
-       *new_x = src_x;
-       *new_y = src_y;
-
-       if (src_x + src_w > buf_w) {
-               tmp = src_x;
-               while (tmp + src_w != buf_w)
-                       tmp -= dx;
-
-               changed_x = 1;
-               *new_x = tmp;
-       }
-
-       if (src_y + src_h > buf_h) {
-               tmp = src_y;
-               while (tmp + src_h != buf_h)
-                       tmp -= dy;
-
-               changed_y = 1;
-               *new_y = tmp;
-       }
-
-       if (changed_x == 1 || changed_y == 1)
-               return TDM_ERROR_INVALID_PARAMETER;
-       return TDM_ERROR_NONE;
-}
-
-static tdm_error
-check_hw_restriction(unsigned int crtc_w, unsigned int crtc_h, unsigned int buf_w,
-                                               unsigned int src_x, unsigned int src_w,
-                                               unsigned int dst_x, unsigned int dst_y, unsigned int dst_w,
-                                               unsigned int *new_src_x, unsigned int *new_src_w,
-                                               unsigned int *new_dst_x, unsigned int *new_dst_w)
-{
-       int start, end, diff;
-       int virtual_screen;
-
-       *new_src_x = src_x;
-       *new_src_w = src_w;
-       *new_dst_x = dst_x;
-       *new_dst_w = dst_w;
-
-       if (buf_w < MIN_WIDTH || buf_w % 2) {
-               TDM_ERR("buf_w(%u) not 2's multiple or less than %u", buf_w, MIN_WIDTH);
-               return TDM_ERROR_BAD_REQUEST;
-       }
-
-       if (dst_x > crtc_w || dst_y > crtc_h) {
-               TDM_ERR("dst_pos(%u,%u) is out of crtc(%ux%u)", dst_x, dst_y, crtc_w, crtc_h);
-               return TDM_ERROR_BAD_REQUEST;
-       }
-
-       if (src_x > dst_x || ((dst_x - src_x) + buf_w) > crtc_w)
-               virtual_screen = 1;
-       else
-               virtual_screen = 0;
-
-       start = dst_x;
-       end = ((dst_x + dst_w) > crtc_w) ? crtc_w : (dst_x + dst_w);
-
-       /* check window minimun width */
-       if ((end - start) < MIN_WIDTH) {
-               TDM_ERR("visible_w(%d) less than %u", end - start, MIN_WIDTH);
-               return TDM_ERROR_BAD_REQUEST;
-       }
-
-       if (!virtual_screen) {
-               /* Pagewidth of window (= 8 byte align / bytes-per-pixel ) */
-               if ((end - start) % 2)
-                       end--;
-       } else {
-               /* You should align the sum of PAGEWIDTH_F and OFFSIZE_F double-word (8 byte) boundary. */
-               if (end % 2)
-                       end--;
-       }
-
-       *new_dst_x = start;
-       *new_dst_w = end - start;
-       *new_src_w = *new_dst_w;
-       diff = start - dst_x;
-       *new_src_x += diff;
-
-       RETURN_VAL_IF_FAIL(*new_src_w > 0, TDM_ERROR_BAD_REQUEST);
-       RETURN_VAL_IF_FAIL(*new_dst_w > 0, TDM_ERROR_BAD_REQUEST);
-
-       if (src_x != *new_src_x || src_w != *new_src_w || dst_x != *new_dst_x ||
-           dst_w != *new_dst_w)
-               TDM_DBG("=> buf_w(%d) src(%d,%d) dst(%d,%d), virt(%d) start(%d) end(%d)",
-                               buf_w, *new_src_x, *new_src_w, *new_dst_x, *new_dst_w, virtual_screen, start,
-                               end);
-
-       return TDM_ERROR_NONE;
-}
-
-static drmModeModeInfoPtr
-_tdm_exynos_output_get_mode(tdm_exynos_output_data *output_data)
-{
-       int i;
-
-       if (!output_data->current_mode) {
-               TDM_ERR("no output_data->current_mode");
-               return NULL;
-       }
-
-       for (i = 0; i < output_data->count_modes; i++) {
-               drmModeModeInfoPtr drm_mode = &output_data->drm_modes[i];
-               if (exynos_screen_prerotation_hint % 180) {
-                       if ((drm_mode->hdisplay == output_data->current_mode->vdisplay) &&
-                           (drm_mode->vdisplay == output_data->current_mode->hdisplay) &&
-                           (drm_mode->vrefresh == output_data->current_mode->vrefresh) &&
-                           (drm_mode->flags == output_data->current_mode->flags) &&
-                           (drm_mode->type == output_data->current_mode->type) &&
-                           !(strncmp(drm_mode->name, output_data->current_mode->name, TDM_NAME_LEN)))
-                               return drm_mode;
-               } else {
-                       if ((drm_mode->hdisplay == output_data->current_mode->hdisplay) &&
-                           (drm_mode->vdisplay == output_data->current_mode->vdisplay) &&
-                           (drm_mode->vrefresh == output_data->current_mode->vrefresh) &&
-                           (drm_mode->flags == output_data->current_mode->flags) &&
-                           (drm_mode->type == output_data->current_mode->type) &&
-                           !(strncmp(drm_mode->name, output_data->current_mode->name, TDM_NAME_LEN)))
-                               return drm_mode;
-               }
-       }
-
-       return NULL;
-}
-
-static tdm_error
-_tdm_exynos_output_get_cur_msc(int fd, int pipe, uint *msc)
-{
-       drmVBlank vbl;
-
-       vbl.request.type = DRM_VBLANK_RELATIVE;
-       if (pipe == 1)
-               vbl.request.type |= DRM_VBLANK_SECONDARY;
-       else if (pipe > 1)
-               vbl.request.type |= pipe << DRM_VBLANK_HIGH_CRTC_SHIFT;
-
-       vbl.request.sequence = 0;
-       if (drmWaitVBlank(fd, &vbl)) {
-               TDM_ERR("get vblank counter failed: %m");
-               *msc = 0;
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       *msc = vbl.reply.sequence;
-
-       return TDM_ERROR_NONE;
-}
-
-static tdm_error
-_tdm_exynos_output_wait_vblank(int fd, int pipe, uint *target_msc, void *data)
-{
-       drmVBlank vbl;
-
-       vbl.request.type =  DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
-       if (pipe == 1)
-               vbl.request.type |= DRM_VBLANK_SECONDARY;
-       else if (pipe > 1)
-               vbl.request.type |= pipe << DRM_VBLANK_HIGH_CRTC_SHIFT;
-
-       vbl.request.sequence = *target_msc;
-       vbl.request.signal = (unsigned long)(uintptr_t)data;
-
-       if (drmWaitVBlank(fd, &vbl)) {
-               TDM_ERR("wait vblank failed: %m");
-               *target_msc = 0;
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       *target_msc = vbl.reply.sequence;
-
-       return TDM_ERROR_NONE;
-}
-
-static void
-_tdm_exynos_output_transform_layer_info(int width, int height, tdm_info_layer *info)
-{
-       tdm_pos dst_pos;
-
-       switch (exynos_screen_prerotation_hint) {
-       case 90:
-               dst_pos.x = info->dst_pos.y;
-               dst_pos.y = width - info->dst_pos.x - info->dst_pos.w;
-               dst_pos.w = info->dst_pos.h;
-               dst_pos.h = info->dst_pos.w;
-               break;
-       case 180:
-               dst_pos.x = width - info->dst_pos.x - info->dst_pos.w;
-               dst_pos.y = height - info->dst_pos.y - info->dst_pos.h;
-               dst_pos.w = info->dst_pos.w;
-               dst_pos.h = info->dst_pos.h;
-               break;
-       case 270:
-               dst_pos.x = height - info->dst_pos.y - info->dst_pos.h;
-               dst_pos.y = info->dst_pos.x;
-               dst_pos.w = info->dst_pos.h;
-               dst_pos.h = info->dst_pos.w;
-               break;
-       default:
-               return;
-       }
-
-       info->dst_pos = dst_pos;
-}
-
-static tdm_error
-_tdm_exynos_output_commit_primary_layer(tdm_exynos_layer_data *layer_data,
-                                                                                                 void *user_data, int *do_waitvblank)
-{
-       tdm_exynos_data *exynos_data = layer_data->exynos_data;
-       tdm_exynos_output_data *output_data = layer_data->output_data;
-       unsigned int new_x = -1, new_y = -1;
-       uint32_t fx, fy;
-       int crtc_w, crtc_h;
-
-       if (output_data->mode_changed && layer_data->display_buffer_changed) {
-               tdm_info_layer layer_info = layer_data->info;
-               drmModeModeInfoPtr mode;
-
-               if (!layer_data->display_buffer) {
-                       TDM_ERR("primary layer should have a buffer for modestting");
-                       return TDM_ERROR_BAD_REQUEST;
-               }
-
-               if (output_data->current_mode) {
-                       crtc_w = output_data->current_mode->hdisplay;
-                       crtc_h = output_data->current_mode->vdisplay;
-               } else {
-                       drmModeCrtcPtr crtc = drmModeGetCrtc(exynos_data->drm_fd, output_data->crtc_id);
-                       if (!crtc) {
-                               TDM_ERR("getting crtc failed");
-                               return TDM_ERROR_OPERATION_FAILED;
-                       }
-                       crtc_w = crtc->width;
-                       crtc_h = crtc->height;
-                       if (crtc_w == 0) {
-                               TDM_ERR("getting crtc width failed");
-                               drmModeFreeCrtc(crtc);
-                               return TDM_ERROR_OPERATION_FAILED;
-                       }
-                       drmModeFreeCrtc(crtc);
-               }
-
-               output_data->mode_changed = 0;
-               layer_data->display_buffer_changed = 0;
-               layer_data->info_changed = 0;
-
-               mode = _tdm_exynos_output_get_mode(output_data);
-               if (!mode) {
-                       TDM_ERR("couldn't find proper mode");
-                       return TDM_ERROR_BAD_REQUEST;
-               }
-
-               _tdm_exynos_output_transform_layer_info(crtc_w, crtc_h, &layer_info);
-
-               if (check_hw_restriction_crtc(crtc_w,
-                                                                         layer_info.src_config.size.h, layer_info.src_config.size.v,
-                                                                         layer_info.src_config.pos.x, layer_info.src_config.pos.y,
-                                                                         layer_info.src_config.pos.w, layer_info.src_config.pos.h,
-                                                                         layer_info.dst_pos.w, layer_info.dst_pos.h,
-                                                                         &new_x, &new_y) != TDM_ERROR_NONE)
-               TDM_WRN("not going to set crtc(%u)", output_data->crtc_id);
-
-               if (layer_info.src_config.pos.x != new_x)
-                       TDM_DBG("src_x changed: %u => %u", layer_info.src_config.pos.x,
-                                       new_x);
-               if (layer_info.src_config.pos.y != new_y)
-                       TDM_DBG("src_y changed: %u => %u", layer_info.src_config.pos.y,
-                                       new_y);
-
-               fx = (unsigned int)new_x;
-               fy = (unsigned int)new_y;
-
-               TDM_DBG("SetCrtc: drm_fd(%d) crtc_id(%u) fb_id(%u) mode(%ux%u, %uhz) pos(%u %u)",
-                               exynos_data->drm_fd, output_data->crtc_id, layer_data->display_buffer->fb_id,
-                               mode->hdisplay, mode->vdisplay, mode->vrefresh, fx, fy);
-
-               if (drmModeSetCrtc(exynos_data->drm_fd, output_data->crtc_id,
-                                                  layer_data->display_buffer->fb_id, fx, fy,
-                                                  &output_data->connector_id, 1, mode)) {
-                       TDM_ERR("set crtc failed: %m");
-                       return TDM_ERROR_OPERATION_FAILED;
-               }
-
-               tdm_exynos_output_update_status(output_data, TDM_OUTPUT_CONN_STATUS_MODE_SETTED);
-
-               *do_waitvblank = 1;
-
-               return TDM_ERROR_NONE;
-       } else if (layer_data->display_buffer_changed) {
-               layer_data->display_buffer_changed = 0;
-
-               if (layer_data->display_buffer) {
-                       tbm_surface_info_s info;
-                       int ret;
-                       tdm_exynos_event_data *event_data = calloc(1, sizeof(tdm_exynos_event_data));
-
-                       if (!event_data) {
-                               TDM_ERR("alloc failed");
-                               return TDM_ERROR_OUT_OF_MEMORY;
-                       }
-                       event_data->type = TDM_EXYNOS_EVENT_TYPE_PAGEFLIP;
-                       event_data->output_data = output_data;
-                       event_data->user_data = user_data;
-                       event_data->hwc_mode = exynos_data->hwc_mode;
-
-                       TDM_DBG("PageFlip: drm_fd(%d) crtc_id(%u) fb_id(%u)",
-                                       exynos_data->drm_fd, output_data->crtc_id,
-                                       layer_data->display_buffer->fb_id);
-
-                       ret = tbm_surface_map(layer_data->display_buffer->buffer, TBM_SURF_OPTION_READ, &info);
-                       if (ret == TBM_SURFACE_ERROR_NONE)
-                               tbm_surface_unmap(layer_data->display_buffer->buffer);
-
-                       if (drmModePageFlip(exynos_data->drm_fd, output_data->crtc_id,
-                                                               layer_data->display_buffer->fb_id, DRM_MODE_PAGE_FLIP_EVENT, event_data)) {
-                               TDM_ERR("pageflip failed: %m");
-                               free(event_data);
-                               return TDM_ERROR_OPERATION_FAILED;
-                       }
-                       *do_waitvblank = 0;
-               } else {
-                       /* to call a user commit handler whenever committed */
-                       *do_waitvblank = 1;
-               }
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-static tdm_error
-_tdm_exynos_output_commit_layer(tdm_exynos_layer_data *layer_data)
-{
-       tdm_exynos_data *exynos_data = layer_data->exynos_data;
-       tdm_exynos_output_data *output_data = layer_data->output_data;
-       unsigned int new_src_x, new_src_w;
-       unsigned int new_dst_x, new_dst_w;
-       uint32_t fx, fy, fw, fh;
-       int crtc_w, crtc_h;
-       tdm_info_layer layer_info = layer_data->info;
-
-       if (!layer_data->display_buffer_changed && !layer_data->info_changed)
-               return TDM_ERROR_NONE;
-
-       if (output_data->current_mode) {
-               crtc_w = output_data->current_mode->hdisplay;
-               crtc_h = output_data->current_mode->vdisplay;
-       } else {
-               drmModeCrtcPtr crtc = drmModeGetCrtc(exynos_data->drm_fd, output_data->crtc_id);
-               if (!crtc) {
-                       TDM_ERR("getting crtc failed");
-                       return TDM_ERROR_OPERATION_FAILED;
-               }
-               crtc_w = crtc->width;
-               crtc_h = crtc->height;
-               if (crtc_w == 0) {
-                       TDM_ERR("getting crtc width failed");
-                       drmModeFreeCrtc(crtc);
-                       return TDM_ERROR_OPERATION_FAILED;
-               }
-               drmModeFreeCrtc(crtc);
-       }
-
-       layer_data->display_buffer_changed = 0;
-       layer_data->info_changed = 0;
-
-       if (!layer_data->display_buffer) {
-               TDM_DBG("SetPlane: drm_fd(%d) plane_id(%u) crtc_id(%u) off",
-                               exynos_data->drm_fd, layer_data->plane_id, output_data->crtc_id);
-
-               if (drmModeSetPlane(exynos_data->drm_fd, layer_data->plane_id,
-                                                       output_data->crtc_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
-                       TDM_ERR("unset plane(%u) filed: %m", layer_data->plane_id);
-
-               return TDM_ERROR_NONE;
-       }
-
-               _tdm_exynos_output_transform_layer_info(crtc_w, crtc_h, &layer_info);
-
-       /* check hw restriction*/
-       if (check_hw_restriction(crtc_w, crtc_h, layer_data->display_buffer->width,
-                                                        layer_info.src_config.pos.x,
-                                                        layer_info.src_config.pos.w,
-                                                        layer_info.dst_pos.x,
-                                                        layer_info.dst_pos.y,
-                                                        layer_info.dst_pos.w,
-                                                        &new_src_x, &new_src_w, &new_dst_x, &new_dst_w) != TDM_ERROR_NONE) {
-               TDM_WRN("not going to set plane(%u)", layer_data->plane_id);
-               return TDM_ERROR_NONE;
-       }
-
-       if (layer_info.src_config.pos.x != new_src_x)
-               TDM_DBG("src_x changed: %u => %u", layer_info.src_config.pos.x, new_src_x);
-       if (layer_info.src_config.pos.w != new_src_w)
-               TDM_DBG("src_w changed: %u => %u", layer_info.src_config.pos.w, new_src_w);
-       if (layer_info.dst_pos.x != new_dst_x)
-               TDM_DBG("dst_x changed: %u => %u", layer_info.dst_pos.x, new_dst_x);
-       if (layer_info.dst_pos.w != new_dst_w)
-               TDM_DBG("dst_w changed: %u => %u", layer_info.dst_pos.w, new_dst_w);
-
-       /* Source values are 16.16 fixed point */
-       fx = ((unsigned int)new_src_x) << 16;
-       fy = ((unsigned int)layer_info.src_config.pos.y) << 16;
-       fw = ((unsigned int)new_src_w) << 16;
-       fh = ((unsigned int)layer_info.src_config.pos.h) << 16;
-
-       TDM_DBG("SetPlane: drm_fd(%d) plane_id(%u) zpos(%d) crtc_id(%u) fb_id(%u) src(%u,%u %ux%u) dst(%u,%u %ux%u)",
-                       exynos_data->drm_fd, layer_data->plane_id, layer_data->zpos,
-                       output_data->crtc_id, layer_data->display_buffer->fb_id,
-                       new_src_x, layer_info.src_config.pos.y,
-                       new_src_w, layer_info.src_config.pos.h,
-                       layer_info.dst_pos.x, layer_info.dst_pos.y,
-                       layer_info.dst_pos.w, layer_info.dst_pos.h);
-
-       if (drmModeSetPlane(exynos_data->drm_fd, layer_data->plane_id,
-                                               output_data->crtc_id, layer_data->display_buffer->fb_id, 0,
-                                               new_dst_x, layer_info.dst_pos.y,
-                                               new_dst_w, layer_info.dst_pos.h,
-                                               fx, fy, fw, fh) < 0) {
-               TDM_ERR("SetPlane: drm_fd(%d) plane_id(%u) zpos(%d) crtc_id(%u) fb_id(%u) src(%u,%u %ux%u) dst(%u,%u %ux%u) failed: %m",
-                               exynos_data->drm_fd, layer_data->plane_id, layer_data->zpos,
-                               output_data->crtc_id, layer_data->display_buffer->fb_id,
-                               new_src_x, layer_info.src_config.pos.y,
-                               new_src_w, layer_info.src_config.pos.h,
-                               layer_info.dst_pos.x, layer_info.dst_pos.y,
-                               layer_info.dst_pos.w, layer_info.dst_pos.h);
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-void
-tdm_exynos_output_cb_event(int fd, unsigned int sequence,
-                                                                 unsigned int tv_sec, unsigned int tv_usec,
-                                                                 void *user_data)
-{
-       tdm_exynos_event_data *event_data = user_data;
-       tdm_exynos_output_data *output_data;
-       tdm_exynos_hwc_data *hwc_data;
-
-       if (!event_data) {
-               TDM_ERR("no event data");
-               return;
-       }
-
-       output_data = event_data->output_data;
-       hwc_data = output_data->hwc_data;
-
-       switch (event_data->type) {
-       case TDM_EXYNOS_EVENT_TYPE_PAGEFLIP:
-       case TDM_EXYNOS_EVENT_TYPE_COMMIT:
-               if (event_data->hwc_mode && hwc_data) {
-                       if (hwc_data->commit_func)
-                               hwc_data->commit_func(hwc_data, sequence, tv_sec, tv_usec,
-                                                                         event_data->user_data);
-               } else {
-                       if (output_data->commit_func)
-                               output_data->commit_func(output_data, sequence, tv_sec, tv_usec,
-                                                                                event_data->user_data);
-               }
-               break;
-       case TDM_EXYNOS_EVENT_TYPE_WAIT:
-               if (output_data->vblank_func)
-                       output_data->vblank_func(output_data, sequence, tv_sec, tv_usec,
-                                                                        event_data->user_data);
-               break;
-       default:
-               break;
-       }
-
-       free(event_data);
-}
-
-tdm_error
-tdm_exynos_output_update_status(tdm_exynos_output_data *output_data,
-                                                                               tdm_output_conn_status status)
-{
-       tdm_exynos_layer_data *layer_data = NULL;
-
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-
-       if (output_data->status == status)
-               return TDM_ERROR_NONE;
-
-       output_data->status = status;
-
-       LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
-               if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) {
-                       if (layer_data->display_buffer)
-                               layer_data->display_buffer_force_unset = 1;
-               } else
-                       layer_data->display_buffer_force_unset = 0;
-       }
-
-       if (output_data->status_func)
-               output_data->status_func(output_data, status,
-                                                                output_data->status_user_data);
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_get_capability(tdm_output *output, tdm_caps_output *caps)
-{
-       tdm_exynos_output_data *output_data = output;
-       tdm_exynos_data *exynos_data;
-       drmModeConnectorPtr connector = NULL;
-       drmModeCrtcPtr crtc = NULL;
-       drmModeObjectPropertiesPtr props = NULL;
-       int i;
-       tdm_error ret;
-
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
-
-       memset(caps, 0, sizeof(tdm_caps_output));
-
-       exynos_data = output_data->exynos_data;
-
-       snprintf(caps->maker, TDM_NAME_LEN, "unknown");
-       snprintf(caps->model, TDM_NAME_LEN, "unknown");
-       snprintf(caps->name, TDM_NAME_LEN, "unknown");
-
-       caps->type = output_data->connector_type;
-       caps->type_id = output_data->connector_type_id;
-
-       connector = drmModeGetConnector(exynos_data->drm_fd, output_data->connector_id);
-       RETURN_VAL_IF_FAIL(connector, TDM_ERROR_OPERATION_FAILED);
-
-       caps->mode_count = connector->count_modes;
-       caps->modes = calloc(1, sizeof(tdm_output_mode) * caps->mode_count);
-       if (!caps->modes) {
-               ret = TDM_ERROR_OUT_OF_MEMORY;
-               TDM_ERR("alloc failed\n");
-               goto failed_get;
-       }
-       if (caps->mode_count != output_data->count_modes) {
-               drmModeModeInfoPtr new_drm_modes;
-               tdm_output_mode *new_output_modes;
-
-               new_drm_modes = calloc(connector->count_modes,
-                                               sizeof(drmModeModeInfo));
-               if (!new_drm_modes) {
-                       ret = TDM_ERROR_OUT_OF_MEMORY;
-                       TDM_ERR("alloc failed drm_modes\n");
-                       goto failed_get;
-               }
-               new_output_modes = calloc(connector->count_modes,
-                                               sizeof(tdm_output_mode));
-               if (!new_output_modes) {
-                       ret = TDM_ERROR_OUT_OF_MEMORY;
-                       TDM_ERR("alloc failed output_modes\n");
-                       free(new_drm_modes);
-                       goto failed_get;
-               }
-               free(output_data->drm_modes);
-               free(output_data->output_modes);
-
-               output_data->drm_modes = new_drm_modes;
-               output_data->output_modes = new_output_modes;
-               output_data->count_modes = caps->mode_count;
-       }
-       for (i = 0; i < caps->mode_count; i++) {
-               output_data->drm_modes[i] = connector->modes[i];
-               tdm_exynos_display_to_tdm_mode(&output_data->drm_modes[i],
-                                                                          &output_data->output_modes[i]);
-               caps->modes[i] = output_data->output_modes[i];
-       }
-
-       if (connector->connection == DRM_MODE_CONNECTED)
-               output_data->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
-       else
-               output_data->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
-       caps->status = output_data->status;
-
-       if (exynos_screen_prerotation_hint % 180) {
-               caps->mmWidth = connector->mmHeight;
-               caps->mmHeight = connector->mmWidth;
-               caps->min_w = exynos_data->mode_res->min_height;
-               caps->min_h = exynos_data->mode_res->min_width;
-               caps->max_w = exynos_data->mode_res->max_height;
-               caps->max_h = exynos_data->mode_res->max_width;
-       } else {
-               caps->mmWidth = connector->mmWidth;
-               caps->mmHeight = connector->mmHeight;
-               caps->min_w = exynos_data->mode_res->min_width;
-               caps->min_h = exynos_data->mode_res->min_height;
-               caps->max_w = exynos_data->mode_res->max_width;
-               caps->max_h = exynos_data->mode_res->max_height;
-       }
-
-       caps->subpixel = connector->subpixel;
-       caps->preferred_align = -1;
-
-       caps->cursor_min_w = 32;
-       caps->cursor_min_h = 32;
-       caps->cursor_max_w = -1;
-       caps->cursor_max_h = -1;
-       caps->cursor_preferred_align = -1;
-
-       crtc = drmModeGetCrtc(exynos_data->drm_fd, output_data->crtc_id);
-       if (!crtc) {
-               ret = TDM_ERROR_OPERATION_FAILED;
-               TDM_ERR("get crtc failed: %m\n");
-               goto failed_get;
-       }
-
-       props = drmModeObjectGetProperties(exynos_data->drm_fd, output_data->crtc_id,
-                                                                          DRM_MODE_OBJECT_CRTC);
-       if (!props) {
-               ret = TDM_ERROR_OPERATION_FAILED;
-               TDM_ERR("get crtc properties failed: %m\n");
-               goto failed_get;
-       }
-
-       caps->props = calloc(1, sizeof(tdm_prop) * props->count_props);
-       if (!caps->props) {
-               ret = TDM_ERROR_OUT_OF_MEMORY;
-               TDM_ERR("alloc failed\n");
-               goto failed_get;
-       }
-
-       caps->prop_count = 0;
-       for (i = 0; i < props->count_props; i++) {
-               drmModePropertyPtr prop = drmModeGetProperty(exynos_data->drm_fd,
-                                                                                                        props->props[i]);
-               if (!prop)
-                       continue;
-               snprintf(caps->props[caps->prop_count].name, TDM_NAME_LEN, "%s", prop->name);
-               caps->props[caps->prop_count].id = props->props[i];
-               caps->prop_count++;
-               drmModeFreeProperty(prop);
-       }
-
-       if (output_data->hwc_enable)
-               caps->capabilities |= TDM_OUTPUT_CAPABILITY_HWC;
-
-       drmModeFreeObjectProperties(props);
-       drmModeFreeCrtc(crtc);
-       drmModeFreeConnector(connector);
-
-       return TDM_ERROR_NONE;
-failed_get:
-       drmModeFreeCrtc(crtc);
-       drmModeFreeObjectProperties(props);
-       drmModeFreeConnector(connector);
-       free(caps->modes);
-       free(caps->props);
-       memset(caps, 0, sizeof(tdm_caps_output));
-       return ret;
-}
-
-tdm_layer **
-exynos_output_get_layers(tdm_output *output,  int *count, tdm_error *error)
-{
-       tdm_exynos_output_data *output_data = output;
-       tdm_exynos_layer_data *layer_data = NULL;
-       tdm_layer **layers;
-       tdm_error ret;
-       int i;
-
-       RETURN_VAL_IF_FAIL(output_data, NULL);
-       RETURN_VAL_IF_FAIL(count, NULL);
-
-       if (output_data->hwc_enable) {
-               *count = 0;
-               ret = TDM_ERROR_NONE;
-               goto failed_get;
-       }
-
-       *count = 0;
-       LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link)
-       (*count)++;
-
-       if (*count == 0) {
-               ret = TDM_ERROR_NONE;
-               goto failed_get;
-       }
-
-       /* will be freed in frontend */
-       layers = calloc(*count, sizeof(tdm_exynos_layer_data *));
-       if (!layers) {
-               TDM_ERR("failed: alloc memory");
-               *count = 0;
-               ret = TDM_ERROR_OUT_OF_MEMORY;
-               goto failed_get;
-       }
-
-       i = 0;
-       LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link)
-       layers[i++] = layer_data;
-
-       if (error)
-               *error = TDM_ERROR_NONE;
-
-       return layers;
-failed_get:
-       if (error)
-               *error = ret;
-       return NULL;
-}
-
-tdm_error
-exynos_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
-{
-       tdm_exynos_output_data *output_data = output;
-       tdm_exynos_data *exynos_data;
-       int ret;
-
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(output_data->crtc_id > 0, TDM_ERROR_INVALID_PARAMETER);
-
-       exynos_data = output_data->exynos_data;
-       ret = drmModeObjectSetProperty(exynos_data->drm_fd,
-                                                                  output_data->crtc_id, DRM_MODE_OBJECT_CRTC,
-                                                                  id, value.u32);
-       if (ret < 0) {
-               TDM_ERR("set property failed: %m");
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_get_property(tdm_output *output, unsigned int id,
-                                                                tdm_value *value)
-{
-       tdm_exynos_output_data *output_data = output;
-       tdm_exynos_data *exynos_data;
-       drmModeObjectPropertiesPtr props;
-       int i;
-
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(output_data->crtc_id > 0, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(value, TDM_ERROR_INVALID_PARAMETER);
-
-       exynos_data = output_data->exynos_data;
-       props = drmModeObjectGetProperties(exynos_data->drm_fd, output_data->crtc_id,
-                                                                          DRM_MODE_OBJECT_CRTC);
-       if (props == NULL) {
-               TDM_ERR("get property failed: %m");
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       for (i = 0; i < props->count_props; i++)
-               if (props->props[i] == id) {
-                       (*value).u32 = (uint)props->prop_values[i];
-                       break;
-               }
-
-       drmModeFreeObjectProperties(props);
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_wait_vblank(tdm_output *output, int interval, int sync,
-                                                               void *user_data)
-{
-       tdm_exynos_output_data *output_data = output;
-       tdm_exynos_data *exynos_data;
-       tdm_exynos_event_data *event_data;
-       uint target_msc;
-       tdm_error ret;
-
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-
-       event_data = calloc(1, sizeof(tdm_exynos_event_data));
-       if (!event_data) {
-               TDM_ERR("alloc failed");
-               return TDM_ERROR_OUT_OF_MEMORY;
-       }
-
-       exynos_data = output_data->exynos_data;
-
-       ret = _tdm_exynos_output_get_cur_msc(exynos_data->drm_fd, output_data->pipe,
-                                                                                &target_msc);
-       if (ret != TDM_ERROR_NONE)
-               goto failed_vblank;
-
-       target_msc += interval;
-
-       event_data->type = TDM_EXYNOS_EVENT_TYPE_WAIT;
-       event_data->output_data = output_data;
-       event_data->user_data = user_data;
-
-       ret = _tdm_exynos_output_wait_vblank(exynos_data->drm_fd, output_data->pipe,
-                                                                                &target_msc, event_data);
-       if (ret != TDM_ERROR_NONE)
-               goto failed_vblank;
-
-       return TDM_ERROR_NONE;
-failed_vblank:
-       free(event_data);
-       return ret;
-}
-
-tdm_error
-exynos_output_set_vblank_handler(tdm_output *output,
-                                                                               tdm_output_vblank_handler func)
-{
-       tdm_exynos_output_data *output_data = output;
-
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
-
-       output_data->vblank_func = func;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_commit(tdm_output *output, int sync, void *user_data)
-{
-       tdm_exynos_output_data *output_data = output;
-       tdm_exynos_data *exynos_data;
-       tdm_exynos_layer_data *layer_data = NULL;
-       tdm_error ret;
-       int do_waitvblank = 1;
-
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-
-       exynos_data = output_data->exynos_data;
-
-       LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
-               if (layer_data == output_data->primary_layer) {
-                       if (!layer_data->display_buffer ||
-                               (output_data->current_mode->hdisplay == layer_data->info.src_config.pos.w &&
-                               output_data->current_mode->vdisplay == layer_data->info.src_config.pos.h)) {
-                               ret = _tdm_exynos_output_commit_primary_layer(layer_data, user_data,
-                                                                                                                                                 &do_waitvblank);
-                       } else
-                               ret = _tdm_exynos_output_commit_layer(layer_data);
-
-                       if (ret != TDM_ERROR_NONE)
-                               return ret;
-               } else {
-                       ret = _tdm_exynos_output_commit_layer(layer_data);
-                       if (ret != TDM_ERROR_NONE)
-                               return ret;
-               }
-       }
-
-       if (do_waitvblank == 1) {
-               tdm_exynos_event_data *event_data = calloc(1, sizeof(tdm_exynos_event_data));
-               uint target_msc;
-
-               if (!event_data) {
-                       TDM_ERR("alloc failed");
-                       return TDM_ERROR_OUT_OF_MEMORY;
-               }
-
-               ret = _tdm_exynos_output_get_cur_msc(exynos_data->drm_fd, output_data->pipe,
-                                                                                        &target_msc);
-               if (ret != TDM_ERROR_NONE) {
-                       free(event_data);
-                       return ret;
-               }
-
-               target_msc++;
-
-               event_data->type = TDM_EXYNOS_EVENT_TYPE_COMMIT;
-               event_data->output_data = output_data;
-               event_data->user_data = user_data;
-               event_data->hwc_mode = exynos_data->hwc_mode;
-
-               ret = _tdm_exynos_output_wait_vblank(exynos_data->drm_fd, output_data->pipe,
-                                                                                        &target_msc, event_data);
-               if (ret != TDM_ERROR_NONE) {
-                       free(event_data);
-                       return ret;
-               }
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_set_commit_handler(tdm_output *output,
-                                                                                tdm_output_commit_handler func)
-{
-       tdm_exynos_output_data *output_data = output;
-
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
-
-       output_data->commit_func = func;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
-{
-       tdm_exynos_output_data *output_data = output;
-       tdm_exynos_data *exynos_data;
-       int ret;
-
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-
-       exynos_data = output_data->exynos_data;
-       ret = drmModeObjectSetProperty(exynos_data->drm_fd,
-                                                                  output_data->connector_id, DRM_MODE_OBJECT_CONNECTOR,
-                                                                  output_data->dpms_prop_id, dpms_value);
-       if (ret < 0) {
-               TDM_ERR("set dpms failed: %m");
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
-{
-       tdm_exynos_output_data *output_data = output;
-       tdm_exynos_data *exynos_data;
-       drmModeObjectPropertiesPtr props;
-       int i;
-
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(dpms_value, TDM_ERROR_INVALID_PARAMETER);
-
-       exynos_data = output_data->exynos_data;
-       props = drmModeObjectGetProperties(exynos_data->drm_fd,
-                                                                          output_data->connector_id, DRM_MODE_OBJECT_CONNECTOR);
-       if (props == NULL) {
-               TDM_ERR("get property failed: %m");
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       for (i = 0; i < props->count_props; i++)
-               if (props->props[i] == output_data->dpms_prop_id) {
-                       *dpms_value = (uint)props->prop_values[i];
-                       break;
-               }
-
-       drmModeFreeObjectProperties(props);
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
-{
-       tdm_exynos_output_data *output_data = output;
-       tdm_error ret = TDM_ERROR_NONE;
-
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER);
-
-       /* create or replace the target_window when the output mode is set */
-       if (output_data->hwc_enable) {
-               ret = exynos_hwc_initailize_target_window(output_data->hwc_data, mode->hdisplay, mode->vdisplay);
-               if (ret != TDM_ERROR_NONE) {
-                       TDM_ERR("create target hwc window failed (%d)", ret);
-                       return ret;
-               }
-       }
-
-       output_data->current_mode = mode;
-       output_data->mode_changed = 1;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
-{
-       tdm_exynos_output_data *output_data = output;
-
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER);
-
-       *mode = output_data->current_mode;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_capture*
-exynos_output_create_capture(tdm_output *output, tdm_error *error)
-{
-       tdm_exynos_output_data *output_data = output;
-       tdm_exynos_data *exynos_data;
-
-       RETURN_VAL_IF_FAIL(output_data, NULL);
-
-       exynos_data = output_data->exynos_data;
-
-       if (exynos_data->use_ippv2)
-               return tdm_exynos_capture_create_output(exynos_data, output, error);
-       else
-               return tdm_exynos_capture_legacy_create_output(exynos_data, output, error);
-}
-
-tdm_error
-exynos_output_set_status_handler(tdm_output *output,
-                                                                          tdm_output_status_handler func,
-                                                                          void *user_data)
-{
-       tdm_exynos_output_data *output_data = output;
-
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
-
-       output_data->status_func = func;
-       output_data->status_user_data = user_data;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_hwc *
-exynos_output_get_hwc(tdm_output *output, tdm_error *error)
-{
-       tdm_exynos_hwc_data *hwc_data = NULL;
-       tdm_exynos_output_data *output_data = output;
-
-       if (!output_data) {
-               TDM_ERR("invalid params");
-               if (error)
-                       *error = TDM_ERROR_INVALID_PARAMETER;
-               return NULL;
-       }
-
-       if (output_data->hwc_data) {
-               TDM_INFO("hwc_data already exists");
-               if (error)
-                       *error = TDM_ERROR_NONE;
-               return output_data->hwc_data;
-       }
-
-       hwc_data = calloc(1, sizeof(tdm_exynos_hwc_data));
-       if (!hwc_data) {
-               TDM_ERR("alloc failed");
-               if (error)
-                       *error = TDM_ERROR_OUT_OF_MEMORY;
-               return NULL;
-       }
-       hwc_data->output_data = output_data;
-
-       LIST_INITHEAD(&hwc_data->hwc_window_list);
-
-       output_data->hwc_data = hwc_data;
-
-       if (error)
-               *error = TDM_ERROR_NONE;
-
-       return hwc_data;
-}
diff --git a/src/tdm_exynos_output.h b/src/tdm_exynos_output.h
deleted file mode 100644 (file)
index 195f15f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _TDM_EXYNOS_OUTPUT_H_
-#define _TDM_EXYNOS_OUTPUT_H_
-
-#include "tdm_exynos.h"
-
-void tdm_exynos_output_cb_event(int fd, unsigned int sequence,
-                                                                          unsigned int tv_sec, unsigned int tv_usec,
-                                                                          void *user_data);
-tdm_error
-tdm_exynos_output_update_status(tdm_exynos_output_data *output_data,
-                                                                               tdm_output_conn_status status);
-
-#endif /* _TDM_EXYNOS_OUTPUT_H_ */
diff --git a/src/tdm_exynos_pp.c b/src/tdm_exynos_pp.c
deleted file mode 100644 (file)
index fb63e6d..0000000
+++ /dev/null
@@ -1,433 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_exynos.h"
-
-typedef struct _tdm_exynos_pp_data {
-       tdm_exynos_data *exynos_data;
-
-       tdm_info_pp info;
-
-       struct list_head pending_buffer_list;
-       struct list_head buffer_list;
-
-       tdm_pp_done_handler done_func;
-       void *done_user_data;
-
-       int first_event;
-
-       struct list_head link;
-} tdm_exynos_pp_data;
-
-typedef struct _tdm_exynos_pp_buffer {
-       tdm_exynos_pp_data *pp_data;
-       tbm_surface_h src;
-       tbm_surface_h dst;
-
-       struct list_head link;
-} tdm_exynos_pp_buffer;
-
-
-static int pp_list_init;
-static struct list_head pp_list;
-
-struct exynos_drm_ipp_std_task {
-       struct drm_exynos_ipp_task_buffer buf[2];
-       struct drm_exynos_ipp_task_rect rect[2];
-       struct drm_exynos_ipp_task_transform transform;
-} __packed;
-
-static unsigned int tdm_transform_to_drm(tdm_transform t)
-{
-       switch (t) {
-       case TDM_TRANSFORM_NORMAL:
-               return DRM_MODE_ROTATE_0;
-       case TDM_TRANSFORM_90:
-               return DRM_MODE_ROTATE_90;
-       case TDM_TRANSFORM_180:
-               return DRM_MODE_ROTATE_180;
-       case TDM_TRANSFORM_270:
-               return DRM_MODE_ROTATE_270;
-       case TDM_TRANSFORM_FLIPPED:
-               return DRM_MODE_REFLECT_Y;
-       case TDM_TRANSFORM_FLIPPED_90:
-               return DRM_MODE_REFLECT_Y | DRM_MODE_ROTATE_90;
-       case TDM_TRANSFORM_FLIPPED_180:
-               return DRM_MODE_REFLECT_Y | DRM_MODE_ROTATE_180;
-       case TDM_TRANSFORM_FLIPPED_270:
-               return DRM_MODE_REFLECT_Y | DRM_MODE_ROTATE_270;
-       }
-       return 0;
-}
-
-static tdm_error
-_tdm_exynos_pp_process(tdm_exynos_pp_data *pp_data, tdm_exynos_pp_buffer *buffer)
-{
-       tdm_exynos_data *exynos_data = pp_data->exynos_data;
-       tdm_info_pp *info = &pp_data->info;
-       int i, plane_num, ret = 0;
-
-       struct exynos_drm_ipp_std_task task;
-       struct drm_exynos_ioctl_ipp_commit arg;
-
-       CLEAR(task);
-
-       /* src buf */
-       task.buf[0].id = DRM_EXYNOS_IPP_TASK_BUFFER | DRM_EXYNOS_IPP_TASK_TYPE_SOURCE;
-       task.buf[0].fourcc = tdm_exynos_format_to_drm_format(tbm_surface_get_format(buffer->src));
-       task.buf[0].width = tbm_surface_get_width(buffer->src);
-       task.buf[0].height = tbm_surface_get_height(buffer->src);
-
-       plane_num = tbm_surface_internal_get_num_planes(tbm_surface_get_format(buffer->src));
-       for (i = 0; i < EXYNOS_DRM_PLANAR_MAX && i < plane_num; i++) {
-               uint32_t size, offset, pitch;
-               int bo_index;
-               tbm_bo bo;
-
-               bo_index = tbm_surface_internal_get_plane_bo_idx(buffer->src, i);
-               bo = tbm_surface_internal_get_bo(buffer->src, bo_index);
-
-               tbm_surface_internal_get_plane_data(buffer->src, i, &size, &offset, &pitch);
-               task.buf[0].gem_id[i] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
-               task.buf[0].pitch[i] = pitch;
-               task.buf[0].offset[i] = offset;
-       }
-
-       /* dst buf */
-       task.buf[1].id = DRM_EXYNOS_IPP_TASK_BUFFER | DRM_EXYNOS_IPP_TASK_TYPE_DESTINATION;
-       task.buf[1].fourcc = tdm_exynos_format_to_drm_format(tbm_surface_get_format(buffer->dst));
-       task.buf[1].width = tbm_surface_get_width(buffer->dst);
-       task.buf[1].height = tbm_surface_get_height(buffer->dst);
-
-       plane_num = tbm_surface_internal_get_num_planes(tbm_surface_get_format(buffer->dst));
-       for (i = 0; i < EXYNOS_DRM_PLANAR_MAX && i < plane_num; i++) {
-               uint32_t size, offset, pitch;
-               int bo_index;
-               tbm_bo bo;
-
-               bo_index = tbm_surface_internal_get_plane_bo_idx(buffer->dst, i);
-               bo = tbm_surface_internal_get_bo(buffer->dst, bo_index);
-
-               tbm_surface_internal_get_plane_data(buffer->dst, i, &size, &offset, &pitch);
-               task.buf[1].gem_id[i] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
-               task.buf[1].pitch[i] = pitch;
-               task.buf[1].offset[i] = offset;
-       }
-
-       task.rect[0].id = DRM_EXYNOS_IPP_TASK_RECTANGLE | DRM_EXYNOS_IPP_TASK_TYPE_SOURCE;
-       task.rect[0].x = info->src_config.pos.x;
-       task.rect[0].y = info->src_config.pos.y;
-       task.rect[0].w = info->src_config.pos.w;
-       task.rect[0].h = info->src_config.pos.h;
-
-       task.rect[1].id = DRM_EXYNOS_IPP_TASK_RECTANGLE | DRM_EXYNOS_IPP_TASK_TYPE_DESTINATION;
-       task.rect[1].x = info->dst_config.pos.x;
-       task.rect[1].y = info->dst_config.pos.y;
-       task.rect[1].w = info->dst_config.pos.w;
-       task.rect[1].h = info->dst_config.pos.h;
-
-       task.transform.id = DRM_EXYNOS_IPP_TASK_TRANSFORM;
-       task.transform.rotation = tdm_transform_to_drm(info->transform);
-
-       CLEAR(arg);
-       arg.flags = DRM_EXYNOS_IPP_FLAG_EVENT | DRM_EXYNOS_IPP_FLAG_NONBLOCK;
-       arg.ipp_id = exynos_data->ipp_module_id;
-       arg.params_size = sizeof(task);
-       arg.params_ptr = (unsigned long)(&task);
-       arg.user_data = (__u64)(uintptr_t)buffer;
-
-       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_COMMIT, &arg);
-       if (ret) {
-               TDM_ERR("ipp commit failed. %xx pp_data(%p), buffer(%p). %m", DRM_IOCTL_EXYNOS_IPP_COMMIT, pp_data, buffer);
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-void
-tdm_exynos_pp_handler(unsigned int tv_sec, unsigned int tv_usec, void *data)
-{
-       tdm_exynos_pp_buffer *b = NULL, *bb, *dequeued_buffer = data;
-       tdm_exynos_pp_data *pp_data;
-
-       if (!dequeued_buffer) {
-               TDM_ERR("invalid params");
-               return;
-       }
-
-       if (!pp_list_init)
-               return;
-
-       pp_data = dequeued_buffer->pp_data;
-
-       TDM_DBG("pp_data(%p) buffer(%p)", pp_data, dequeued_buffer);
-
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->buffer_list, link) {
-               if (b == dequeued_buffer) {
-                       LIST_DEL(&dequeued_buffer->link);
-                       TDM_DBG("dequeued: %p", dequeued_buffer);
-                       break;
-               }
-       }
-
-       if (!pp_data->first_event) {
-               TDM_DBG("pp(%p) got a first event. ", pp_data);
-               pp_data->first_event = 1;
-       }
-
-       if (pp_data->done_func)
-               pp_data->done_func(pp_data,
-                                  dequeued_buffer->src,
-                                  dequeued_buffer->dst,
-                                  pp_data->done_user_data);
-       free(dequeued_buffer);
-}
-
-static enum drm_exynos_ipp_capability required_exynos_ipp_caps =
-       DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE |
-       DRM_EXYNOS_IPP_CAP_SCALE | DRM_EXYNOS_IPP_CAP_CONVERT;
-
-tdm_error
-tdm_exynos_pp_init(tdm_exynos_data *exynos_data)
-{
-       struct drm_exynos_ioctl_ipp_get_caps caps_arg;
-       struct drm_exynos_ioctl_ipp_get_res res_arg;
-       uint32_t *ipps;
-       int i;
-
-       exynos_data->ipp_module_id = -1;
-
-       CLEAR(res_arg);
-       if (ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_RESOURCES,
-                 &res_arg)) {
-               TDM_ERR("failed to get Exynos IPP resources");
-               return TDM_ERROR_NO_CAPABILITY;
-       }
-
-       ipps = calloc(res_arg.count_ipps, sizeof(*ipps));
-       if (!ipps) {
-               TDM_ERR("alloc failed");
-               return TDM_ERROR_OUT_OF_MEMORY;
-       }
-
-       res_arg.ipp_id_ptr = (unsigned long)ipps;
-       if (ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_RESOURCES,
-                 &res_arg)) {
-               TDM_ERR("failed to get Exynos IPP resources");
-               free(ipps);
-               return TDM_ERROR_NO_CAPABILITY;
-       }
-
-       for (i = 0; i < res_arg.count_ipps; i++) {
-               CLEAR(caps_arg);
-               caps_arg.ipp_id = ipps[i];
-               if (ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_CAPS,
-                 &caps_arg)) {
-                       TDM_ERR("failed to get IPP capabilities");
-                       free(ipps);
-                       return TDM_ERROR_NO_CAPABILITY;
-               }
-               if ((caps_arg.capabilities & required_exynos_ipp_caps) ==
-                   required_exynos_ipp_caps)
-                       break;
-       }
-       if (i == res_arg.count_ipps) {
-               free(ipps);
-               return TDM_ERROR_NO_CAPABILITY;
-       }
-
-       TDM_INFO("selected Exynos IPP module id %d", ipps[i]);
-       exynos_data->ipp_module_id = ipps[i];
-       free(ipps);
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-tdm_exynos_pp_get_capability(tdm_exynos_data *exynos_data, tdm_caps_pp *caps)
-{
-       struct drm_exynos_ioctl_ipp_get_caps caps_arg;
-       struct drm_exynos_ipp_format *formats;
-       int i, pp_formats;
-
-       if (!caps) {
-               TDM_ERR("invalid params");
-               return TDM_ERROR_INVALID_PARAMETER;
-       }
-
-       CLEAR(caps_arg);
-       caps_arg.ipp_id = exynos_data->ipp_module_id;
-       if (ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_CAPS,
-                 &caps_arg)) {
-               TDM_ERR("failed to get IPP capabilities");
-               return TDM_ERROR_NO_CAPABILITY;
-       }
-
-       formats = calloc(caps_arg.formats_count, sizeof(*formats));
-       if (!formats) {
-               TDM_ERR("alloc failed");
-               return TDM_ERROR_OUT_OF_MEMORY;
-       }
-
-       caps_arg.formats_ptr = (unsigned long) formats;
-       if (ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_CAPS,
-                 &caps_arg)) {
-               TDM_ERR("failed to get IPP capabilities");
-               free(formats);
-               return TDM_ERROR_NO_CAPABILITY;
-       }
-
-       for (pp_formats = 0, i = 0; i < caps_arg.formats_count; i++)
-               if (formats[i].modifier == 0 &&
-                   tdm_exynos_format_to_tbm_format(formats[i].fourcc))
-                       pp_formats++;
-
-       caps->capabilities = TDM_PP_CAPABILITY_ASYNC;
-       caps->format_count = pp_formats;
-
-       /* will be freed in frontend */
-       caps->formats = calloc(pp_formats, sizeof(tbm_format));
-       if (!caps->formats) {
-               TDM_ERR("alloc failed");
-               free(formats);
-               return TDM_ERROR_OUT_OF_MEMORY;
-       }
-
-       for (pp_formats = 0, i = 0; i < caps_arg.formats_count; i++) {
-               tbm_format f;
-               f = tdm_exynos_format_to_tbm_format(formats[i].fourcc);
-               if (formats[i].modifier == 0 && f)
-                       caps->formats[pp_formats++] = f;
-       }
-
-       caps->min_w = 16;
-       caps->min_h = 8;
-       caps->max_w = -1;   /* not defined */
-       caps->max_h = -1;
-       caps->preferred_align = 16;
-
-       caps->max_attach_count = -1;
-
-       free(formats);
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_pp *
-tdm_exynos_pp_create(tdm_exynos_data *exynos_data, tdm_error *error)
-{
-       tdm_exynos_pp_data *pp_data = calloc(1, sizeof(tdm_exynos_pp_data));
-       if (!pp_data) {
-               TDM_ERR("alloc failed");
-               if (error)
-                       *error = TDM_ERROR_OUT_OF_MEMORY;
-               return NULL;
-       }
-
-       pp_data->exynos_data = exynos_data;
-
-       LIST_INITHEAD(&pp_data->pending_buffer_list);
-       LIST_INITHEAD(&pp_data->buffer_list);
-
-       if (!pp_list_init) {
-               pp_list_init = 1;
-               LIST_INITHEAD(&pp_list);
-       }
-       LIST_ADDTAIL(&pp_data->link, &pp_list);
-
-       return pp_data;
-}
-
-void
-exynos_pp_destroy(tdm_pp *pp)
-{
-       tdm_exynos_pp_data *pp_data = pp;
-       tdm_exynos_pp_buffer *b = NULL, *bb = NULL;
-
-       if (!pp_data)
-               return;
-
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->pending_buffer_list, link) {
-               LIST_DEL(&b->link);
-               free(b);
-       }
-       LIST_DEL(&pp_data->link);
-
-       free(pp_data);
-}
-
-tdm_error
-exynos_pp_set_info(tdm_pp *pp, tdm_info_pp *info)
-{
-       tdm_exynos_pp_data *pp_data = pp;
-
-       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
-
-       if (info->sync) {
-               TDM_ERR("not support sync mode currently");
-               return TDM_ERROR_INVALID_PARAMETER;
-       }
-
-       pp_data->info = *info;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst)
-{
-       tdm_exynos_pp_data *pp_data = pp;
-       tdm_exynos_pp_buffer *buffer;
-
-       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(src, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(dst, TDM_ERROR_INVALID_PARAMETER);
-
-       buffer = calloc(1, sizeof(tdm_exynos_pp_buffer));
-       if (!buffer) {
-               TDM_ERR("alloc failed");
-               return TDM_ERROR_NONE;
-       }
-
-       LIST_ADDTAIL(&buffer->link, &pp_data->pending_buffer_list);
-       buffer->src = src;
-       buffer->dst = dst;
-       buffer->pp_data = pp_data;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_pp_commit(tdm_pp *pp)
-{
-       tdm_exynos_pp_data *pp_data = pp;
-       tdm_exynos_pp_buffer *b = NULL, *bb = NULL;
-
-       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
-
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->pending_buffer_list, link) {
-               LIST_DEL(&b->link);
-               _tdm_exynos_pp_process(pp_data, b);
-               LIST_ADDTAIL(&b->link, &pp_data->buffer_list);
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_pp_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func,
-                                                                 void *user_data)
-{
-       tdm_exynos_pp_data *pp_data = pp;
-
-       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
-
-       pp_data->done_func = func;
-       pp_data->done_user_data = user_data;
-
-       return TDM_ERROR_NONE;
-}
diff --git a/src/tdm_exynos_pp.h b/src/tdm_exynos_pp.h
deleted file mode 100644 (file)
index 07d3d34..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _TDM_EXYNOS_PP_H_
-#define _TDM_EXYNOS_PP_H_
-
-#include "tdm_exynos.h"
-
-tdm_error    tdm_exynos_pp_init(tdm_exynos_data *exynos_data);
-tdm_error    tdm_exynos_pp_get_capability(tdm_exynos_data *exynos_data, tdm_caps_pp *caps);
-tdm_pp*      tdm_exynos_pp_create(tdm_exynos_data *exynos_data, tdm_error *error);
-void         tdm_exynos_pp_handler(unsigned int tv_sec, unsigned int tv_usec, void *data);
-#endif /* _TDM_EXYNOS_PP_H_ */
diff --git a/src/tdm_exynos_pp_legacy.c b/src/tdm_exynos_pp_legacy.c
deleted file mode 100644 (file)
index 13a7237..0000000
+++ /dev/null
@@ -1,451 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_exynos.h"
-
-typedef struct _tdm_exynos_pp_legacy_buffer {
-       int index;
-       tbm_surface_h src;
-       tbm_surface_h dst;
-
-       struct list_head link;
-} tdm_exynos_pp_legacy_buffer;
-
-typedef struct _tdm_exynos_pp_legacy_data {
-       tdm_exynos_data *exynos_data;
-
-       unsigned int prop_id;
-
-       tdm_info_pp info;
-       int info_changed;
-
-       struct list_head pending_buffer_list;
-       struct list_head buffer_list;
-
-       tdm_pp_done_handler done_func;
-       void *done_user_data;
-
-       int startd;
-       int first_event;
-
-       struct list_head link;
-} tdm_exynos_pp_legacy_data;
-
-
-static tbm_format pp_formats[] = {
-       TBM_FORMAT_ARGB8888,
-       TBM_FORMAT_XRGB8888,
-       TBM_FORMAT_NV12,
-       TBM_FORMAT_NV21,
-       TBM_FORMAT_YUV420,
-       TBM_FORMAT_YVU420,
-#ifdef HAVE_TILED_FORMAT
-       TBM_FORMAT_NV12MT,
-#endif
-};
-
-#define NUM_PP_FORMAT   (sizeof(pp_formats) / sizeof(pp_formats[0]))
-
-static int pp_list_init;
-static struct list_head pp_list;
-
-static int
-_get_index(tdm_exynos_pp_legacy_data *pp_data)
-{
-       tdm_exynos_pp_legacy_buffer *buffer = NULL;
-       int ret = 0;
-
-       while (1) {
-               int found = 0;
-               LIST_FOR_EACH_ENTRY(buffer, &pp_data->pending_buffer_list, link) {
-                       if (ret == buffer->index) {
-                               found = 1;
-                               break;
-                       }
-               }
-               if (!found)
-                       LIST_FOR_EACH_ENTRY(buffer, &pp_data->buffer_list, link) {
-                       if (ret == buffer->index) {
-                               found = 1;
-                               break;
-                       }
-               }
-               if (!found)
-                       break;
-               ret++;
-       }
-
-       return ret;
-}
-
-static tdm_error
-_tdm_exynos_pp_legacy_set(tdm_exynos_pp_legacy_data *pp_data)
-{
-       tdm_exynos_data *exynos_data = pp_data->exynos_data;
-       tdm_info_pp *info = &pp_data->info;
-       struct drm_exynos_ipp_property property;
-       int ret = 0;
-
-       CLEAR(property);
-       property.config[0].ops_id = EXYNOS_DRM_OPS_SRC;
-       property.config[0].fmt = tdm_exynos_format_to_drm_format(info->src_config.format);
-       memcpy(&property.config[0].sz, &info->src_config.size, sizeof(tdm_size));
-       memcpy(&property.config[0].pos, &info->src_config.pos, sizeof(tdm_pos));
-       property.config[1].ops_id = EXYNOS_DRM_OPS_DST;
-       property.config[1].degree = info->transform % 4;
-       property.config[1].flip = (info->transform > 3) ? EXYNOS_DRM_FLIP_HORIZONTAL : 0;
-       property.config[1].fmt = tdm_exynos_format_to_drm_format(info->dst_config.format);
-       memcpy(&property.config[1].sz, &info->dst_config.size, sizeof(tdm_size));
-       memcpy(&property.config[1].pos, &info->dst_config.pos, sizeof(tdm_pos));
-       property.cmd = IPP_CMD_M2M;
-       property.prop_id = pp_data->prop_id;
-
-       TDM_DBG("src : flip(%x) deg(%d) fmt(%c%c%c%c) sz(%dx%d) pos(%d,%d %dx%d)  ",
-                       property.config[0].flip, property.config[0].degree,
-                       FOURCC_STR(property.config[0].fmt),
-                       property.config[0].sz.hsize, property.config[0].sz.vsize,
-                       property.config[0].pos.x, property.config[0].pos.y, property.config[0].pos.w,
-                       property.config[0].pos.h);
-       TDM_DBG("dst : flip(%x) deg(%d) fmt(%c%c%c%c) sz(%dx%d) pos(%d,%d %dx%d)  ",
-                       property.config[1].flip, property.config[1].degree,
-                       FOURCC_STR(property.config[1].fmt),
-                       property.config[1].sz.hsize, property.config[1].sz.vsize,
-                       property.config[1].pos.x, property.config[1].pos.y, property.config[1].pos.w,
-                       property.config[1].pos.h);
-
-       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_SET_PROPERTY, &property);
-       if (ret) {
-               TDM_ERR("failed: %m");
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       TDM_DBG("success. prop_id(%d) ", property.prop_id);
-       pp_data->prop_id = property.prop_id;
-       return TDM_ERROR_NONE;
-}
-
-static tdm_error
-_tdm_exynos_pp_legacy_queue(tdm_exynos_pp_legacy_data *pp_data, tdm_exynos_pp_legacy_buffer *buffer,
-                                                       enum drm_exynos_ipp_buf_type type)
-{
-       tdm_exynos_data *exynos_data = pp_data->exynos_data;
-       struct drm_exynos_ipp_queue_buf buf;
-       int i, bo_num, ret = 0;
-
-       CLEAR(buf);
-       buf.prop_id = pp_data->prop_id;
-       buf.ops_id = EXYNOS_DRM_OPS_SRC;
-       buf.buf_type = type;
-       buf.buf_id = buffer->index;
-       buf.user_data = (__u64)(uintptr_t)pp_data;
-       bo_num = tbm_surface_internal_get_num_bos(buffer->src);
-       for (i = 0; i < EXYNOS_DRM_PLANAR_MAX && i < bo_num; i++) {
-               tbm_bo bo = tbm_surface_internal_get_bo(buffer->src, i);
-               buf.handle[i] = (__u32)tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
-       }
-
-       TDM_DBG("prop_id(%d) ops_id(%d) ctrl(%d) id(%d) handles(%x %x %x). ",
-                       buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id,
-                       buf.handle[0], buf.handle[1], buf.handle[2]);
-
-       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
-       if (ret) {
-               TDM_ERR("src failed. prop_id(%d) op(%d) buf(%d) id(%d). %m",
-                               buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id);
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       CLEAR(buf);
-       buf.prop_id = pp_data->prop_id;
-       buf.ops_id = EXYNOS_DRM_OPS_DST;
-       buf.buf_type = type;
-       buf.buf_id = buffer->index;
-       buf.user_data = (__u64)(uintptr_t)pp_data;
-       bo_num = tbm_surface_internal_get_num_bos(buffer->dst);
-       for (i = 0; i < EXYNOS_DRM_PLANAR_MAX && i < bo_num; i++) {
-               tbm_bo bo = tbm_surface_internal_get_bo(buffer->dst, i);
-               buf.handle[i] = (__u32)tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
-       }
-
-       TDM_DBG("prop_id(%d) ops_id(%d) ctrl(%d) id(%d) handles(%x %x %x). ",
-                       buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id,
-                       buf.handle[0], buf.handle[1], buf.handle[2]);
-
-       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
-       if (ret) {
-               TDM_ERR("dst failed. prop_id(%d) op(%d) buf(%d) id(%d). %m",
-                               buf.prop_id, buf.ops_id, buf.buf_type, buf.buf_id);
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       TDM_DBG("success. prop_id(%d)", buf.prop_id);
-
-       return TDM_ERROR_NONE;
-}
-
-static tdm_error
-_tdm_exynos_pp_legacy_cmd(tdm_exynos_pp_legacy_data *pp_data, enum drm_exynos_ipp_ctrl cmd)
-{
-       tdm_exynos_data *exynos_data = pp_data->exynos_data;
-       struct drm_exynos_ipp_cmd_ctrl ctrl;
-       int ret = 0;
-
-       ctrl.prop_id = pp_data->prop_id;
-       ctrl.ctrl = cmd;
-
-       TDM_DBG("prop_id(%d) ctrl(%d). ", ctrl.prop_id, ctrl.ctrl);
-
-       ret = ioctl(exynos_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_CMD_CTRL, &ctrl);
-       if (ret) {
-               TDM_ERR("failed. prop_id(%d) ctrl(%d). %m", ctrl.prop_id, ctrl.ctrl);
-               return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       TDM_DBG("success. prop_id(%d) ", ctrl.prop_id);
-
-       return TDM_ERROR_NONE;
-}
-
-void
-tdm_exynos_pp_legacy_cb(int fd, unsigned int prop_id, unsigned int *buf_idx,
-                                         unsigned int tv_sec, unsigned int tv_usec, void *user_data)
-{
-       tdm_exynos_pp_legacy_handler(prop_id, buf_idx, tv_sec, tv_usec, user_data);
-}
-
-void
-tdm_exynos_pp_legacy_handler(unsigned int prop_id, unsigned int *buf_idx,
-                                                       unsigned int tv_sec, unsigned int tv_usec, void *data)
-{
-       tdm_exynos_pp_legacy_data *found = NULL, *d = NULL, *pp_data = data;
-       tdm_exynos_pp_legacy_buffer *b = NULL, *bb = NULL, *dequeued_buffer = NULL;
-
-       if (!pp_data || !buf_idx) {
-               TDM_ERR("invalid params");
-               return;
-       }
-
-       if (!pp_list_init)
-               return;
-
-       LIST_FOR_EACH_ENTRY(d, &pp_list, link) {
-               if (d == pp_data) {
-                       found = d;
-                       break;
-               }
-       }
-       if (!found)
-               return;
-
-       TDM_DBG("pp_data(%p) index(%d, %d)", pp_data, buf_idx[0], buf_idx[1]);
-
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->buffer_list, link) {
-               if (buf_idx[0] == b->index) {
-                       dequeued_buffer = b;
-                       LIST_DEL(&dequeued_buffer->link);
-                       TDM_DBG("dequeued: %d", dequeued_buffer->index);
-                       break;
-               }
-       }
-
-       if (!dequeued_buffer) {
-               TDM_ERR("not found buffer index: %d", buf_idx[0]);
-               return;
-       }
-
-       if (!pp_data->first_event) {
-               TDM_DBG("pp(%p) got a first event. ", pp_data);
-               pp_data->first_event = 1;
-       }
-
-       if (pp_data->done_func)
-               pp_data->done_func(pp_data,
-                                                  dequeued_buffer->src,
-                                                  dequeued_buffer->dst,
-                                                  pp_data->done_user_data);
-       free(dequeued_buffer);
-}
-
-tdm_error
-tdm_exynos_pp_legacy_get_capability(tdm_exynos_data *exynos_data, tdm_caps_pp *caps)
-{
-       int i;
-
-       if (!caps) {
-               TDM_ERR("invalid params");
-               return TDM_ERROR_INVALID_PARAMETER;
-       }
-
-       caps->capabilities = TDM_PP_CAPABILITY_ASYNC;
-
-       caps->format_count = NUM_PP_FORMAT;
-
-       /* will be freed in frontend */
-       caps->formats = calloc(1, sizeof pp_formats);
-       if (!caps->formats) {
-               TDM_ERR("alloc failed");
-               return TDM_ERROR_OUT_OF_MEMORY;
-       }
-       for (i = 0; i < caps->format_count; i++)
-               caps->formats[i] = pp_formats[i];
-
-       caps->min_w = 16;
-       caps->min_h = 8;
-       caps->max_w = -1;   /* not defined */
-       caps->max_h = -1;
-       caps->preferred_align = 16;
-
-       caps->max_attach_count = -1;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_pp *
-tdm_exynos_pp_legacy_create(tdm_exynos_data *exynos_data, tdm_error *error)
-{
-       tdm_exynos_pp_legacy_data *pp_data = calloc(1, sizeof(tdm_exynos_pp_legacy_data));
-       if (!pp_data) {
-               TDM_ERR("alloc failed");
-               if (error)
-                       *error = TDM_ERROR_OUT_OF_MEMORY;
-               return NULL;
-       }
-
-       pp_data->exynos_data = exynos_data;
-
-       LIST_INITHEAD(&pp_data->pending_buffer_list);
-       LIST_INITHEAD(&pp_data->buffer_list);
-
-       if (!pp_list_init) {
-               pp_list_init = 1;
-               LIST_INITHEAD(&pp_list);
-       }
-       LIST_ADDTAIL(&pp_data->link, &pp_list);
-
-       return pp_data;
-}
-
-void
-exynos_pp_legacy_destroy(tdm_pp *pp)
-{
-       tdm_exynos_pp_legacy_data *pp_data = pp;
-       tdm_exynos_pp_legacy_buffer *b = NULL, *bb = NULL;
-
-       if (!pp_data)
-               return;
-
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->pending_buffer_list, link) {
-               LIST_DEL(&b->link);
-               free(b);
-       }
-
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->buffer_list, link) {
-               LIST_DEL(&b->link);
-               _tdm_exynos_pp_legacy_queue(pp_data, b, IPP_BUF_DEQUEUE);
-               free(b);
-       }
-
-       if (pp_data->prop_id)
-               _tdm_exynos_pp_legacy_cmd(pp_data, IPP_CTRL_STOP);
-
-       LIST_DEL(&pp_data->link);
-
-       free(pp_data);
-}
-
-tdm_error
-exynos_pp_legacy_set_info(tdm_pp *pp, tdm_info_pp *info)
-{
-       tdm_exynos_pp_legacy_data *pp_data = pp;
-
-       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
-
-       if (info->sync) {
-               TDM_ERR("not support sync mode currently");
-               return TDM_ERROR_INVALID_PARAMETER;
-       }
-
-       pp_data->info = *info;
-       pp_data->info_changed = 1;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_pp_legacy_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst)
-{
-       tdm_exynos_pp_legacy_data *pp_data = pp;
-       tdm_exynos_pp_legacy_buffer *buffer;
-
-       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(src, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(dst, TDM_ERROR_INVALID_PARAMETER);
-
-       buffer = calloc(1, sizeof(tdm_exynos_pp_legacy_buffer));
-       if (!buffer) {
-               TDM_ERR("alloc failed");
-               return TDM_ERROR_NONE;
-       }
-
-       LIST_ADDTAIL(&buffer->link, &pp_data->pending_buffer_list);
-       buffer->index = _get_index(pp_data);
-       buffer->src = src;
-       buffer->dst = dst;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_pp_legacy_commit(tdm_pp *pp)
-{
-       tdm_exynos_pp_legacy_data *pp_data = pp;
-       tdm_exynos_pp_legacy_buffer *b = NULL, *bb = NULL;
-       tdm_error ret;
-
-       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
-
-       if (pp_data->info_changed) {
-               if (pp_data->startd)
-                       _tdm_exynos_pp_legacy_cmd(pp_data, IPP_CTRL_PAUSE);
-
-               ret = _tdm_exynos_pp_legacy_set(pp_data);
-               if (ret < 0)
-                       return TDM_ERROR_OPERATION_FAILED;
-       }
-
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->pending_buffer_list, link) {
-               LIST_DEL(&b->link);
-               _tdm_exynos_pp_legacy_queue(pp_data, b, IPP_BUF_ENQUEUE);
-               TDM_DBG("queued: %d", b->index);
-               LIST_ADDTAIL(&b->link, &pp_data->buffer_list);
-       }
-
-       if (pp_data->info_changed) {
-               pp_data->info_changed = 0;
-
-               if (!pp_data->startd) {
-                       pp_data->startd = 1;
-                       _tdm_exynos_pp_legacy_cmd(pp_data, IPP_CTRL_PLAY);
-               } else
-                       _tdm_exynos_pp_legacy_cmd(pp_data, IPP_CTRL_RESUME);
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-exynos_pp_legacy_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func,
-                                                                 void *user_data)
-{
-       tdm_exynos_pp_legacy_data *pp_data = pp;
-
-       RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
-
-       pp_data->done_func = func;
-       pp_data->done_user_data = user_data;
-
-       return TDM_ERROR_NONE;
-}
diff --git a/src/tdm_exynos_pp_legacy.h b/src/tdm_exynos_pp_legacy.h
deleted file mode 100644 (file)
index 21354bf..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _TDM_EXYNOS_PP_LEGACY_H_
-#define _TDM_EXYNOS_PP_LEGACY_H_
-
-#include "tdm_exynos.h"
-
-tdm_error    tdm_exynos_pp_legacy_get_capability(tdm_exynos_data *exynos_data, tdm_caps_pp *caps);
-tdm_pp*      tdm_exynos_pp_legacy_create(tdm_exynos_data *exynos_data, tdm_error *error);
-void         tdm_exynos_pp_legacy_handler(unsigned int prop_id, unsigned int *buf_idx,
-                                                                                unsigned int tv_sec, unsigned int tv_usec, void *data);
-void         tdm_exynos_pp_legacy_cb(int fd, unsigned int prop_id, unsigned int *buf_idx,
-                                                                       unsigned int tv_sec, unsigned int tv_usec,
-                                                                       void *user_data);
-#endif /* _TDM_EXYNOS_PP_LEGACY_H_ */
diff --git a/src/tdm_exynos_types.h b/src/tdm_exynos_types.h
deleted file mode 100644 (file)
index 93bc57e..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-#ifndef _TDM_EXYNOS_TYPES_H_
-#define _TDM_EXYNOS_TYPES_H_
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <errno.h>
-#include <unistd.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-#include <exynos_drm.h>
-#include <tbm_surface.h>
-#include <tbm_surface_internal.h>
-#include <tdm_backend.h>
-#include <tdm_log.h>
-#include <tdm_list.h>
-
-#if HAVE_UDEV
-#include <libudev.h>
-#endif
-
-/* exynos module internal macros, structures */
-#define NEVER_GET_HERE() TDM_ERR("** NEVER GET HERE **")
-
-#define C(b, m)                (((b) >> (m)) & 0xFF)
-#define B(c, s)                ((((unsigned int)(c)) & 0xff) << (s))
-#define FOURCC(a, b, c, d)     (B(d, 24) | B(c, 16) | B(b, 8) | B(a, 0))
-#define FOURCC_STR(id)         C(id, 0), C(id, 8), C(id, 16), C(id, 24)
-
-#define IS_RGB(format)      (format == TBM_FORMAT_XRGB8888 || format == TBM_FORMAT_ARGB8888 || \
-                                                       format == TBM_FORMAT_XBGR8888 || format == TBM_FORMAT_ABGR8888)
-
-#define CLEAR(x) memset(&(x), 0, sizeof(x))
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define SWAP(a, b)  ({ \
-                                               int t; \
-                                               t = a; \
-                                               a = b; \
-                                               b = t; \
-                                       })
-#define ROUNDUP(x)  (ceil(floor((float)(height) / 4)))
-
-#define ALIGN_TO_16B(x)    ((((x) + (1 <<  4) - 1) >>  4) <<  4)
-#define ALIGN_TO_32B(x)    ((((x) + (1 <<  5) - 1) >>  5) <<  5)
-#define ALIGN_TO_128B(x)   ((((x) + (1 <<  7) - 1) >>  7) <<  7)
-#define ALIGN_TO_2KB(x)    ((((x) + (1 << 11) - 1) >> 11) << 11)
-#define ALIGN_TO_8KB(x)    ((((x) + (1 << 13) - 1) >> 13) << 13)
-#define ALIGN_TO_64KB(x)   ((((x) + (1 << 16) - 1) >> 16) << 16)
-
-#define RETURN_IF_FAIL(cond) { \
-       if (!(cond)) { \
-               TDM_ERR("'%s' failed", #cond); \
-               return; \
-       } \
-}
-#define RETURN_VAL_IF_FAIL(cond, val) { \
-       if (!(cond)) { \
-               TDM_ERR("'%s' failed", #cond); \
-               return val; \
-       } \
-}
-
-typedef enum {
-       TDM_EXYNOS_EVENT_TYPE_WAIT,
-       TDM_EXYNOS_EVENT_TYPE_COMMIT,
-       TDM_EXYNOS_EVENT_TYPE_PAGEFLIP,
-} tdm_exynos_event_type;
-
-typedef struct _tdm_exynos_data tdm_exynos_data;
-typedef struct _tdm_exynos_output_data tdm_exynos_output_data;
-typedef struct _tdm_exynos_layer_data tdm_exynos_layer_data;
-typedef struct _tdm_exynos_hwc_data tdm_exynos_hwc_data;
-typedef struct _tdm_exynos_hwc_window_data tdm_exynos_hwc_window_data;
-typedef struct _tdm_exynos_event_data tdm_exynos_event_data;
-typedef struct _tdm_exynos_display_buffer tdm_exynos_display_buffer;
-
-struct _tdm_exynos_data {
-       tdm_display *dpy;
-
-       int drm_fd;
-
-#if HAVE_UDEV
-       struct udev_monitor *uevent_monitor;
-       tdm_event_loop_source *uevent_source;
-#endif
-
-       /* If true, it means that the device has many planes for one crtc. If false,
-        * planes are dedicated to specific crtc.
-        */
-       int has_zpos_info;
-
-       /* If has_zpos_info is false and is_immutable_zpos is true, it means that
-        * planes are dedicated to specific crtc.
-        */
-       int is_immutable_zpos;
-
-       drmModeResPtr mode_res;
-       drmModePlaneResPtr plane_res;
-
-       int hwc_mode;
-
-       struct list_head output_list;
-       struct list_head buffer_list;
-
-       int use_ippv2;
-       int ipp_module_id;
-};
-
-struct _tdm_exynos_output_data {
-       struct list_head link;
-
-       /* data which are fixed at initializing */
-       tdm_exynos_data *exynos_data;
-       uint32_t connector_id;
-       uint32_t encoder_id;
-       uint32_t crtc_id;
-       uint32_t pipe;
-       uint32_t dpms_prop_id;
-       int count_modes;
-       drmModeModeInfoPtr drm_modes;
-       tdm_output_mode *output_modes;
-       tdm_output_type connector_type;
-       unsigned int connector_type_id;
-       struct list_head layer_list;
-       tdm_exynos_layer_data *primary_layer;
-
-       /* not fixed data below */
-       tdm_output_vblank_handler vblank_func;
-       tdm_output_commit_handler commit_func;
-
-       tdm_output_conn_status status;
-       tdm_output_status_handler status_func;
-       void *status_user_data;
-
-       int mode_changed;
-       const tdm_output_mode *current_mode;
-
-       int crtc_set;
-
-       /* hwc data */
-       int hwc_enable;
-       tdm_exynos_hwc_data *hwc_data;
-};
-
-struct _tdm_exynos_layer_data {
-       struct list_head link;
-
-       /* data which are fixed at initializing */
-       tdm_exynos_data *exynos_data;
-       tdm_exynos_output_data *output_data;
-       uint32_t plane_id;
-       tdm_layer_capability capabilities;
-       int zpos;
-
-       /* not fixed data below */
-       tdm_info_layer info;
-       int info_changed;
-
-       tdm_exynos_display_buffer *display_buffer;
-       int display_buffer_changed;
-       int display_buffer_force_unset;
-
-       tbm_format *formats;
-       int format_count;
-
-       tdm_prop *props;
-       int prop_count;
-};
-
-struct _tdm_exynos_hwc_data {
-       tdm_exynos_hwc_window_data *target_hwc_window;
-
-       int need_validate;
-       int need_target_window;
-
-       int target_window_zpos;
-
-       tdm_exynos_output_data *output_data;
-       struct list_head hwc_window_list;
-
-       tdm_hwc_commit_handler commit_func;
-};
-
-struct _tdm_exynos_hwc_window_data {
-       struct list_head link;
-
-       /* data which are fixed at initializing */
-       tdm_exynos_hwc_data *hwc_data;
-
-       /* not fixed data below */
-       tdm_hwc_window_info info;
-       int info_changed;
-
-       tbm_surface_h surface;
-       int display_buffer_changed;
-       int enabled_flag;
-
-       /* client_type stores the initial type given to us by client(compositor),
-        *  validated_type stores the type after running Validate
-        */
-       tdm_hwc_window_composition client_type;
-       tdm_hwc_window_composition validated_type;
-
-       int candidate_layer_zpos;
-       int assigned_layer_zpos;
-};
-
-struct _tdm_exynos_display_buffer {
-       tdm_exynos_data *exynos_data;
-       unsigned int fb_id;
-       tbm_surface_h buffer;
-       int width;
-};
-
-struct _tdm_exynos_event_data {
-       tdm_exynos_event_type type;
-       tdm_exynos_output_data *output_data;
-       void *user_data;
-       int hwc_mode;
-};
-
-typedef struct _Drm_Event_Context {
-       void (*pageflip_handler)(int fd, unsigned int sequence, unsigned int tv_sec,
-                                                        unsigned int tv_usec, void *user_data);
-       void (*vblank_handler)(int fd, unsigned int sequence, unsigned int tv_sec,
-                                                  unsigned int tv_usec, void *user_data);
-       void (*pp_handler)(int fd, unsigned int  prop_id, unsigned int *buf_idx,
-                                          unsigned int  tv_sec, unsigned int  tv_usec, void *user_data);
-} Drm_Event_Context;
-
-#endif /* _TDM_EXYNOS_TYPES_H_ */