PKG_CHECK_MODULES(UDEV, libudev, [udev=yes], [udev=no])
-# for libtdm-exynos
-PKG_CHECK_MODULES(TDM_EXYNOS, libtdm libtbm [libdrm >= 2.4.47] libdrm_exynos)
-
# for libhal-backend-tdm-exynos
-PKG_CHECK_MODULES(LIBHAL_BACKEND_TDM_EXYNOS, hal-api-common hal-api-tdm hal-api-tbm libdrm libdrm_exynos dlog pixman-1)
+PKG_CHECK_MODULES(LIBHAL_BACKEND_TDM_EXYNOS, hal-api-common hal-api-tdm hal-api-tbm libtbm libdrm libdrm_exynos dlog pixman-1)
if test x"$udev" = xyes; then
AC_DEFINE(HAVE_UDEV,1,[Enable udev-based monitor hotplug detection])
- # for libtdm-exynos
- TDM_EXYNOS_CFLAGS="$TDM_EXYNOS_CFLAGS $UDEV_CFLAGS"
- TDM_EXYNOS_LIBS="$TDM_EXYNOS_LIBS $UDEV_LIBS"
-
# for libhal-backend-tdm-exynos
LIBHAL_BACKEND_TDM_EXYNOS_CFLAGS="$LIBHAL_BACKEND_TDM_EXYNOS_CFLAGS $UDEV_CFLAGS"
LIBHAL_BACKEND_TDM_EXYNOS_LIBS="$LIBHAL_BACKEND_TDM_EXYNOS_LIBS $UDEV_LIBS"
fi
-# for libtdm-exynos
-AC_SUBST(TDM_EXYNOS_CFLAGS)
-AC_SUBST(TDM_EXYNOS_LIBS)
-
# for libhal-backend-tdm-exynos
AC_SUBST(LIBHAL_BACKEND_TDM_EXYNOS_CFLAGS)
AC_SUBST(LIBHAL_BACKEND_TDM_EXYNOS_LIBS)
AC_DEFINE(HAVE_TILED_FORMAT, [1], [Enable tiled format])
fi
-# set the dir for the tdm module
-DEFAULT_TDM_MODULE_PATH="${libdir}/tdm"
-AC_ARG_WITH(tdm-module-path, AS_HELP_STRING([--with-tdm-module-path=PATH], [tdm module dir]),
- [ TDM_MODULE_PATH="$withval" ],
- [ TDM_MODULE_PATH="${DEFAULT_TDM_MODULE_PATH}" ])
-AC_SUBST(TDM_MODULE_PATH)
-
# set the library dir for the tdm hal backend
DEFAULT_HAL_LIBDIR="/hal/lib"
AC_ARG_WITH(hal-libdir, AS_HELP_STRING([--with-hal-libdir=PATH], [hal backend library path]),
# For enumerating devices in test case
AC_OUTPUT([
Makefile
- src/libhal-backend-tdm-exynos/Makefile
- src/libtdm-exynos/Makefile
src/Makefile])
echo ""
echo "TDM_EXYNOS_LIBS : $LIBHAL_BACKEND_TDM_EXYNOS_LIBS"
echo "TDM_MODULE_DIR : $HAL_LIBDIR"
echo ""
-echo ""
-echo "$PACKAGE_STRING will be compiled with:"
-echo ""
-echo "TDM_EXYNOS_CFLAGS : $TDM_EXYNOS_CFLAGS"
-echo "TDM_EXYNOS_LIBS : $TDM_EXYNOS_LIBS"
-echo "TDM_MODULE_DIR : $TDM_MODULE_PATH"
-echo ""
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+Name: hal-backend-tdm-exynos
+Version: 3.0.1
+Release: 0
+Summary: hal-backend-tdm module for exynos
+Group: System/Libraries
+License: MIT
+Source0: %{name}-%{version}.tar.gz
+Source1001: %{name}.manifest
+
+BuildRequires: pkgconfig(libdrm)
+BuildRequires: pkgconfig(libdrm_exynos)
+BuildRequires: pkgconfig(libudev)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(libtbm)
+BuildRequires: pkgconfig(hal-api-common)
+BuildRequires: pkgconfig(hal-api-tdm)
+BuildRequires: pkgconfig(hal-api-tbm)
+BuildRequires: pkgconfig(pixman-1)
+ExclusiveArch: %{arm} aarch64
+
+%description
+descriptionion: hal tdm backend module for exynos
+
+%global TZ_SYS_RO_SHARE %{?TZ_SYS_RO_SHARE:%TZ_SYS_RO_SHARE}%{!?TZ_SYS_RO_SHARE:/usr/share}
+
+%prep
+%setup -q
+cp %{SOURCE1001} .
+
+%build
+%reconfigure --prefix=%{_prefix} --libdir=%{_libdir} --disable-static \
+ --with-hal-libdir=%{_hal_libdir} \
+%if "%_repository" == "target-circle"
+ --enable-tiled-format \
+%endif
+ CFLAGS="${CFLAGS} -Wall -Werror" \
+ LDFLAGS="${LDFLAGS} -Wl,--hash-style=both -Wl,--as-needed"
+make %{?_smp_mflags}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+# make lincense directory and move COPY to it.
+mkdir -p %{buildroot}%{_hal_licensedir}/libhal-backend-tdm-exynos
+cp -af COPYING %{buildroot}%{_hal_licensedir}/libhal-backend-tdm-exynos
+
+
+%post
+if [ -f %{_hal_libdir}/libhal-backend-tdm.so ]; then
+ rm -rf %{_hal_libdir}/libhal-backend-tdm.so
+fi
+ln -s libhal-backend-tdm-exynos.so %{_hal_libdir}/libhal-backend-tdm.so
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest %{name}.manifest
+%{_hal_licensedir}/libhal-backend-tdm-exynos/COPYING
+%{_hal_libdir}/libhal-backend-*.so*
+++ /dev/null
-<manifest>
- <request>
- <domain name="_"/>
- </request>
-</manifest>
+++ /dev/null
-<manifest>
- <request>
- <domain name="_"/>
- </request>
-</manifest>
+++ /dev/null
-Name: libtdm-exynos
-Version: 3.0.1
-Release: 0
-Summary: Tizen Display Manager Exynos Back-End Library
-Group: Development/Libraries
-License: MIT
-Source0: %{name}-%{version}.tar.gz
-Source1001: %{name}.manifest
-Source1002: libhal-backend-tdm-exynos.manifest
-
-BuildRequires: pkgconfig(libdrm)
-BuildRequires: pkgconfig(libdrm_exynos)
-BuildRequires: pkgconfig(libudev)
-BuildRequires: pkgconfig(dlog)
-BuildRequires: pkgconfig(libtdm)
-BuildRequires: pkgconfig(libtbm)
-BuildRequires: pkgconfig(hal-api-common)
-BuildRequires: pkgconfig(hal-api-tdm)
-BuildRequires: pkgconfig(hal-api-tbm)
-BuildRequires: pkgconfig(pixman-1)
-ExclusiveArch: %{arm} aarch64
-
-%description
-Back-End library of Tizen Display Manager Exynos : libtdm-mgr Exynos library
-
-%package -n hal-backend-tdm-exynos
-Summary: hal-backend-tdm module for exynos
-Group: System/Libraries
-Requires: hal-api-tdm
-Requires: hal-api-common
-
-%description -n hal-backend-tdm-exynos
-descriptionion: hal tdm backend module for exynos
-
-%global TZ_SYS_RO_SHARE %{?TZ_SYS_RO_SHARE:%TZ_SYS_RO_SHARE}%{!?TZ_SYS_RO_SHARE:/usr/share}
-
-%prep
-%setup -q
-cp %{SOURCE1001} .
-cp %{SOURCE1002} .
-
-%build
-%reconfigure --prefix=%{_prefix} --libdir=%{_libdir} --disable-static \
- --with-hal-libdir=%{_hal_libdir} \
-%if "%_repository" == "target-circle"
- --enable-tiled-format \
-%endif
- CFLAGS="${CFLAGS} -Wall -Werror" \
- LDFLAGS="${LDFLAGS} -Wl,--hash-style=both -Wl,--as-needed"
-make %{?_smp_mflags}
-
-%install
-rm -rf %{buildroot}
-%make_install
-
-# make lincense directory and move COPY to it.
-mkdir -p %{buildroot}%{_hal_licensedir}/libhal-backend-tdm-exynos
-cp -af COPYING %{buildroot}%{_hal_licensedir}/libhal-backend-tdm-exynos
-
-%post
-if [ -f %{_libdir}/tdm/libtdm-default.so ]; then
- rm -rf %{_libdir}/tdm/libtdm-default.so
-fi
-ln -s libtdm-exynos.so %{_libdir}/tdm/libtdm-default.so
-
-%postun -p /sbin/ldconfig
-
-%post -n hal-backend-tdm-exynos
-if [ -f %{_hal_libdir}/libhal-backend-tdm.so ]; then
- rm -rf %{_hal_libdir}/libhal-backend-tdm.so
-fi
-ln -s libhal-backend-tdm-exynos.so %{_hal_libdir}/libhal-backend-tdm.so
-
-%postun -n hal-backend-tdm-exynos -p /sbin/ldconfig
-
-%files
-%defattr(-,root,root,-)
-%manifest %{name}.manifest
-%license COPYING
-%{_libdir}/tdm/libtdm-exynos.so
-
-%files -n hal-backend-tdm-exynos
-%manifest libhal-backend-tdm-exynos.manifest
-%{_hal_licensedir}/libhal-backend-tdm-exynos/COPYING
-%{_hal_libdir}/libhal-backend-*.so*
-SUBDIRS = libtdm-exynos libhal-backend-tdm-exynos
+AM_CFLAGS = \
+ $(LIBHAL_BACKEND_TDM_EXYNOS_CFLAGS) \
+ -I$(top_srcdir)/src
+
+libhal_backend_tdm_exynos_la_LTLIBRARIES = libhal-backend-tdm-exynos.la
+libhal_backend_tdm_exynos_ladir = @HAL_LIBDIR@
+libhal_backend_tdm_exynos_la_LDFLAGS = -module -avoid-version
+libhal_backend_tdm_exynos_la_LIBADD = $(LIBHAL_BACKEND_TDM_EXYNOS_LIBS) -ldl
+
+libhal_backend_tdm_exynos_la_SOURCES = \
+ tdm_backend_exynos.c \
+ tdm_backend_log.c \
+ tdm_exynos_capture_legacy.c \
+ tdm_exynos_capture.c \
+ tdm_exynos_display.c \
+ tdm_exynos_format.c \
+ tdm_exynos_hwc_window.c \
+ tdm_exynos_hwc.c \
+ tdm_exynos_layer.c \
+ tdm_exynos_output.c \
+ tdm_exynos_pp_legacy.c \
+ tdm_exynos_pp.c
+++ /dev/null
-AM_CFLAGS = \
- $(LIBHAL_BACKEND_TDM_EXYNOS_CFLAGS) \
- -I$(top_srcdir)/src/libhal-backend-tdm-exynos
-
-libhal_backend_tdm_exynos_la_LTLIBRARIES = libhal-backend-tdm-exynos.la
-libhal_backend_tdm_exynos_ladir = @HAL_LIBDIR@
-libhal_backend_tdm_exynos_la_LDFLAGS = -module -avoid-version
-libhal_backend_tdm_exynos_la_LIBADD = $(LIBHAL_BACKEND_TDM_EXYNOS_LIBS) -ldl
-
-libhal_backend_tdm_exynos_la_SOURCES = \
- tdm_backend_exynos.c \
- tdm_backend_log.c \
- tdm_exynos_capture_legacy.c \
- tdm_exynos_capture.c \
- tdm_exynos_display.c \
- tdm_exynos_format.c \
- tdm_exynos_hwc_window.c \
- tdm_exynos_hwc.c \
- tdm_exynos_layer.c \
- tdm_exynos_output.c \
- tdm_exynos_pp_legacy.c \
- tdm_exynos_pp.c
+++ /dev/null
-/**************************************************************************
-
-libtdm_exynos
-
-Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_backend_exynos.h"
-
-#if HAVE_UDEV
-#include <libudev.h>
-#endif
-
-#define EXYNOS_DRM_NAME "exynos"
-
-unsigned int exynos_screen_prerotation_hint;
-
-#ifdef HAVE_UDEV
-static hal_tdm_error
-_tdm_exynos_udev_fd_handler(int fd, hal_tdm_event_loop_mask mask, void *user_data)
-{
- tdm_exynos_display *display_data = (tdm_exynos_display *)user_data;
- struct udev_device *dev;
- const char *hotplug;
- struct stat s;
- dev_t udev_devnum;
- int ret;
-
- dev = udev_monitor_receive_device(display_data->uevent_monitor);
- if (!dev) {
- TDM_BACKEND_ERR("couldn't receive device");
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- udev_devnum = udev_device_get_devnum(dev);
-
- ret = fstat(display_data->drm_fd, &s);
- if (ret == -1) {
- TDM_BACKEND_ERR("fstat failed");
- udev_device_unref(dev);
- return HAL_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_BACKEND_INFO("HotPlug");
- tdm_exynos_display_update_output_status(display_data);
- }
-
- udev_device_unref(dev);
-
- return HAL_TDM_ERROR_NONE;
-}
-
-static struct udev_monitor *
-_tdm_exynos_create_udev_monitor()
-{
- struct udev *u = NULL;
- struct udev_monitor *mon = NULL;
-
- u = udev_new();
- if (!u) {
- TDM_BACKEND_ERR("couldn't create udev");
- goto failed;
- }
-
- mon = udev_monitor_new_from_netlink(u, "udev");
- if (!mon) {
- TDM_BACKEND_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_BACKEND_ERR("add match subsystem failed");
- goto failed;
- }
-
- TDM_BACKEND_INFO("hotplug monitor created");
-
- return mon;
-
-failed:
- if (mon)
- udev_monitor_unref(mon);
- if (u)
- udev_unref(u);
-
- return NULL;
-}
-
-static void
-_tdm_exynos_destroy_udev_monitor(struct udev_monitor *mon)
-{
- struct udev *u;
-
- if (!mon)
- return;
-
- u = udev_monitor_get_udev(mon);
- udev_monitor_unref(mon);
- udev_unref(u);
-
- TDM_BACKEND_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_BACKEND_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_BACKEND_WRN("Cannot open drm device.. search by udev");
- udev = udev_new();
- if (!udev) {
- TDM_BACKEND_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_BACKEND_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_BACKEND_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_BACKEND_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_BACKEND_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;
-}
-
-static void
-_tdm_exynos_display_deinitialize(tdm_exynos_display *display_data)
-{
- if (display_data->use_ippv2)
- drmRemoveUserHandler(display_data->drm_fd, _tdm_exynos_drm_user_handler);
- else
- drmRemoveUserHandler(display_data->drm_fd, _tdm_exynos_drm_user_handler_legacy);
-
- tdm_exynos_display_destroy_output_list(display_data);
-
- if (display_data->plane_res)
- drmModeFreePlaneResources(display_data->plane_res);
- if (display_data->mode_res)
- drmModeFreeResources(display_data->mode_res);
-}
-
-static hal_tdm_error
-_tdm_exynos_display_initialize(tdm_exynos_display *display_data)
-{
- hal_tdm_error ret;
- drmVersionPtr drm_version;
-
- drm_version = drmGetVersion(display_data->drm_fd);
- if (!drm_version) {
- TDM_BACKEND_ERR("no drm version: %m");
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- goto done;
- } else {
- TDM_BACKEND_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))
- display_data->use_ippv2 = 1;
- drmFreeVersion(drm_version);
- }
-
- if (display_data->use_ippv2)
- drmAddUserHandler(display_data->drm_fd, _tdm_exynos_drm_user_handler);
- else
- drmAddUserHandler(display_data->drm_fd, _tdm_exynos_drm_user_handler_legacy);
-
- if (drmSetClientCap(display_data->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) < 0)
- TDM_BACKEND_WRN("Set DRM_CLIENT_CAP_UNIVERSAL_PLANES failed");
-
- display_data->mode_res = drmModeGetResources(display_data->drm_fd);
- if (!display_data->mode_res) {
- TDM_BACKEND_ERR("no drm resource: %m");
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- goto done;
- }
-
- display_data->plane_res = drmModeGetPlaneResources(display_data->drm_fd);
- if (!display_data->plane_res) {
- TDM_BACKEND_ERR("no drm plane resource: %m");
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- goto done;
- }
-
- if (display_data->plane_res->count_planes <= 0) {
- TDM_BACKEND_ERR("no drm plane resource");
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- goto done;
- }
-
- ret = tdm_exynos_display_get_property(display_data,
- display_data->plane_res->planes[0],
- DRM_MODE_OBJECT_PLANE, "zpos", NULL,
- &display_data->is_immutable_zpos);
- if (ret == HAL_TDM_ERROR_NONE) {
- display_data->has_zpos_info = 1;
- if (display_data->is_immutable_zpos)
- TDM_BACKEND_DBG("plane has immutable zpos info");
- } else
- TDM_BACKEND_DBG("plane doesn't have zpos info");
-
- if (display_data->use_ippv2) {
- ret = tdm_exynos_pp_init(display_data);
- if (ret != HAL_TDM_ERROR_NONE)
- goto done;
- }
-
- ret = tdm_exynos_display_create_output_list(display_data);
- if (ret != HAL_TDM_ERROR_NONE)
- goto done;
-
- ret = tdm_exynos_display_create_layer_list(display_data);
- if (ret != HAL_TDM_ERROR_NONE)
- goto done;
-
-done:
- return ret;
-}
-
-static hal_tdm_error
-_tdm_exynos_master_drm_fd_handler(hal_tdm_fd master_drm_fd, void *user_data)
-{
- tdm_exynos_display *display_data = (tdm_exynos_display *) user_data;
- hal_tdm_error ret;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- display_data->drm_fd = master_drm_fd;
- TDM_BACKEND_INFO("Get the master drm_fd(%d)!\n", display_data->drm_fd);
-
- // initialize display with a master drm_fd
- ret = _tdm_exynos_display_initialize(display_data);
- if (ret != HAL_TDM_ERROR_NONE) {
- TDM_BACKEND_ERR("fail to _tdm_exynos_display_initialize!\n");
- _tdm_exynos_display_deinitialize(display_data);
-
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- return HAL_TDM_ERROR_NONE;
-}
-
-int
-hal_backend_tdm_exynos_exit(void *data)
-{
- hal_tdm_backend_data *backend_data = (hal_tdm_backend_data *)data;
- tdm_exynos_display *display_data;
-
- TDM_BACKEND_INFO("deinit");
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(backend_data != NULL, -1);
-
- display_data = (tdm_exynos_display *)backend_data->display;
- TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data != NULL, -1);
-
- if (backend_data->capture_funcs) {
- free(backend_data->capture_funcs);
- backend_data->capture_funcs = NULL;
- }
- if (backend_data->pp_funcs) {
- free(backend_data->pp_funcs);
- backend_data->pp_funcs = NULL;
- }
- if (backend_data->hwc_window_funcs) {
- free(backend_data->hwc_window_funcs);
- backend_data->hwc_window_funcs = NULL;
- }
- if (backend_data->hwc_funcs) {
- free(backend_data->hwc_funcs);
- backend_data->hwc_funcs = NULL;
- }
- if (backend_data->output_funcs) {
- free(backend_data->output_funcs);
- backend_data->output_funcs = NULL;
- }
- if (backend_data->display_funcs) {
- free(backend_data->display_funcs);
- backend_data->display_funcs = NULL;
- }
-
- _tdm_exynos_display_deinitialize(display_data);
-
-#ifdef HAVE_UDEV
- if (display_data->uevent_monitor)
- _tdm_exynos_destroy_udev_monitor(display_data->uevent_monitor);
-#endif
-
- if (display_data->drm_fd >= 0)
- close(display_data->drm_fd);
-
- free(display_data);
- free(backend_data);
-
- return HAL_TDM_ERROR_NONE;
-}
-
-static int
-hal_backend_tdm_exynos_init(void **data)
-{
- hal_tdm_backend_data *backend_data = NULL;
- hal_tdm_display_funcs *display_funcs = NULL;
- hal_tdm_output_funcs *output_funcs = NULL;
- hal_tdm_hwc_funcs *hwc_funcs = NULL;
- hal_tdm_hwc_window_funcs *hwc_window_funcs = NULL;
- hal_tdm_pp_funcs *pp_funcs = NULL;
- hal_tdm_capture_funcs *capture_funcs = NULL;
- tdm_exynos_display *display_data = NULL;
- hal_tdm_error ret;
- int drm_fd;
- const char *value;
-#ifdef HAVE_UDEV
- static struct udev_monitor *mon;
- hal_tdm_event_source *udev_event_source;
-#endif
-
- /* allocate a hal_tdm_backend_data */
- backend_data = calloc(1, sizeof(struct _hal_tdm_backend_data));
- if (!backend_data) {
- TDM_BACKEND_ERR("fail to alloc backend_data!\n");
- *data = NULL;
- return -1;
- }
- *data = backend_data;
-
- /* allocate a hal_tdm_display */
- display_data = calloc(1, sizeof(struct _tdm_exynos_display));
- if (!display_data) {
- TDM_BACKEND_ERR("fail to alloc display_data!\n");
- goto failed;
- }
- backend_data->display = (hal_tdm_display *)display_data;
-
- LIST_INITHEAD(&display_data->output_list);
- LIST_INITHEAD(&display_data->buffer_list);
-
- value = (const char*)getenv("SCREEN_PREROTATION_HINT");
- if (value) {
- char *end;
- exynos_screen_prerotation_hint = strtol(value, &end, 10);
- TDM_BACKEND_INFO("SCREEN_PREROTATION_HINT = %d", exynos_screen_prerotation_hint);
- }
-
- // check if drm_fd is master fd.
- drm_fd = _tdm_exynos_open_drm();
- if (drm_fd < 0) {
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- goto failed;
- }
-
- // set true when backend has a drm_device.
- backend_data->has_drm_device = 1;
-
- if (drmIsMaster(drm_fd)) {
- // drm_fd is a master drm_fd.
- backend_data->drm_info.drm_fd = drm_fd;
- backend_data->drm_info.is_master = 1;
-
- display_data->drm_fd = drm_fd;
- TDM_BACKEND_INFO("Get the master drm_fd(%d)!\n", display_data->drm_fd);
-
- // initialize display with a master drm_fd
- ret = _tdm_exynos_display_initialize(display_data);
- if (ret != HAL_TDM_ERROR_NONE) {
- TDM_BACKEND_ERR("fail to _tdm_exynos_display_initialize!\n");
- goto failed;
- }
- } else {
- // drm_fd is not a master drm_fd.
- // request a master drm_fd
- close(drm_fd);
- backend_data->drm_info.drm_fd = -1;
- backend_data->drm_info.is_master = 0;
- backend_data->drm_info.master_drm_fd_func = _tdm_exynos_master_drm_fd_handler;
- backend_data->drm_info.user_data = display_data;
-
- TDM_BACKEND_INFO("A backend requests an master drm_fd.\n");
- }
-
-#ifdef HAVE_UDEV
- mon = _tdm_exynos_create_udev_monitor();
- if (!mon) {
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- goto failed;
- }
- display_data->uevent_monitor = mon;
-
- /* alloc and register udev_event_source */
- udev_event_source = calloc(1, sizeof(struct _hal_tdm_event_source));
- if (!udev_event_source) {
- TDM_BACKEND_ERR("fail to alloc udev_event_source!\n");
- goto failed;
- }
- udev_event_source->event_fd = udev_monitor_get_fd(mon);
- udev_event_source->func = _tdm_exynos_udev_fd_handler;
- udev_event_source->user_data = display_data;
-
- backend_data->event_sources[0] = udev_event_source;
- backend_data->num_event_sources++;
-#endif
-
- /* alloc and register display_funcs */
- display_funcs = calloc(1, sizeof(struct _hal_tdm_display_funcs));
- if (!display_funcs) {
- TDM_BACKEND_ERR("fail to alloc display_funcs!\n");
- goto failed;
- }
- backend_data->display_funcs = display_funcs;
-
- display_funcs->display_get_capability = exynos_display_get_capability;
- display_funcs->display_get_pp_capability = exynos_display_get_pp_capability;
- display_funcs->display_get_capture_capability = exynos_display_get_capture_capability;
- display_funcs->display_get_outputs = exynos_display_get_outputs;
- display_funcs->display_get_fd = exynos_display_get_fd;
- display_funcs->display_handle_events = exynos_display_handle_events;
- display_funcs->display_create_pp = exynos_display_create_pp;
-
- /* alloc and register output_funcs */
- output_funcs = calloc(1, sizeof(struct _hal_tdm_output_funcs));
- if (!output_funcs) {
- TDM_BACKEND_ERR("fail to alloc output_funcs!\n");
- goto failed;
- }
- backend_data->output_funcs = output_funcs;
-
- output_funcs->output_get_capability = exynos_output_get_capability;
- output_funcs->output_set_property = exynos_output_set_property;
- output_funcs->output_get_property = exynos_output_get_property;
- output_funcs->output_wait_vblank = exynos_output_wait_vblank;
- output_funcs->output_set_vblank_handler = exynos_output_set_vblank_handler;
- output_funcs->output_set_dpms = exynos_output_set_dpms;
- output_funcs->output_get_dpms = exynos_output_get_dpms;
- output_funcs->output_set_mode = exynos_output_set_mode;
- output_funcs->output_get_mode = exynos_output_get_mode;
- output_funcs->output_create_capture = exynos_output_create_capture;
-#ifdef HAVE_UDEV
- output_funcs->output_set_status_handler = exynos_output_set_status_handler;
-#endif
- output_funcs->output_get_hwc = exynos_output_get_hwc;
-
- /* alloc and register hwc_funcs */
- hwc_funcs = calloc(1, sizeof(struct _hal_tdm_hwc_funcs));
- if (!hwc_funcs) {
- TDM_BACKEND_ERR("fail to alloc hwc_funcs!\n");
- goto failed;
- }
- backend_data->hwc_funcs = hwc_funcs;
-
- hwc_funcs->hwc_create_window = exynos_hwc_create_window;
- hwc_funcs->hwc_get_video_supported_formats = exynos_hwc_get_video_supported_formats;
- hwc_funcs->hwc_get_capabilities = exynos_hwc_get_capabilities;
- hwc_funcs->hwc_get_available_properties = exynos_hwc_get_available_properties;
- hwc_funcs->hwc_get_client_target_buffer_queue = exynos_hwc_get_client_target_buffer_queue;
- hwc_funcs->hwc_set_client_target_buffer = exynos_hwc_set_client_target_buffer;
- hwc_funcs->hwc_validate = exynos_hwc_validate;
- hwc_funcs->hwc_get_changed_composition_types = exynos_hwc_get_changed_composition_types;
- hwc_funcs->hwc_accept_validation = exynos_hwc_accept_validation;
- hwc_funcs->hwc_commit = exynos_hwc_commit;
- hwc_funcs->hwc_set_commit_handler = exynos_hwc_set_commit_handler;
-
- /* alloc and register hwc_window_funcs */
- hwc_window_funcs = calloc(1, sizeof(struct _hal_tdm_hwc_window_funcs));
- if (!hwc_window_funcs) {
- TDM_BACKEND_ERR("fail to alloc hwc_window_funcs!\n");
- goto failed;
- }
- backend_data->hwc_window_funcs = hwc_window_funcs;
-
- hwc_window_funcs->hwc_window_destroy = exynos_hwc_window_destroy;
- hwc_window_funcs->hwc_window_acquire_buffer_queue = NULL;
- hwc_window_funcs->hwc_window_release_buffer_queue = NULL;
- hwc_window_funcs->hwc_window_set_composition_type = exynos_hwc_window_set_composition_type;
- hwc_window_funcs->hwc_window_set_buffer_damage = exynos_hwc_window_set_buffer_damage;
- hwc_window_funcs->hwc_window_set_info = exynos_hwc_window_set_info;
- hwc_window_funcs->hwc_window_set_buffer = exynos_hwc_window_set_buffer;
- hwc_window_funcs->hwc_window_set_property = exynos_hwc_window_set_property;
- hwc_window_funcs->hwc_window_get_property = exynos_hwc_window_get_property;
- hwc_window_funcs->hwc_window_get_constraints = exynos_hwc_window_get_constraints;
-
- /* alloc and register pp_funcs */
- pp_funcs = calloc(1, sizeof(struct _hal_tdm_pp_funcs));
- if (!pp_funcs) {
- TDM_BACKEND_ERR("fail to alloc pp_funcs!\n");
- goto failed;
- }
- backend_data->pp_funcs = pp_funcs;
-
- if (display_data->use_ippv2) {
- pp_funcs->pp_destroy = exynos_pp_destroy;
- pp_funcs->pp_set_info = exynos_pp_set_info;
- pp_funcs->pp_attach = exynos_pp_attach;
- pp_funcs->pp_commit = exynos_pp_commit;
- pp_funcs->pp_set_done_handler = exynos_pp_set_done_handler;
- } else {
- pp_funcs->pp_destroy = exynos_pp_legacy_destroy;
- pp_funcs->pp_set_info = exynos_pp_legacy_set_info;
- pp_funcs->pp_attach = exynos_pp_legacy_attach;
- pp_funcs->pp_commit = exynos_pp_legacy_commit;
- pp_funcs->pp_set_done_handler = exynos_pp_legacy_set_done_handler;
- }
-
- /* alloc and register capture_funcs */
- capture_funcs = calloc(1, sizeof(struct _hal_tdm_capture_funcs));
- if (!capture_funcs) {
- TDM_BACKEND_ERR("fail to alloc pp_funcs!\n");
- goto failed;
- }
- backend_data->capture_funcs = capture_funcs;
-
- if (display_data->use_ippv2) {
- capture_funcs->capture_destroy = exynos_capture_destroy;
- capture_funcs->capture_set_info = exynos_capture_set_info;
- capture_funcs->capture_attach = exynos_capture_attach;
- capture_funcs->capture_commit = exynos_capture_commit;
- capture_funcs->capture_set_done_handler = exynos_capture_set_done_handler;
- } else {
- capture_funcs->capture_destroy = exynos_capture_legacy_destroy;
- capture_funcs->capture_set_info = exynos_capture_legacy_set_info;
- capture_funcs->capture_attach = exynos_capture_legacy_attach;
- capture_funcs->capture_commit = exynos_capture_legacy_commit;
- capture_funcs->capture_set_done_handler = exynos_capture_legacy_set_done_handler;
- }
-
- TDM_BACKEND_INFO("init success!");
-
- return HAL_TDM_ERROR_NONE;
-
-failed:
- TDM_BACKEND_ERR("init failed!");
-
- hal_backend_tdm_exynos_exit((void *)backend_data);
-
- return -1;
-}
-
-hal_backend hal_backend_tdm_data = {
- "exynos",
- "Samsung",
- HAL_ABI_VERSION_TIZEN_6_5,
- hal_backend_tdm_exynos_init,
- hal_backend_tdm_exynos_exit
-};
+++ /dev/null
-/**************************************************************************
-
-libtdm_exynos
-
-Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifndef _TDM_EXYNOS_H_
-#define _TDM_EXYNOS_H_
-
-#include "tdm_backend_exynos_types.h"
-
-extern unsigned int exynos_screen_prerotation_hint;
-
-/* display funcs */
-hal_tdm_error exynos_display_get_capability(hal_tdm_display *display, hal_tdm_caps_display *caps);
-hal_tdm_error exynos_display_get_pp_capability(hal_tdm_display *display, hal_tdm_caps_pp *caps);
-hal_tdm_error exynos_display_get_capture_capability(hal_tdm_display *display, hal_tdm_caps_capture *caps);
-hal_tdm_output **exynos_display_get_outputs(hal_tdm_display *display, int *count, hal_tdm_error *error);
-hal_tdm_error exynos_display_get_fd(hal_tdm_display *display, int *fd);
-hal_tdm_error exynos_display_handle_events(hal_tdm_display *display);
-hal_tdm_pp* exynos_display_create_pp(hal_tdm_display *display, hal_tdm_error *error);
-
-/* output funcs */
-hal_tdm_error exynos_output_get_capability(hal_tdm_output *output, hal_tdm_caps_output *caps);
-hal_tdm_error exynos_output_set_property(hal_tdm_output *output, unsigned int id, hal_tdm_value value);
-hal_tdm_error exynos_output_get_property(hal_tdm_output *output, unsigned int id, hal_tdm_value *value);
-hal_tdm_error exynos_output_wait_vblank(hal_tdm_output *output, int interval, int sync, void *user_data);
-hal_tdm_error exynos_output_set_vblank_handler(hal_tdm_output *output, hal_tdm_output_vblank_handler func);
-hal_tdm_error exynos_output_commit(hal_tdm_output *output, int sync, void *user_data);
-hal_tdm_error exynos_output_set_commit_handler(hal_tdm_output *output, hal_tdm_output_commit_handler func);
-hal_tdm_error exynos_output_set_dpms(hal_tdm_output *output, hal_tdm_output_dpms dpms_value);
-hal_tdm_error exynos_output_get_dpms(hal_tdm_output *output, hal_tdm_output_dpms *dpms_value);
-hal_tdm_error exynos_output_set_mode(hal_tdm_output *output, const hal_tdm_output_mode *mode);
-hal_tdm_error exynos_output_get_mode(hal_tdm_output *output, const hal_tdm_output_mode **mode);
-hal_tdm_capture *exynos_output_create_capture(hal_tdm_output *output, hal_tdm_error *error);
-hal_tdm_error exynos_output_set_status_handler(hal_tdm_output *output, hal_tdm_output_status_handler func, void *user_data);
-hal_tdm_hwc *exynos_output_get_hwc(hal_tdm_output *output, hal_tdm_error *error);
-
-/* hwc funcs */
-hal_tdm_hwc_window *exynos_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_error *error);
-hal_tdm_error exynos_hwc_get_video_supported_formats(hal_tdm_hwc *hwc, const tbm_format **formats, int *count);
-hal_tdm_error exynos_hwc_get_capabilities(hal_tdm_hwc *hwc, hal_tdm_hwc_capability *capabilities);
-hal_tdm_error exynos_hwc_get_available_properties(hal_tdm_hwc *hwc, const hal_tdm_prop **props, int *count);
-tbm_surface_queue_h exynos_hwc_get_client_target_buffer_queue(hal_tdm_hwc *hwc, hal_tdm_error *error);
-hal_tdm_error exynos_hwc_set_client_target_buffer(hal_tdm_hwc *hwc, tbm_surface_h buffer, hal_tdm_region damage);
-hal_tdm_error exynos_hwc_validate(hal_tdm_hwc *hwc, hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types);
-hal_tdm_error exynos_hwc_get_changed_composition_types(hal_tdm_hwc *hwc, uint32_t *num_elements, hal_tdm_hwc_window **hwc_wnds, hal_tdm_hwc_window_composition *composition_types);
-hal_tdm_error exynos_hwc_accept_validation(hal_tdm_hwc *hwc);
-hal_tdm_error exynos_hwc_commit(hal_tdm_hwc *hwc, int sync, void *user_data);
-hal_tdm_error exynos_hwc_set_commit_handler(hal_tdm_hwc *hwc, hal_tdm_hwc_commit_handler func);
-
-/* hwc_window funcs */
-void exynos_hwc_window_destroy(hal_tdm_hwc_window *hwc_window);
-hal_tdm_error exynos_hwc_window_set_composition_type(hal_tdm_hwc_window *hwc_window, hal_tdm_hwc_window_composition composition_type);
-hal_tdm_error exynos_hwc_window_set_buffer_damage(hal_tdm_hwc_window *hwc_window, hal_tdm_region damage);
-hal_tdm_error exynos_hwc_window_set_info(hal_tdm_hwc_window *hwc_window, hal_tdm_hwc_window_info *info);
-hal_tdm_error exynos_hwc_window_set_buffer(hal_tdm_hwc_window *hwc_window, tbm_surface_h surface);
-hal_tdm_error exynos_hwc_window_set_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value value);
-hal_tdm_error exynos_hwc_window_get_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value *value);
-hal_tdm_error exynos_hwc_window_get_constraints(hal_tdm_hwc_window *hwc_window, int *constraints);
-
-/* pp funcs */
-void exynos_pp_legacy_destroy(hal_tdm_pp *pp);
-hal_tdm_error exynos_pp_legacy_set_info(hal_tdm_pp *pp, hal_tdm_info_pp *info);
-hal_tdm_error exynos_pp_legacy_attach(hal_tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst);
-hal_tdm_error exynos_pp_legacy_commit(hal_tdm_pp *pp);
-hal_tdm_error exynos_pp_legacy_set_done_handler(hal_tdm_pp *pp, hal_tdm_pp_done_handler func, void *user_data);
-
-void exynos_pp_destroy(hal_tdm_pp *pp);
-hal_tdm_error exynos_pp_set_info(hal_tdm_pp *pp, hal_tdm_info_pp *info);
-hal_tdm_error exynos_pp_attach(hal_tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst);
-hal_tdm_error exynos_pp_commit(hal_tdm_pp *pp);
-hal_tdm_error exynos_pp_set_done_handler(hal_tdm_pp *pp, hal_tdm_pp_done_handler func, void *user_data);
-
-/* capture funcs */
-void exynos_capture_legacy_destroy(hal_tdm_capture *capture);
-hal_tdm_error exynos_capture_legacy_set_info(hal_tdm_capture *capture, hal_tdm_info_capture *info);
-hal_tdm_error exynos_capture_legacy_attach(hal_tdm_capture *capture, tbm_surface_h buffer);
-hal_tdm_error exynos_capture_legacy_commit(hal_tdm_capture *capture);
-hal_tdm_error exynos_capture_legacy_set_done_handler(hal_tdm_pp *pp, hal_tdm_capture_done_handler func, void *user_data);
-
-void exynos_capture_destroy(hal_tdm_capture *capture);
-hal_tdm_error exynos_capture_set_info(hal_tdm_capture *capture, hal_tdm_info_capture *info);
-hal_tdm_error exynos_capture_attach(hal_tdm_capture *capture, tbm_surface_h buffer);
-hal_tdm_error exynos_capture_commit(hal_tdm_capture *capture);
-hal_tdm_error exynos_capture_set_done_handler(hal_tdm_pp *pp, hal_tdm_capture_done_handler func, void *user_data);
-
-/* exynos display */
-void tdm_exynos_display_update_output_status(tdm_exynos_display *display_data);
-hal_tdm_error tdm_exynos_display_create_output_list(tdm_exynos_display *display_data);
-void tdm_exynos_display_destroy_output_list(tdm_exynos_display *display_data);
-hal_tdm_error tdm_exynos_display_create_layer_list(tdm_exynos_display *display_data);
-hal_tdm_error tdm_exynos_display_set_property(tdm_exynos_display *display_data, unsigned int obj_id, unsigned int obj_type, const char *name, unsigned int value);
-hal_tdm_error tdm_exynos_display_get_property(tdm_exynos_display *display_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, hal_tdm_output_mode *tdm_mode);
-
-/* exynos output */
-void tdm_exynos_output_cb_event(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data);
-hal_tdm_error tdm_exynos_output_update_status(tdm_exynos_output *output_data, hal_tdm_output_conn_status status);
-
-/* exynos hwc */
-hal_tdm_error exynos_hwc_initailize_target_window(tdm_exynos_hwc *hwc_data, int width, int height);
-
-/* exynos layer */
-hal_tdm_error tdm_exynos_layer_get_capability(tdm_exynos_layer *layer_data, tdm_exynos_caps_layer *caps);
-hal_tdm_error tdm_exynos_layer_set_property(tdm_exynos_layer *layer_data, unsigned int id, hal_tdm_value value);
-hal_tdm_error tdm_exynos_layer_get_property(tdm_exynos_layer *layer_data, unsigned int id, hal_tdm_value *value);
-hal_tdm_error tdm_exynos_layer_set_info(tdm_exynos_layer *layer_data, tdm_exynos_layer_info *info);
-hal_tdm_error tdm_exynos_layer_get_info(tdm_exynos_layer *layer_data, tdm_exynos_layer_info *info);
-hal_tdm_error tdm_exynos_layer_set_buffer(tdm_exynos_layer *layer_data, tbm_surface_h buffer);
-hal_tdm_error tdm_exynos_layer_unset_buffer(tdm_exynos_layer *layer_data);
-hal_tdm_error tdm_exynos_layer_get_supported_format(tdm_exynos_layer *layer_data, const tbm_format **out_formats, int *out_format_count);
-hal_tdm_error tdm_exynos_layer_get_available_properties(tdm_exynos_layer *layer_data, const hal_tdm_prop **out_props, int *out_prop_count);
-
-/* exynos pp */
-hal_tdm_error tdm_exynos_pp_legacy_get_capability(tdm_exynos_display *display_data, hal_tdm_caps_pp *caps);
-hal_tdm_pp *tdm_exynos_pp_legacy_create(tdm_exynos_display *display_data, hal_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);
-
-hal_tdm_error tdm_exynos_pp_init(tdm_exynos_display *display_data);
-hal_tdm_error tdm_exynos_pp_get_capability(tdm_exynos_display *display_data, hal_tdm_caps_pp *caps);
-hal_tdm_pp *tdm_exynos_pp_create(tdm_exynos_display *display_data, hal_tdm_error *error);
-void tdm_exynos_pp_handler(unsigned int tv_sec, unsigned int tv_usec, void *data);
-
-/* exynos capture */
-hal_tdm_error tdm_exynos_capture_legacy_get_capability(tdm_exynos_display *display_data, hal_tdm_caps_capture *caps);
-hal_tdm_pp *tdm_exynos_capture_legacy_create_output(tdm_exynos_display *display_data, hal_tdm_output *output, hal_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);
-
-hal_tdm_error tdm_exynos_capture_get_capability(tdm_exynos_display *display_data, hal_tdm_caps_capture *caps);
-hal_tdm_pp *tdm_exynos_capture_create_output(tdm_exynos_display *display_data, hal_tdm_output *output, hal_tdm_error *error);
-
-/* exynos format */
-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_H_ */
+++ /dev/null
-/**************************************************************************
-
-libtdm_exynos
-
-Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#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 <linux/fb.h>
-#include <drm.h>
-#include <drm_fourcc.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 <hal-common.h>
-#include <hal-tdm-types.h>
-#include <hal-tdm-interface.h>
-#include <pixman.h>
-
-#include "tdm_backend_log.h"
-#include "tdm_backend_list.h"
-
-/* exynos module internal macros, structures */
-#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)
-
-typedef struct _tdm_exynos_display tdm_exynos_display;
-typedef struct _tdm_exynos_output tdm_exynos_output;
-typedef struct _tdm_exynos_layer tdm_exynos_layer;
-typedef struct _tdm_exynos_hwc tdm_exynos_hwc;
-typedef struct _tdm_exynos_hwc_window tdm_exynos_hwc_window;
-typedef struct _tdm_exynos_event tdm_exynos_event;
-typedef struct _tdm_exynos_display_buffer tdm_exynos_display_buffer;
-
-typedef enum {
- TDM_EXYNOS_EVENT_TYPE_WAIT,
- TDM_EXYNOS_EVENT_TYPE_COMMIT,
- TDM_EXYNOS_EVENT_TYPE_PAGEFLIP,
-} tdm_exynos_event_type;
-
-typedef enum {
- TDM_EXYNOS_LAYER_CAPABILITY_CURSOR = (1 << 0), /**< cursor */
- TDM_EXYNOS_LAYER_CAPABILITY_PRIMARY = (1 << 1), /**< primary */
- TDM_EXYNOS_LAYER_CAPABILITY_OVERLAY = (1 << 2), /**< overlay */
- TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC = (1 << 4), /**< graphic */
- TDM_EXYNOS_LAYER_CAPABILITY_VIDEO = (1 << 5), /**< video */
- TDM_EXYNOS_LAYER_CAPABILITY_SCALE = (1 << 8), /**< if a layer_data has scale capability */
- TDM_EXYNOS_LAYER_CAPABILITY_TRANSFORM = (1 << 9), /**< if a layer_data has transform capability */
- TDM_EXYNOS_LAYER_CAPABILITY_SCANOUT = (1 << 10), /**< if a layer_data allows a scanout buffer only */
- TDM_EXYNOS_LAYER_CAPABILITY_RESEVED_MEMORY = (1 << 11), /**< if a layer_data allows a reserved buffer only */
- TDM_EXYNOS_LAYER_CAPABILITY_NO_CROP = (1 << 12), /**< if a layer_data has no cropping capability */
-} tdm_exynos_layer_capability;
-
-struct _tdm_exynos_display {
- int drm_fd;
-
-#if HAVE_UDEV
- struct udev_monitor *uevent_monitor;
-#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;
-
- struct list_head output_list;
- struct list_head buffer_list;
-
- int use_ippv2;
- int ipp_module_id;
-};
-
-struct _tdm_exynos_output {
- struct list_head link;
-
- /* data which are fixed at initializing */
- tdm_exynos_display *display_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;
- hal_tdm_output_mode *output_modes;
- hal_tdm_output_type connector_type;
- unsigned int connector_type_id;
- struct list_head layer_list;
- tdm_exynos_layer *primary_layer;
-
- /* not fixed data below */
- hal_tdm_output_vblank_handler vblank_func;
- hal_tdm_output_commit_handler commit_func;
-
- hal_tdm_output_conn_status status;
- hal_tdm_output_status_handler status_func;
- void *status_user_data;
-
- int mode_changed;
- const hal_tdm_output_mode *current_mode;
-
- int crtc_set;
-
- /* hwc data */
- tdm_exynos_hwc *hwc_data;
-};
-
-typedef struct _tdm_exynos_layer_info {
- hal_tdm_info_config src_config;
- hal_tdm_pos dst_pos;
- hal_tdm_transform transform;
-} tdm_exynos_layer_info;
-
-typedef struct _tdm_exynos_caps_layer {
- tdm_exynos_layer_capability capabilities; /**< The capabilities of layer_data */
-
- /**
- * The z-order
- * GRAPHIC layers are non-changeable. The zpos of GRAPHIC layers starts
- * from 0. If there are 4 GRAPHIC layers, The zpos SHOULD be 0, 1, 2, 3.\n
- * But the zpos of VIDEO layer_data is changeable by layer_set_video_pos() function
- * of #tdm_func_layer. And The zpos of VIDEO layers is less than GRAPHIC
- * layers or more than GRAPHIC layers.
- * ie, ..., -2, -1, 4, 5, ... (if 0 <= GRAPHIC layer_data's zpos < 4).
- * The zpos of VIDEO layers is @b relative. It doesn't need to start
- * from -1 or 4. Let's suppose that there are two VIDEO layers.
- * One has -2 zpos. Another has -4 zpos. Then -2 Video layer_data is higher
- * than -4 VIDEO layer_data.
- */
- int zpos;
-
- unsigned int format_count; /**< The count of available formats */
- tbm_format *formats; /**< The @b newly-allocated array of formats. will be freed in frontend. */
-
- unsigned int prop_count; /**< The count of available properties */
- hal_tdm_prop *props; /**< The @b newly-allocated array of properties. will be freed in frontend. */
-} tdm_exynos_caps_layer;
-
-struct _tdm_exynos_layer {
- struct list_head link;
-
- /* data which are fixed at initializing */
- tdm_exynos_display *display_data;
- tdm_exynos_output *output_data;
- uint32_t plane_id;
- tdm_exynos_layer_capability capabilities;
- int zpos;
-
- /* not fixed data below */
- tdm_exynos_layer_info 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;
-
- hal_tdm_prop *props;
- int prop_count;
-};
-
-struct _tdm_exynos_hwc {
- tdm_exynos_hwc_window *target_hwc_window;
-
- int need_validate;
- int need_target_window;
-
- int target_window_zpos;
-
- tdm_exynos_output *output_data;
- struct list_head hwc_window_list;
-
- hal_tdm_hwc_commit_handler commit_func;
-};
-
-struct _tdm_exynos_hwc_window {
- struct list_head link;
-
- /* data which are fixed at initializing */
- tdm_exynos_hwc *hwc_data;
-
- /* not fixed data below */
- hal_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
- */
- hal_tdm_hwc_window_composition client_type;
- hal_tdm_hwc_window_composition validated_type;
-
- int candidate_layer_zpos;
- int assigned_layer_zpos;
-};
-
-struct _tdm_exynos_display_buffer {
- tdm_exynos_display *display_data;
- unsigned int fb_id;
- tbm_surface_h buffer;
- int width;
-};
-
-struct _tdm_exynos_event {
- tdm_exynos_event_type type;
- tdm_exynos_output *output_data;
- void *user_data;
-};
-
-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_ */
+++ /dev/null
-/*
- *
- * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- */
-
-/**
- * \file
- * List macros heavily inspired by the Linux kernel
- * list handling. No list looping yet.
- *
- * Is not threadsafe, so common operations need to
- * be protected using an external mutex.
- */
-#ifndef _U_DOUBLE_LIST_H_
-#define _U_DOUBLE_LIST_H_
-
-#include <stddef.h>
-
-struct list_head {
- struct list_head *prev;
- struct list_head *next;
-};
-
-static inline void list_inithead(struct list_head *item)
-{
- item->prev = item;
- item->next = item;
-}
-
-static inline void list_add(struct list_head *item, struct list_head *list)
-{
- item->prev = list;
- item->next = list->next;
- list->next->prev = item;
- list->next = item;
-}
-
-static inline void list_addtail(struct list_head *item, struct list_head *list)
-{
- item->next = list;
- item->prev = list->prev;
- list->prev->next = item;
- list->prev = item;
-}
-
-static inline void list_replace(struct list_head *from, struct list_head *to)
-{
- to->prev = from->prev;
- to->next = from->next;
- from->next->prev = to;
- from->prev->next = to;
-}
-
-static inline void list_del(struct list_head *item)
-{
- item->prev->next = item->next;
- item->next->prev = item->prev;
-}
-
-static inline void list_delinit(struct list_head *item)
-{
- item->prev->next = item->next;
- item->next->prev = item->prev;
- item->next = item;
- item->prev = item;
-}
-
-static inline int list_length(struct list_head *item)
-{
- struct list_head *next;
- int length = 0;
-
- next = item->next;
- while (next != item) {
- length++;
- next = next->next;
- }
-
- return length;
-}
-
-#define LIST_INITHEAD(__item) list_inithead(__item)
-#define LIST_ADD(__item, __list) list_add(__item, __list)
-#define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list)
-#define LIST_REPLACE(__from, __to) list_replace(__from, __to)
-#define LIST_DEL(__item) list_del(__item)
-#define LIST_DELINIT(__item) list_delinit(__item)
-#define LIST_LENGTH(__item) list_length(__item)
-
-#define LIST_ENTRY(__type, __item, __field) \
- ((__type *)(((char *)(__item)) - offsetof(__type, __field)))
-
-#define LIST_FIRST_ENTRY(__ptr, __type, __field) \
- LIST_ENTRY(__type, (__ptr)->next, __field)
-
-#define LIST_LAST_ENTRY(__ptr, __type, __field) \
- LIST_ENTRY(__type, (__ptr)->prev, __field)
-
-#define LIST_IS_EMPTY(__list) \
- ((__list)->next == (__list))
-
-#ifndef container_of
-#define container_of(ptr, sample, member) \
- (void *)((char *)(ptr) \
- - ((char *)&(sample)->member - (char *)(sample)))
-#endif
-
-#define LIST_FOR_EACH_ENTRY(pos, head, member) \
- for (pos = container_of((head)->next, pos, member); \
- &pos->member != (head); \
- pos = container_of(pos->member.next, pos, member))
-
-#define LIST_FOR_EACH_ENTRY_REV(pos, head, member) \
- for (pos = container_of((head)->prev, pos, member); \
- &pos->member != (head); \
- pos = container_of(pos->member.prev, pos, member))
-
-#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \
- for (pos = container_of((head)->next, pos, member), \
- storage = container_of(pos->member.next, pos, member); \
- &pos->member != (head); \
- pos = storage, storage = container_of(storage->member.next, storage, member))
-
-#define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \
- for (pos = container_of((head)->prev, pos, member), \
- storage = container_of(pos->member.prev, pos, member); \
- &pos->member != (head); \
- pos = storage, storage = container_of(storage->member.prev, storage, member))
-
-#define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \
- for (pos = container_of((start), pos, member); \
- &pos->member != (head); \
- pos = container_of(pos->member.next, pos, member))
-
-#define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \
- for (pos = container_of((start), pos, member); \
- &pos->member != (head); \
- pos = container_of(pos->member.prev, pos, member))
-
-#define LIST_FIND_ITEM(item, head, type, member, found) \
- do { \
- type *pos = NULL; \
- found = NULL; \
- LIST_FOR_EACH_ENTRY(pos, head, member) \
- if (pos == item) { found = item; break; } \
- } while (0)
-
-#endif /*_U_DOUBLE_LIST_H_*/
+++ /dev/null
-/**************************************************************************
-
-libtdm_vc4
-
-Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#include "tdm_backend_log.h"
-
-#undef LOG_TAG
-#define LOG_TAG "TDM_BACKEND"
-
-unsigned int tbm_log_debug_level = TDM_BACKEND_LOG_LEVEL_INFO;
-
-static void
-_tdm_backend_log_dlog_print(int level, const char *fmt, va_list arg)
-{
- log_priority dlog_prio;
-
- switch (level) {
- case TDM_BACKEND_LOG_LEVEL_ERR:
- dlog_prio = DLOG_ERROR;
- break;
- case TDM_BACKEND_LOG_LEVEL_WRN:
- dlog_prio = DLOG_WARN;
- break;
- case TDM_BACKEND_LOG_LEVEL_INFO:
- dlog_prio = DLOG_INFO;
- break;
- case TDM_BACKEND_LOG_LEVEL_DBG:
- dlog_prio = DLOG_DEBUG;
- break;
- default:
- return;
- }
- __dlog_vprint(LOG_ID_SYSTEM, dlog_prio, LOG_TAG, fmt, arg);
-}
-
-void
-tdm_backend_log_print(int level, const char *fmt, ...)
-{
- va_list arg;
-
- if (level > tbm_log_debug_level)
- return;
-
- va_start(arg, fmt);
- _tdm_backend_log_dlog_print(level, fmt, arg);
- va_end(arg);
-}
\ No newline at end of file
+++ /dev/null
-/**************************************************************************
-
-libtbm_exynos
-
-Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifndef __TDM_BACKEND_LOG_H__
-#define __TDM_BACKEND_LOG_H__
-
-#include <sys/syscall.h>
-#include <unistd.h>
-#include <time.h>
-#include <dlog.h>
-
-enum {
- TDM_BACKEND_LOG_LEVEL_NONE,
- TDM_BACKEND_LOG_LEVEL_ERR,
- TDM_BACKEND_LOG_LEVEL_WRN,
- TDM_BACKEND_LOG_LEVEL_INFO,
- TDM_BACKEND_LOG_LEVEL_DBG,
-};
-
-
-/* log level */
-void tdm_backend_log_print(int level, const char *fmt, ...);
-
-#define TDM_BACKEND_DBG(fmt, args...) \
- do { \
- struct timespec ts; \
- clock_gettime(CLOCK_MONOTONIC, &ts); \
- tdm_backend_log_print(TDM_BACKEND_LOG_LEVEL_DBG, "[%5d.%06d][%d][%s %d]"fmt, \
- (int)ts.tv_sec, (int)ts.tv_nsec / 1000, \
- (int)syscall(SYS_gettid), __FUNCTION__, __LINE__, ##args); \
- } while (0)
-
-#define TDM_BACKEND_INFO(fmt, args...) \
- do { \
- struct timespec ts; \
- clock_gettime(CLOCK_MONOTONIC, &ts); \
- tdm_backend_log_print(TDM_BACKEND_LOG_LEVEL_INFO, "[%5d.%06d][%d][%s %d]"fmt, \
- (int)ts.tv_sec, (int)ts.tv_nsec / 1000, \
- (int)syscall(SYS_gettid), __FUNCTION__, __LINE__, ##args); \
- } while (0)
-
-#define TDM_BACKEND_WRN(fmt, args...) \
- do { \
- struct timespec ts; \
- clock_gettime(CLOCK_MONOTONIC, &ts); \
- tdm_backend_log_print(TDM_BACKEND_LOG_LEVEL_WRN, "[%5d.%06d][%d][%s %d]"fmt, \
- (int)ts.tv_sec, (int)ts.tv_nsec / 1000, \
- (int)syscall(SYS_gettid), __FUNCTION__, __LINE__, ##args); \
- } while (0)
-
-#define TDM_BACKEND_ERR(fmt, args...) \
- do { \
- struct timespec ts; \
- clock_gettime(CLOCK_MONOTONIC, &ts); \
- tdm_backend_log_print(TDM_BACKEND_LOG_LEVEL_ERR, "[%5d.%06d][%d][%s %d]"fmt, \
- (int)ts.tv_sec, (int)ts.tv_nsec / 1000, \
- (int)syscall(SYS_gettid), __FUNCTION__, __LINE__, ##args); \
- } while (0)
-
-#define TDM_BACKEND_RETURN_IF_FAIL(cond) {\
- if (!(cond)) {\
- TDM_BACKEND_ERR("'%s' failed.\n", #cond);\
- return;\
- } \
-}
-#define TDM_BACKEND_RETURN_VAL_IF_FAIL(cond, val) {\
- if (!(cond)) {\
- TDM_BACKEND_ERR("'%s' failed.\n", #cond);\
- return val;\
- } \
-}
-#define TDM_BACKEND_GOTO_VAL_IF_FAIL(cond, val) {\
- if (!(cond)) {\
- TDM_BACKEND_ERR("'%s' failed.\n", #cond);\
- goto val;\
- } \
-}
-
-#endif /* __TDM_BACKEND_LOG_H__ */
\ No newline at end of file
+++ /dev/null
-/**************************************************************************
-
-libtdm_exynos
-
-Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_backend_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_display *display_data;
-
- tdm_exynos_output *output_data;
-
- hal_tdm_info_capture info;
- int info_changed;
-
- struct list_head pending_buffer_list;
- struct list_head buffer_list;
-
- struct {
-#if 0 // DO NOT SUPPORT
- hal_tdm_event_loop_source *timer_source;
-#endif
- int startd;
- int first_event;
- } stream;
-
- hal_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, hal_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, hal_tdm_pos *scale)
-{
- float ratio;
- hal_tdm_pos center = {0,};
-
- _tdm_exynos_capture_oneshot_center_rect(src_w, src_h, dst_w, dst_h, ¢er);
-
- 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(hal_tdm_pos *out_rect, hal_tdm_pos *dst_rect, hal_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 *layer_data, hal_tdm_pos *src_crop, hal_tdm_pos *showing_rect)
-{
- tdm_exynos_output *output_data = capture_data->output_data;
- float ratio_x, ratio_y;
- hal_tdm_pos out_rect;
- hal_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 *layer_data,
- hal_tdm_pos *dst_pos, hal_tdm_pos *showing_pos, hal_tdm_pos *dst_crop,
- hal_tdm_transform transform)
-{
- tdm_exynos_output *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 == HAL_TDM_TRANSFORM_NORMAL || transform == HAL_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 == HAL_TDM_TRANSFORM_90 || transform == HAL_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 == HAL_TDM_TRANSFORM_180 || transform == HAL_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 == HAL_TDM_TRANSFORM_270 || transform == HAL_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_BACKEND_ERR("oneshot: get_crop unknown case error");
- }
-}
-
-static pixman_format_code_t
-_tdm_exynos_pixman_format_get(tbm_format format)
-{
- switch (format) {
- case TBM_FORMAT_ARGB8888:
- return PIXMAN_a8r8g8b8;
- case TBM_FORMAT_XRGB8888:
- return PIXMAN_x8r8g8b8;
- default:
- return 0;
- }
-
- return 0;
-}
-
-static hal_tdm_error
-_tdm_exynos_capture_convert_buffer(tbm_surface_h srcbuf, tbm_surface_h dstbuf,
- hal_tdm_pos *srcpos, hal_tdm_pos *dstpos,
- hal_tdm_transform transform, int over)
-{
- tbm_surface_info_s src_info, dst_info;
- pixman_image_t *src_img = NULL, *dst_img = NULL;
- pixman_format_code_t src_format, dst_format;
- double scale_x, scale_y;
- int rotate_step, bos;
- pixman_transform_t t;
- struct pixman_f_transform ft;
- pixman_op_t op;
- int src_stride, dst_stride;
- int buf_width, err;
- hal_tdm_error ret = HAL_TDM_ERROR_OPERATION_FAILED;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(srcbuf != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(dstbuf != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- bos = tbm_surface_internal_get_num_bos(srcbuf);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(bos == 1, HAL_TDM_ERROR_OPERATION_FAILED);
-
- bos = tbm_surface_internal_get_num_bos(dstbuf);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(bos == 1, HAL_TDM_ERROR_OPERATION_FAILED);
-
- err = tbm_surface_map(srcbuf, TBM_OPTION_READ, &src_info);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(err == TBM_SURFACE_ERROR_NONE, HAL_TDM_ERROR_OPERATION_FAILED);
-
- err = tbm_surface_map(dstbuf, TBM_OPTION_WRITE, &dst_info);
- TDM_BACKEND_GOTO_VAL_IF_FAIL(err == TBM_SURFACE_ERROR_NONE, unmap_srcbuf);
-
- /* not handle buffers which have 2 more gem handles */
- TDM_BACKEND_GOTO_VAL_IF_FAIL(src_info.planes[0].ptr != NULL, unmap_dstbuf);
- TDM_BACKEND_GOTO_VAL_IF_FAIL(dst_info.planes[0].ptr != NULL, unmap_dstbuf);
-
- src_format = _tdm_exynos_pixman_format_get(src_info.format);
- TDM_BACKEND_GOTO_VAL_IF_FAIL(src_format > 0, unmap_dstbuf);
- dst_format = _tdm_exynos_pixman_format_get(dst_info.format);
- TDM_BACKEND_GOTO_VAL_IF_FAIL(dst_format > 0, unmap_dstbuf);
-
- buf_width = src_info.planes[0].stride >> 2;
- src_stride = src_info.planes[0].stride;
- src_img = pixman_image_create_bits(src_format, buf_width, src_info.height,
- (uint32_t*)src_info.planes[0].ptr, src_stride);
- TDM_BACKEND_GOTO_VAL_IF_FAIL(src_img, unref_img);
-
- buf_width = dst_info.planes[0].stride >> 2;
- dst_stride = dst_info.planes[0].stride;
- dst_img = pixman_image_create_bits(dst_format, buf_width, dst_info.height,
- (uint32_t*)dst_info.planes[0].ptr, dst_stride);
- TDM_BACKEND_GOTO_VAL_IF_FAIL(dst_img, unref_img);
-
- pixman_f_transform_init_identity(&ft);
-
- if (transform & HAL_TDM_TRANSFORM_FLIPPED) {
- pixman_f_transform_scale(&ft, NULL, -1, 1);
- pixman_f_transform_translate(&ft, NULL, dstpos->w, 0);
- }
-
- rotate_step = transform & 0x3;
- if (rotate_step > 0) {
- int c, s, tx = 0, ty = 0;
- switch (rotate_step) {
- case 1:
- c = 0, s = -1, tx = -dstpos->w;
- break;
- case 2:
- c = -1, s = 0, tx = -dstpos->w, ty = -dstpos->h;
- break;
- case 3:
- c = 0, s = 1, ty = -dstpos->h;
- break;
- }
- pixman_f_transform_translate(&ft, NULL, tx, ty);
- pixman_f_transform_rotate(&ft, NULL, c, s);
- }
-
- if (rotate_step % 2 == 0) {
- scale_x = (double)srcpos->w / dstpos->w;
- scale_y = (double)srcpos->h / dstpos->h;
- } else {
- scale_x = (double)srcpos->w / dstpos->h;
- scale_y = (double)srcpos->h / dstpos->w;
- }
-
- pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
- pixman_f_transform_translate(&ft, NULL, srcpos->x, srcpos->y);
- pixman_transform_from_pixman_f_transform(&t, &ft);
- pixman_image_set_transform(src_img, &t);
-
- op = (!over) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER;
-
- pixman_image_composite(op, src_img, NULL, dst_img, 0, 0, 0, 0,
- dstpos->x, dstpos->y, dstpos->w, dstpos->h);
-
- ret = HAL_TDM_ERROR_NONE;
-
-unref_img:
- if (src_img)
- pixman_image_unref(src_img);
- if (dst_img)
- pixman_image_unref(dst_img);
-unmap_dstbuf:
- tbm_surface_unmap(dstbuf);
-unmap_srcbuf:
- tbm_surface_unmap(srcbuf);
-
- return ret;
-}
-
-static void
-_tdm_exynos_capture_oneshot_composite_layers_sw(tdm_exynos_capture_data *capture_data, tbm_surface_h buffer)
-{
- tdm_exynos_output *output_data = capture_data->output_data;
- tdm_exynos_layer *layer_data = NULL;
- tbm_surface_info_s buf_info;
- int err;
-
- err = tbm_surface_get_info(buffer, &buf_info);
- TDM_BACKEND_RETURN_IF_FAIL(err == TBM_SURFACE_ERROR_NONE);
-
- LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
- tbm_surface_h buf;
- hal_tdm_pos dst_pos;
- hal_tdm_pos showing_pos;
- hal_tdm_pos src_crop;
- hal_tdm_pos dst_crop;
- hal_tdm_transform transform = HAL_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_BACKEND_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_exynos_capture_convert_buffer(buf, buffer, &src_crop, &dst_crop, transform, 1);
- }
-}
-
-static hal_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-tdm_exynos_capture_get_capability(tdm_exynos_display *display_data, hal_tdm_caps_capture *caps)
-{
- int i;
-
- if (!caps) {
- TDM_BACKEND_ERR("invalid params");
- return HAL_TDM_ERROR_INVALID_PARAMETER;
- }
-
- caps->capabilities = HAL_TDM_CAPTURE_CAPABILITY_OUTPUT|
- HAL_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_BACKEND_ERR("alloc failed");
- return HAL_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_capture *
-tdm_exynos_capture_create_output(tdm_exynos_display *display_data, hal_tdm_output *output, hal_tdm_error *error)
-{
- tdm_exynos_capture_data *capture_data = calloc(1, sizeof(tdm_exynos_capture_data));
- if (!capture_data) {
- TDM_BACKEND_ERR("alloc failed");
- if (error)
- *error = HAL_TDM_ERROR_OUT_OF_MEMORY;
- return NULL;
- }
-
- capture_data->display_data = display_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_BACKEND_DBG("capture(%p) create", capture_data);
-
- return capture_data;
-}
-
-void
-exynos_capture_destroy(hal_tdm_capture *capture)
-{
- tdm_exynos_capture_data *capture_data = capture;
- tdm_exynos_capture_buffer *b = NULL, *bb = NULL;
-
- if (!capture_data)
- return;
-
- TDM_BACKEND_DBG("capture(%p) destroy", capture_data);
-
-#if 0 // DO NOT SUPPORT
- if (capture_data->stream.timer_source)
- hal_tdm_event_loop_source_remove(capture_data->stream.timer_source);
-#endif
-
- 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);
- tbm_surface_internal_unref(b->ui_buffer);
- free(b);
- }
-
- LIST_DEL(&capture_data->link);
-
- free(capture_data);
-}
-
-hal_tdm_error
-exynos_capture_set_info(hal_tdm_capture *capture, hal_tdm_info_capture *info)
-{
- tdm_exynos_capture_data *capture_data = capture;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(info, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- capture_data->info = *info;
- capture_data->info_changed = 1;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_capture_attach(hal_tdm_capture *capture, tbm_surface_h buffer)
-{
- tdm_exynos_capture_data *capture_data = capture;
- tdm_exynos_capture_buffer *b;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(buffer, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- b = calloc(1, sizeof(tdm_exynos_capture_buffer));
- if (!b) {
- TDM_BACKEND_ERR("alloc failed");
- return HAL_TDM_ERROR_NONE;
- }
-
- LIST_ADDTAIL(&b->link, &capture_data->pending_buffer_list);
-
- b->index = _get_index(capture_data);
- b->buffer = buffer;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_capture_commit(hal_tdm_capture *capture)
-{
- tdm_exynos_capture_data *capture_data = capture;
- hal_tdm_error ret = HAL_TDM_ERROR_INVALID_PARAMETER;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- if (capture_data->info.type == HAL_TDM_CAPTURE_TYPE_ONESHOT)
- ret = _tdm_exynos_capture_commit_oneshot(capture_data);
-
- return ret;
-}
-
-hal_tdm_error
-exynos_capture_set_done_handler(hal_tdm_capture *capture, hal_tdm_capture_done_handler func, void *user_data)
-{
- tdm_exynos_capture_data *capture_data = capture;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- capture_data->done_func = func;
- capture_data->done_user_data = user_data;
-
- return HAL_TDM_ERROR_NONE;
-}
+++ /dev/null
-/**************************************************************************
-
-libtdm_exynos
-
-Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_backend_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_display *display_data;
-
- tdm_exynos_output *output_data;
-
- hal_tdm_info_capture info;
- int info_changed;
-
- struct list_head pending_buffer_list;
- struct list_head buffer_list;
-
- struct {
-#if 0 // DO NOT SUPPORT
- hal_tdm_event_loop_source *timer_source;
-#endif
- unsigned int prop_id;
-
- int startd;
- int first_event;
- } stream;
-
- hal_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;
-}
-
-#if 0 // DO NOT SUPPORT
-static hal_tdm_error
-_tdm_exynos_capture_legacy_stream_pp_set(tdm_exynos_capture_legacy_data *capture_data, tbm_surface_h ui_buffer)
-{
- tdm_exynos_display *display_data = capture_data->display_data;
- hal_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(hal_tdm_size));
- memcpy(&property.config[1].pos, &info->dst_config.pos, sizeof(hal_tdm_pos));
- property.cmd = IPP_CMD_M2M;
- property.prop_id = capture_data->stream.prop_id;
-
- TDM_BACKEND_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_BACKEND_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(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_SET_PROPERTY, &property);
- if (ret) {
- TDM_BACKEND_ERR("failed: %m");
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- TDM_BACKEND_DBG("success. prop_id(%d) ", property.prop_id);
- capture_data->stream.prop_id = property.prop_id;
- return HAL_TDM_ERROR_NONE;
-}
-#endif
-
-static hal_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_display *display_data = capture_data->display_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_BACKEND_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(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
- if (ret) {
- TDM_BACKEND_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 HAL_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_BACKEND_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(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
- if (ret) {
- TDM_BACKEND_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 HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- TDM_BACKEND_DBG("success. prop_id(%d)", buf.prop_id);
-
- return HAL_TDM_ERROR_NONE;
-}
-
-static hal_tdm_error
-_tdm_exynos_capture_legacy_stream_pp_cmd(tdm_exynos_capture_legacy_data *capture_data, enum drm_exynos_ipp_ctrl cmd)
-{
- tdm_exynos_display *display_data = capture_data->display_data;
- struct drm_exynos_ipp_cmd_ctrl ctrl;
- int ret = 0;
-
- ctrl.prop_id = capture_data->stream.prop_id;
- ctrl.ctrl = cmd;
-
- TDM_BACKEND_DBG("prop_id(%d) ctrl(%d). ", ctrl.prop_id, ctrl.ctrl);
-
- ret = ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_CMD_CTRL, &ctrl);
- if (ret) {
- TDM_BACKEND_ERR("failed. prop_id(%d) ctrl(%d). %m", ctrl.prop_id, ctrl.ctrl);
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- TDM_BACKEND_DBG("success. prop_id(%d) ", ctrl.prop_id);
-
- return HAL_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_BACKEND_ERR("invalid params");
- return;
- }
-
- LIST_FOR_EACH_ENTRY(d, &capture_list, link) {
- if (d == capture_data) {
- found = d;
- break;
- }
- }
- if (!found)
- return;
-
- TDM_BACKEND_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_BACKEND_DBG("dequeued: %d", dequeued_buffer->index);
- break;
- }
- }
-
- if (!dequeued_buffer) {
- TDM_BACKEND_ERR("not found buffer index: %d", buf_idx[0]);
- return;
- }
-
- if (!capture_data->stream.first_event) {
- TDM_BACKEND_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);
-
- tbm_surface_internal_unref(dequeued_buffer->ui_buffer);
-
- free(dequeued_buffer);
-}
-
-#if 0 // DO NOT SUPPORT
-static hal_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;
- hal_tdm_error ret;
-
- hal_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 HAL_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 HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- b = LIST_FIRST_ENTRY(&capture_data->pending_buffer_list, tdm_exynos_capture_legacy_buffer, link);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(b != NULL, HAL_TDM_ERROR_OPERATION_FAILED);
-
- LIST_DEL(&b->link);
- b->ui_buffer = hal_tdm_buffer_ref_backend(ui_buffer);
- _tdm_exynos_capture_legacy_stream_pp_queue(capture_data, b, IPP_BUF_ENQUEUE);
- TDM_BACKEND_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 HAL_TDM_ERROR_NONE;
-}
-#endif
-
-static hal_tdm_error
-_tdm_exynos_capture_legacy_commit_stream(tdm_exynos_capture_legacy_data *capture_data)
-{
-#if 0 // DO NOT SUPPORT
- 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->display_data->dpy,
- _tdm_exynos_capture_legacy_stream_timer_handler,
- capture_data, NULL);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data->stream.timer_source != NULL, HAL_TDM_ERROR_OUT_OF_MEMORY);
- }
-
- hal_tdm_event_loop_source_timer_update(capture_data->stream.timer_source, ms);
-#endif
- return HAL_TDM_ERROR_NONE;
-}
-
-static void
-_tdm_exynos_capture_legacy_oneshot_center_rect(int src_w, int src_h, int dst_w, int dst_h, hal_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, hal_tdm_pos *scale)
-{
- float ratio;
- hal_tdm_pos center = {0,};
-
- _tdm_exynos_capture_legacy_oneshot_center_rect(src_w, src_h, dst_w, dst_h, ¢er);
-
- 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(hal_tdm_pos *out_rect, hal_tdm_pos *dst_rect, hal_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 *layer_data, hal_tdm_pos *src_crop, hal_tdm_pos *showing_rect)
-{
- tdm_exynos_output *output_data = capture_data->output_data;
- float ratio_x, ratio_y;
- hal_tdm_pos out_rect;
- hal_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 *layer_data,
- hal_tdm_pos *dst_pos, hal_tdm_pos *showing_pos, hal_tdm_pos *dst_crop,
- hal_tdm_transform transform)
-{
- tdm_exynos_output *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 == HAL_TDM_TRANSFORM_NORMAL || transform == HAL_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 == HAL_TDM_TRANSFORM_90 || transform == HAL_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 == HAL_TDM_TRANSFORM_180 || transform == HAL_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 == HAL_TDM_TRANSFORM_270 || transform == HAL_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_BACKEND_ERR("oneshot: get_crop unknown case error");
- }
-}
-
-static pixman_format_code_t
-_tdm_exynos_pixman_format_get(tbm_format format)
-{
- switch (format) {
- case TBM_FORMAT_ARGB8888:
- return PIXMAN_a8r8g8b8;
- case TBM_FORMAT_XRGB8888:
- return PIXMAN_x8r8g8b8;
- default:
- return 0;
- }
-
- return 0;
-}
-
-static hal_tdm_error
-_tdm_exynos_capture_convert_buffer(tbm_surface_h srcbuf, tbm_surface_h dstbuf,
- hal_tdm_pos *srcpos, hal_tdm_pos *dstpos,
- hal_tdm_transform transform, int over)
-{
- tbm_surface_info_s src_info, dst_info;
- pixman_image_t *src_img = NULL, *dst_img = NULL;
- pixman_format_code_t src_format, dst_format;
- double scale_x, scale_y;
- int rotate_step, bos;
- pixman_transform_t t;
- struct pixman_f_transform ft;
- pixman_op_t op;
- int src_stride, dst_stride;
- int buf_width, err;
- hal_tdm_error ret = HAL_TDM_ERROR_OPERATION_FAILED;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(srcbuf != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(dstbuf != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- bos = tbm_surface_internal_get_num_bos(srcbuf);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(bos == 1, HAL_TDM_ERROR_OPERATION_FAILED);
-
- bos = tbm_surface_internal_get_num_bos(dstbuf);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(bos == 1, HAL_TDM_ERROR_OPERATION_FAILED);
-
- err = tbm_surface_map(srcbuf, TBM_OPTION_READ, &src_info);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(err == TBM_SURFACE_ERROR_NONE, HAL_TDM_ERROR_OPERATION_FAILED);
-
- err = tbm_surface_map(dstbuf, TBM_OPTION_WRITE, &dst_info);
- TDM_BACKEND_GOTO_VAL_IF_FAIL(err == TBM_SURFACE_ERROR_NONE, unmap_srcbuf);
-
- /* not handle buffers which have 2 more gem handles */
- TDM_BACKEND_GOTO_VAL_IF_FAIL(src_info.planes[0].ptr != NULL, unmap_dstbuf);
- TDM_BACKEND_GOTO_VAL_IF_FAIL(dst_info.planes[0].ptr != NULL, unmap_dstbuf);
-
- src_format = _tdm_exynos_pixman_format_get(src_info.format);
- TDM_BACKEND_GOTO_VAL_IF_FAIL(src_format > 0, unmap_dstbuf);
- dst_format = _tdm_exynos_pixman_format_get(dst_info.format);
- TDM_BACKEND_GOTO_VAL_IF_FAIL(dst_format > 0, unmap_dstbuf);
-
- buf_width = src_info.planes[0].stride >> 2;
- src_stride = src_info.planes[0].stride;
- src_img = pixman_image_create_bits(src_format, buf_width, src_info.height,
- (uint32_t*)src_info.planes[0].ptr, src_stride);
- TDM_BACKEND_GOTO_VAL_IF_FAIL(src_img, unref_img);
-
- buf_width = dst_info.planes[0].stride >> 2;
- dst_stride = dst_info.planes[0].stride;
- dst_img = pixman_image_create_bits(dst_format, buf_width, dst_info.height,
- (uint32_t*)dst_info.planes[0].ptr, dst_stride);
- TDM_BACKEND_GOTO_VAL_IF_FAIL(dst_img, unref_img);
-
- pixman_f_transform_init_identity(&ft);
-
- if (transform & HAL_TDM_TRANSFORM_FLIPPED) {
- pixman_f_transform_scale(&ft, NULL, -1, 1);
- pixman_f_transform_translate(&ft, NULL, dstpos->w, 0);
- }
-
- rotate_step = transform & 0x3;
- if (rotate_step > 0) {
- int c, s, tx = 0, ty = 0;
- switch (rotate_step) {
- case 1:
- c = 0, s = -1, tx = -dstpos->w;
- break;
- case 2:
- c = -1, s = 0, tx = -dstpos->w, ty = -dstpos->h;
- break;
- case 3:
- c = 0, s = 1, ty = -dstpos->h;
- break;
- }
- pixman_f_transform_translate(&ft, NULL, tx, ty);
- pixman_f_transform_rotate(&ft, NULL, c, s);
- }
-
- if (rotate_step % 2 == 0) {
- scale_x = (double)srcpos->w / dstpos->w;
- scale_y = (double)srcpos->h / dstpos->h;
- } else {
- scale_x = (double)srcpos->w / dstpos->h;
- scale_y = (double)srcpos->h / dstpos->w;
- }
-
- pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
- pixman_f_transform_translate(&ft, NULL, srcpos->x, srcpos->y);
- pixman_transform_from_pixman_f_transform(&t, &ft);
- pixman_image_set_transform(src_img, &t);
-
- op = (!over) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER;
-
- pixman_image_composite(op, src_img, NULL, dst_img, 0, 0, 0, 0,
- dstpos->x, dstpos->y, dstpos->w, dstpos->h);
-
- ret = HAL_TDM_ERROR_NONE;
-
-unref_img:
- if (src_img)
- pixman_image_unref(src_img);
- if (dst_img)
- pixman_image_unref(dst_img);
-unmap_dstbuf:
- tbm_surface_unmap(dstbuf);
-unmap_srcbuf:
- tbm_surface_unmap(srcbuf);
-
- return ret;
-}
-
-static void
-_tdm_exynos_capture_legacy_oneshot_composite_layers_sw(tdm_exynos_capture_legacy_data *capture_data, tbm_surface_h buffer)
-{
- tdm_exynos_output *output_data = capture_data->output_data;
- tdm_exynos_layer *layer_data = NULL;
- tbm_surface_info_s buf_info;
- int err;
-
- err = tbm_surface_get_info(buffer, &buf_info);
- TDM_BACKEND_RETURN_IF_FAIL(err == TBM_SURFACE_ERROR_NONE);
-
- LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
- tbm_surface_h buf;
- hal_tdm_pos dst_pos;
- hal_tdm_pos showing_pos;
- hal_tdm_pos src_crop;
- hal_tdm_pos dst_crop;
- hal_tdm_transform transform = HAL_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_BACKEND_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_exynos_capture_convert_buffer(buf, buffer,
- &src_crop, &dst_crop, transform, 1);
- }
-}
-
-static hal_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-tdm_exynos_capture_legacy_get_capability(tdm_exynos_display *display_data, hal_tdm_caps_capture *caps)
-{
- int i;
-
- if (!caps) {
- TDM_BACKEND_ERR("invalid params");
- return HAL_TDM_ERROR_INVALID_PARAMETER;
- }
-
- caps->capabilities = HAL_TDM_CAPTURE_CAPABILITY_OUTPUT|
- HAL_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_BACKEND_ERR("alloc failed");
- return HAL_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_capture *
-tdm_exynos_capture_legacy_create_output(tdm_exynos_display *display_data, hal_tdm_output *output, hal_tdm_error *error)
-{
- tdm_exynos_capture_legacy_data *capture_data = calloc(1, sizeof(tdm_exynos_capture_legacy_data));
- if (!capture_data) {
- TDM_BACKEND_ERR("alloc failed");
- if (error)
- *error = HAL_TDM_ERROR_OUT_OF_MEMORY;
- return NULL;
- }
-
- capture_data->display_data = display_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_BACKEND_DBG("capture(%p) create", capture_data);
-
- return capture_data;
-}
-
-void
-exynos_capture_legacy_destroy(hal_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_BACKEND_DBG("capture(%p) destroy", capture_data);
-
-#if 0 // DO NOT SUPPORT
- if (capture_data->stream.timer_source)
- hal_tdm_event_loop_source_remove(capture_data->stream.timer_source);
-#endif
-
- 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);
- tbm_surface_internal_unref(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);
-}
-
-hal_tdm_error
-exynos_capture_legacy_set_info(hal_tdm_capture *capture, hal_tdm_info_capture *info)
-{
- tdm_exynos_capture_legacy_data *capture_data = capture;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(info, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- capture_data->info = *info;
- capture_data->info_changed = 1;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_capture_legacy_attach(hal_tdm_capture *capture, tbm_surface_h buffer)
-{
- tdm_exynos_capture_legacy_data *capture_data = capture;
- tdm_exynos_capture_legacy_buffer *b;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(buffer, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- b = calloc(1, sizeof(tdm_exynos_capture_legacy_buffer));
- if (!b) {
- TDM_BACKEND_ERR("alloc failed");
- return HAL_TDM_ERROR_NONE;
- }
-
- LIST_ADDTAIL(&b->link, &capture_data->pending_buffer_list);
-
- b->index = _get_index(capture_data);
- b->buffer = buffer;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_capture_legacy_commit(hal_tdm_capture *capture)
-{
- tdm_exynos_capture_legacy_data *capture_data = capture;
- hal_tdm_error ret;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- if (capture_data->info.type == HAL_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;
-}
-
-hal_tdm_error
-exynos_capture_legacy_set_done_handler(hal_tdm_capture *capture, hal_tdm_capture_done_handler func, void *user_data)
-{
- tdm_exynos_capture_legacy_data *capture_data = capture;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- capture_data->done_func = func;
- capture_data->done_user_data = user_data;
-
- return HAL_TDM_ERROR_NONE;
-}
+++ /dev/null
-/**************************************************************************
-
-libtdm_exynos
-
-Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_backend_exynos.h"
-
-#define LAYER_COUNT_FOR_NOT_FIXED 2
-#define LAYER_PRIMARY_INDEX_FOR_NOT_FIXED 1
-
-static hal_tdm_error
-_tdm_exynos_display_create_layer_list_type(tdm_exynos_display *display_data)
-{
- hal_tdm_error ret;
- int i;
-
- for (i = 0; i < display_data->plane_res->count_planes; i++) {
- tdm_exynos_output *output_data = NULL;
- tdm_exynos_layer *layer_data;
- drmModePlanePtr plane;
- unsigned int type = 0;
- int output_find = 0;
-
- plane = drmModeGetPlane(display_data->drm_fd, display_data->plane_res->planes[i]);
- if (!plane) {
- TDM_BACKEND_ERR("no plane");
- continue;
- }
-
- ret = tdm_exynos_display_get_property(display_data,
- display_data->plane_res->planes[i],
- DRM_MODE_OBJECT_PLANE, "type", &type, NULL);
- if (ret != HAL_TDM_ERROR_NONE) {
- TDM_BACKEND_ERR("plane(%d) doesn't have 'type' info",
- display_data->plane_res->planes[i]);
- drmModeFreePlane(plane);
- continue;
- }
-
- layer_data = calloc(1, sizeof(tdm_exynos_layer));
- if (!layer_data) {
- TDM_BACKEND_ERR("alloc failed");
- drmModeFreePlane(plane);
- continue;
- }
-
- LIST_FOR_EACH_ENTRY(output_data, &display_data->output_list, link) {
- if (plane->possible_crtcs & (1 << output_data->pipe)) {
- output_find = 1;
- break;
- }
- }
-
- if (!output_find) {
- TDM_BACKEND_ERR("plane(%d) couldn't found proper output", plane->plane_id);
- drmModeFreePlane(plane);
- free(layer_data);
- continue;
- }
-
- layer_data->display_data = display_data;
- layer_data->output_data = output_data;
- layer_data->plane_id = display_data->plane_res->planes[i];
-
- if (type == DRM_PLANE_TYPE_CURSOR) {
- layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_CURSOR |
- TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
- layer_data->zpos = 2;
- } else if (type == DRM_PLANE_TYPE_OVERLAY) {
- layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_OVERLAY |
- TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
- layer_data->zpos = 1;
- } else if (type == DRM_PLANE_TYPE_PRIMARY) {
- layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_PRIMARY |
- TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
- layer_data->zpos = 0;
- output_data->primary_layer = layer_data;
- } else {
- drmModeFreePlane(plane);
- free(layer_data);
- continue;
- }
-
- TDM_BACKEND_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 HAL_TDM_ERROR_NONE;
-}
-
-static hal_tdm_error
-_tdm_exynos_display_create_layer_list_immutable_zpos(tdm_exynos_display *display_data)
-{
- hal_tdm_error ret;
- int i;
-
- for (i = 0; i < display_data->plane_res->count_planes; i++) {
- tdm_exynos_output *output_data = NULL;
- tdm_exynos_layer *layer_data;
- drmModePlanePtr plane;
- unsigned int type = 0, zpos = 0;
- int output_find = 0;
-
- plane = drmModeGetPlane(display_data->drm_fd, display_data->plane_res->planes[i]);
- if (!plane) {
- TDM_BACKEND_ERR("no plane");
- continue;
- }
-
- ret = tdm_exynos_display_get_property(display_data,
- display_data->plane_res->planes[i],
- DRM_MODE_OBJECT_PLANE, "type", &type, NULL);
- if (ret != HAL_TDM_ERROR_NONE) {
- TDM_BACKEND_ERR("plane(%d) doesn't have 'type' info",
- display_data->plane_res->planes[i]);
- drmModeFreePlane(plane);
- continue;
- }
-
- ret = tdm_exynos_display_get_property(display_data,
- display_data->plane_res->planes[i],
- DRM_MODE_OBJECT_PLANE, "zpos", &zpos, NULL);
- if (ret != HAL_TDM_ERROR_NONE) {
- TDM_BACKEND_ERR("plane(%d) doesn't have 'zpos' info",
- display_data->plane_res->planes[i]);
- drmModeFreePlane(plane);
- continue;
- }
-
- layer_data = calloc(1, sizeof(tdm_exynos_layer));
- if (!layer_data) {
- TDM_BACKEND_ERR("alloc failed");
- drmModeFreePlane(plane);
- continue;
- }
-
- LIST_FOR_EACH_ENTRY(output_data, &display_data->output_list, link) {
- if (plane->possible_crtcs & (1 << output_data->pipe)) {
- output_find = 1;
- break;
- }
- }
-
- if (!output_find) {
- TDM_BACKEND_ERR("plane(%d) couldn't found proper output", plane->plane_id);
- drmModeFreePlane(plane);
- free(layer_data);
- continue;
- }
-
- layer_data->display_data = display_data;
- layer_data->output_data = output_data;
- layer_data->plane_id = display_data->plane_res->planes[i];
- layer_data->zpos = zpos;
-
- if (type == DRM_PLANE_TYPE_CURSOR)
- layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_CURSOR |
- TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
- else if (type == DRM_PLANE_TYPE_OVERLAY)
- layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_OVERLAY |
- TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
- else if (type == DRM_PLANE_TYPE_PRIMARY) {
- layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_PRIMARY |
- TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
- output_data->primary_layer = layer_data;
- } else {
- drmModeFreePlane(plane);
- free(layer_data);
- continue;
- }
-
- TDM_BACKEND_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 HAL_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 hal_tdm_error
-_tdm_exynos_display_create_layer_list_not_fixed(tdm_exynos_display *display_data)
-{
- int find_pipe = -1;
- int zpos = 0;
- int output_count, i;
-
- output_count = LIST_LENGTH(&display_data->output_list);
-
- if (display_data->plane_res->count_planes < (output_count * LAYER_COUNT_FOR_NOT_FIXED)) {
- TDM_BACKEND_ERR("not enough layers");
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- for (i = 0; i < display_data->plane_res->count_planes; i++) {
- tdm_exynos_output *output_data = NULL;
- tdm_exynos_layer *layer_data;
- drmModePlanePtr plane;
-
- plane = drmModeGetPlane(display_data->drm_fd, display_data->plane_res->planes[i]);
- if (!plane) {
- TDM_BACKEND_ERR("no plane");
- continue;
- }
-
- layer_data = calloc(1, sizeof(tdm_exynos_layer));
- if (!layer_data) {
- TDM_BACKEND_ERR("alloc failed");
- drmModeFreePlane(plane);
- continue;
- }
-
- if (i % LAYER_COUNT_FOR_NOT_FIXED == 0) {
- find_pipe++;
- zpos = 0;
- }
-
- LIST_FOR_EACH_ENTRY(output_data, &display_data->output_list, link) {
- if (output_data->pipe == find_pipe)
- break;
- }
-
- layer_data->display_data = display_data;
- layer_data->output_data = output_data;
- layer_data->plane_id = display_data->plane_res->planes[i];
-
- layer_data->zpos = zpos++;
-
- if (layer_data->zpos == LAYER_PRIMARY_INDEX_FOR_NOT_FIXED) {
- layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_PRIMARY |
- TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
- output_data->primary_layer = layer_data;
- } else {
- hal_tdm_error ret;
-
- layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_OVERLAY |
- TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
-
- ret = tdm_exynos_display_set_property(display_data, layer_data->plane_id,
- DRM_MODE_OBJECT_PLANE, "zpos", layer_data->zpos);
- if (ret != HAL_TDM_ERROR_NONE) {
- drmModeFreePlane(plane);
- free(layer_data);
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
- }
-
- TDM_BACKEND_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 HAL_TDM_ERROR_NONE;
-}
-
-void
-tdm_exynos_display_to_tdm_mode(drmModeModeInfoPtr drm_mode,
- hal_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, HAL_TDM_NAME_LEN, "%s", drm_mode->name);
-}
-
-hal_tdm_error
-tdm_exynos_display_create_layer_list(tdm_exynos_display *display_data)
-{
- tdm_exynos_output *output_data = NULL;
- hal_tdm_error ret;
-
- if (!display_data->has_zpos_info)
- ret = _tdm_exynos_display_create_layer_list_type(display_data);
- else if (display_data->is_immutable_zpos)
- ret = _tdm_exynos_display_create_layer_list_immutable_zpos(display_data);
- else
- ret = _tdm_exynos_display_create_layer_list_not_fixed(display_data);
-
- if (ret != HAL_TDM_ERROR_NONE)
- return ret;
-
- LIST_FOR_EACH_ENTRY(output_data, &display_data->output_list, link) {
- if (!output_data->primary_layer) {
- TDM_BACKEND_ERR("output(%d) no primary layer_data", output_data->pipe);
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
- }
-
- return HAL_TDM_ERROR_NONE;
-}
-
-void
-tdm_exynos_display_destroy_output_list(tdm_exynos_display *display_data)
-{
- tdm_exynos_output *o = NULL, *oo = NULL;
-
- if (LIST_IS_EMPTY(&display_data->output_list))
- return;
-
- LIST_FOR_EACH_ENTRY_SAFE(o, oo, &display_data->output_list, link) {
- LIST_DEL(&o->link);
- if (!LIST_IS_EMPTY(&o->layer_list)) {
- tdm_exynos_layer *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_display *display_data)
-{
- tdm_exynos_output *output_data = NULL;
-
- if (LIST_IS_EMPTY(&display_data->output_list))
- return;
-
- LIST_FOR_EACH_ENTRY(output_data, &display_data->output_list, link) {
- drmModeConnectorPtr connector;
- hal_tdm_output_conn_status new_status;
-
- connector = drmModeGetConnector(display_data->drm_fd,
- output_data->connector_id);
- if (!connector) {
- TDM_BACKEND_ERR("no connector: %d", output_data->connector_id);
- continue;
- }
-
- if (connector->connection == DRM_MODE_CONNECTED)
- new_status = HAL_TDM_OUTPUT_CONN_STATUS_CONNECTED;
- else
- new_status = HAL_TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
-
- tdm_exynos_output_update_status(output_data, new_status);
-
- drmModeFreeConnector(connector);
- }
-}
-
-hal_tdm_error
-tdm_exynos_display_create_output_list(tdm_exynos_display *display_data)
-{
- tdm_exynos_output *output_data;
- int i;
- hal_tdm_error ret;
- int allocated = 0;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(LIST_IS_EMPTY(&display_data->output_list),
- HAL_TDM_ERROR_OPERATION_FAILED);
-
- for (i = 0; i < display_data->mode_res->count_connectors; i++) {
- drmModeConnectorPtr connector;
- drmModeEncoderPtr encoder;
- int crtc_id = 0, c, j;
-
- connector = drmModeGetConnector(display_data->drm_fd,
- display_data->mode_res->connectors[i]);
- if (!connector) {
- TDM_BACKEND_ERR("no connector");
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- goto failed_create;
- }
-
- if (connector->count_encoders != 1) {
- TDM_BACKEND_ERR("too many encoders: %d", connector->count_encoders);
- drmModeFreeConnector(connector);
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- goto failed_create;
- }
-
- encoder = drmModeGetEncoder(display_data->drm_fd, connector->encoders[0]);
- if (!encoder) {
- TDM_BACKEND_ERR("no encoder");
- drmModeFreeConnector(connector);
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- goto failed_create;
- }
-
- for (c = 0; c < display_data->mode_res->count_crtcs; c++) {
- if (allocated & (1 << c))
- continue;
-
- if ((encoder->possible_crtcs & (1 << c)) == 0)
- continue;
-
- crtc_id = display_data->mode_res->crtcs[c];
- allocated |= (1 << c);
- break;
- }
-
- if (crtc_id == 0) {
- TDM_BACKEND_ERR("no possible crtc");
- drmModeFreeConnector(connector);
- drmModeFreeEncoder(encoder);
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- goto failed_create;
- }
-
- output_data = calloc(1, sizeof(tdm_exynos_output));
- if (!output_data) {
- TDM_BACKEND_ERR("alloc failed");
- drmModeFreeConnector(connector);
- drmModeFreeEncoder(encoder);
- ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
- goto failed_create;
- }
-
- LIST_INITHEAD(&output_data->layer_list);
-
- output_data->display_data = display_data;
- output_data->connector_id = display_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 = HAL_TDM_OUTPUT_CONN_STATUS_CONNECTED;
- else
- output_data->status = HAL_TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
-
- for (j = 0; j < connector->count_props; j++) {
- drmModePropertyPtr prop = drmModeGetProperty(display_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_BACKEND_ERR("alloc failed");
- free(output_data);
- drmModeFreeConnector(connector);
- drmModeFreeEncoder(encoder);
- ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
- goto failed_create;
- }
- output_data->output_modes = calloc(connector->count_modes, sizeof(hal_tdm_output_mode));
- if (!output_data->output_modes) {
- TDM_BACKEND_ERR("alloc failed");
- free(output_data->drm_modes);
- free(output_data);
- drmModeFreeConnector(connector);
- drmModeFreeEncoder(encoder);
- ret = HAL_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]);
- }
-
- LIST_ADDTAIL(&output_data->link, &display_data->output_list);
-
- TDM_BACKEND_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_BACKEND_DBG("output count: %d", display_data->mode_res->count_connectors);
-
- return HAL_TDM_ERROR_NONE;
-failed_create:
- tdm_exynos_display_destroy_output_list(display_data);
- return ret;
-}
-
-hal_tdm_error
-tdm_exynos_display_set_property(tdm_exynos_display *display_data,
- unsigned int obj_id, unsigned int obj_type,
- const char *name, unsigned int value)
-{
- drmModeObjectPropertiesPtr props = NULL;
- unsigned int i;
-
- props = drmModeObjectGetProperties(display_data->drm_fd, obj_id, obj_type);
- if (!props) {
- TDM_BACKEND_ERR("drmModeObjectGetProperties failed: %m");
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
- for (i = 0; i < props->count_props; i++) {
- drmModePropertyPtr prop = drmModeGetProperty(display_data->drm_fd,
- props->props[i]);
- int ret;
- if (!prop) {
- TDM_BACKEND_ERR("drmModeGetProperty failed: %m");
- drmModeFreeObjectProperties(props);
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
- if (!strcmp(prop->name, name)) {
- ret = drmModeObjectSetProperty(display_data->drm_fd, obj_id, obj_type,
- prop->prop_id, value);
- if (ret < 0) {
- TDM_BACKEND_ERR("drmModeObjectSetProperty failed: %m");
- drmModeFreeProperty(prop);
- drmModeFreeObjectProperties(props);
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
- drmModeFreeProperty(prop);
- drmModeFreeObjectProperties(props);
- return HAL_TDM_ERROR_NONE;
- }
- drmModeFreeProperty(prop);
- }
-
- TDM_BACKEND_ERR("not found '%s' property", name);
-
- drmModeFreeObjectProperties(props);
- /* TODO
- * kernel info error
- * it must be changed to 'return HAL_TDM_ERROR_OPERATION_FAILED' after kernel fix.
- */
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-tdm_exynos_display_get_property(tdm_exynos_display *display_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(display_data->drm_fd, obj_id, obj_type);
- if (!props)
- return HAL_TDM_ERROR_OPERATION_FAILED;
-
- for (i = 0; i < props->count_props; i++) {
- drmModePropertyPtr prop = drmModeGetProperty(display_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 HAL_TDM_ERROR_NONE;
- }
-
- drmModeFreeProperty(prop);
- }
- drmModeFreeObjectProperties(props);
- TDM_BACKEND_DBG("coundn't find '%s' property", name);
- return HAL_TDM_ERROR_OPERATION_FAILED;
-}
-
-hal_tdm_error
-exynos_display_get_capability(hal_tdm_display *display, hal_tdm_caps_display *caps)
-{
- TDM_BACKEND_RETURN_VAL_IF_FAIL(caps, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- caps->max_layer_count = -1; /* not defined */
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_display_get_pp_capability(hal_tdm_display *display, hal_tdm_caps_pp *caps)
-{
- tdm_exynos_display *display_data = (tdm_exynos_display *)display;
- if (display_data->use_ippv2)
- return tdm_exynos_pp_get_capability(display_data, caps);
- else
- return tdm_exynos_pp_legacy_get_capability(display_data, caps);
-}
-
-hal_tdm_error
-exynos_display_get_capture_capability(hal_tdm_display *display, hal_tdm_caps_capture *caps)
-{
- tdm_exynos_display *display_data = (tdm_exynos_display *)display;
- if (display_data->use_ippv2)
- return tdm_exynos_capture_get_capability(display_data, caps);
- else
- return tdm_exynos_capture_legacy_get_capability(display_data, caps);
-}
-
-hal_tdm_output **
-exynos_display_get_outputs(hal_tdm_display *display, int *count,
- hal_tdm_error *error)
-{
- tdm_exynos_display *display_data = (tdm_exynos_display *)display;
- tdm_exynos_output *output_data = NULL;
- hal_tdm_output **outputs;
- hal_tdm_error ret;
- int i;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data, NULL);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(count, NULL);
-
- *count = 0;
- LIST_FOR_EACH_ENTRY(output_data, &display_data->output_list, link)
- (*count)++;
-
- if (*count == 0) {
- ret = HAL_TDM_ERROR_NONE;
- goto failed_get;
- }
-
- /* will be freed in frontend */
- outputs = calloc(*count, sizeof(tdm_exynos_output *));
- if (!outputs) {
- TDM_BACKEND_ERR("failed: alloc memory");
- *count = 0;
- ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
- goto failed_get;
- }
-
- i = 0;
- LIST_FOR_EACH_ENTRY(output_data, &display_data->output_list, link)
- outputs[i++] = output_data;
-
- if (error)
- *error = HAL_TDM_ERROR_NONE;
-
- return outputs;
-failed_get:
- if (error)
- *error = ret;
- return NULL;
-}
-
-hal_tdm_error
-exynos_display_get_fd(hal_tdm_display *display, int *fd)
-{
- tdm_exynos_display *display_data = (tdm_exynos_display *)display;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(fd, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- *fd = display_data->drm_fd;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_display_handle_events(hal_tdm_display *display)
-{
- tdm_exynos_display *display_data = (tdm_exynos_display *)display;
- drmEventContext ctx;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data, HAL_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(display_data->drm_fd, &ctx);
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_pp *
-exynos_display_create_pp(hal_tdm_display *display, hal_tdm_error *error)
-{
- tdm_exynos_display *display_data = (tdm_exynos_display *)display;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data, NULL);
-
- if (display_data->use_ippv2)
- return tdm_exynos_pp_create(display_data, error);
- else
- return tdm_exynos_pp_legacy_create(display_data, error);
-}
+++ /dev/null
-/**************************************************************************
-
-libtdm_exynos
-
-Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_backend_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_BACKEND_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_BACKEND_ERR("drm format '%c%c%c%c' not found", FOURCC_STR(format));
-
- return 0;
-}
+++ /dev/null
-/**************************************************************************
-
-libtdm_exynos
-
-Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_backend_exynos.h"
-
-#define MIN_WIDTH 32
-
-hal_tdm_hwc_window *
-_exynos_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_hwc_window_info *info,
- hal_tdm_error *error);
-
-const char *
-_comp_to_str(hal_tdm_hwc_window_composition composition_type)
-{
- if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_CLIENT)
- return "CLIENT";
- else if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_DEVICE)
- return "DEVICE";
- else if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_CURSOR)
- return "CURSOR";
- else if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_VIDEO)
- return "VIDEO";
- else if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_NONE)
- return "SKIP";
-
- return "unknown";
-}
-
-static int
-_can_set_hwc_window_on_hw_layer(tdm_exynos_hwc_window *hwc_window_data)
-{
- if (!hwc_window_data->surface)
- return 0;
-
- if (hwc_window_data->info.transform != HAL_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 *
-_exynos_hwc_get_layer(tdm_exynos_hwc *hwc_data, int zpos)
-{
- tdm_exynos_output *output_data = hwc_data->output_data;
- tdm_exynos_layer *l = NULL;
-
- LIST_FOR_EACH_ENTRY(l, &output_data->layer_list, link)
- if (l->zpos == zpos)
- return l;
-
- return NULL;
-}
-
-static hal_tdm_error
-_set_hwc_window_buffer_to_layer(tdm_exynos_layer *layer_data,
- tdm_exynos_hwc_window *hwc_window_data)
-{
- hal_tdm_error ret;
-
- if (hwc_window_data == NULL || !hwc_window_data->surface) {
- ret = tdm_exynos_layer_unset_buffer(layer_data);
- } else {
- ret = tdm_exynos_layer_set_buffer(layer_data, hwc_window_data->surface);
- }
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret);
-
- return ret;
-}
-
-static tdm_exynos_hwc_window *
-_find_maped_hwc_window_to_layer(struct list_head *hwc_wnds, int layer_zpos)
-{
- tdm_exynos_hwc_window *hwc_window_data = NULL;
-
- LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
- if (hwc_window_data->client_type == HAL_TDM_HWC_WIN_COMPOSITION_NONE)
- continue;
-
- if (hwc_window_data->assigned_layer_zpos == layer_zpos &&
- (hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_DEVICE ||
- hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_CURSOR ||
- hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_VIDEO)) {
- TDM_BACKEND_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 *hwc_data)
-{
- tdm_exynos_layer *layer_data = NULL;
- tdm_exynos_output *output_data = hwc_data->output_data;
- tdm_exynos_hwc_window *hwc_window_data;
- hal_tdm_error ret;
-
- LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
- if (hwc_data->need_target_window && layer_data->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_data->zpos);
-
- if (hwc_window_data) {
- ret = tdm_exynos_layer_set_info((tdm_exynos_layer *)layer_data, (tdm_exynos_layer_info *)&(hwc_window_data->info));
- if (ret != HAL_TDM_ERROR_NONE)
- TDM_BACKEND_ERR("cannot set info to layer_data with %d zpos", layer_data->zpos);
- }
- }
-}
-
-static tdm_exynos_hwc_window *
-_exynos_hwc_find_assigned_hwc_window(struct list_head *hwc_wnds, int layer_zpos)
-{
- tdm_exynos_hwc_window *hwc_window_data = NULL;
-
- LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
- if (hwc_window_data->client_type == HAL_TDM_HWC_WIN_COMPOSITION_NONE)
- continue;
-
- if (hwc_window_data->assigned_layer_zpos == layer_zpos) {
- return hwc_window_data;
- }
- }
-
- return NULL;
-}
-
-static hal_tdm_error
-_exynos_hwc_prepare_commit(tdm_exynos_hwc *hwc_data) {
- tdm_exynos_layer *layer_data = NULL;
- tdm_exynos_hwc_window *hwc_window_data = NULL;
- tdm_exynos_output *output_data = hwc_data->output_data;
-
- _update_layers_info(hwc_data);
-
- /* set target hwc window */
- if (hwc_data->need_target_window) {
- layer_data = _exynos_hwc_get_layer(hwc_data, hwc_data->target_window_zpos);
- _set_hwc_window_buffer_to_layer(layer_data, hwc_data->target_hwc_window);
- }
-
- LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
- if (hwc_data->need_target_window && layer_data == output_data->primary_layer)
- continue;
-
- hwc_window_data = _exynos_hwc_find_assigned_hwc_window(&hwc_data->hwc_window_list, layer_data->zpos);
- if (hwc_window_data) {
- _set_hwc_window_buffer_to_layer(layer_data, hwc_window_data);
- } else {
- /* do not set the null on the primary layer_data */
- if (layer_data != output_data->primary_layer)
- _set_hwc_window_buffer_to_layer(layer_data, NULL);
- }
- }
-
- return HAL_TDM_ERROR_NONE;
-}
-
-static int
-_exynos_hwc_get_primary_layer_zpos(tdm_exynos_hwc *hwc_data)
-{
- tdm_exynos_output *output_data = hwc_data->output_data;
- tdm_exynos_layer *layer_data = NULL;
-
- LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
- if (layer_data->capabilities & TDM_EXYNOS_LAYER_CAPABILITY_PRIMARY)
- return layer_data->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 *hwc_data , hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds)
-{
- tdm_exynos_output *output_data = hwc_data->output_data;
- tdm_exynos_hwc_window **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**)composited_wnds;
-
- TDM_BACKEND_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 != HAL_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_data policy */
- for (i = 0; i < num_wnds; i++) {
- if (composited_list[i]->client_type == HAL_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_data */
- ++min_zpos;
- --available_layers;
- continue;
- }
-
- composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_CLIENT;
- composited_list[i]->candidate_layer_zpos = -1;
-
- /* The validate type of all windows below this window are HAL_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 == HAL_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_BACKEND_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 == HAL_TDM_HWC_WIN_COMPOSITION_VIDEO)
- continue;
- if (available_layers == 0)
- break;
-
- if (composited_list[i]->client_type == HAL_TDM_HWC_WIN_COMPOSITION_DEVICE ||
- composited_list[i]->client_type == HAL_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_BACKEND_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 == HAL_TDM_HWC_WIN_COMPOSITION_VIDEO)
- continue;
-
- composited_list[i]->validated_type = HAL_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 *hwc_data)
-{
- tdm_exynos_hwc_window *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 == HAL_TDM_HWC_WIN_COMPOSITION_NONE)
- continue;
-
- if (hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_DEVICE ||
- hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_CURSOR ||
- hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_VIDEO)
- TDM_BACKEND_DBG(" window(%p) type: %s -> %s : is mapped to layer_data 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_BACKEND_DBG(" window(%p) type: %s -> %s : is composited to layer_data 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 *hwc_data)
-{
- tdm_exynos_hwc_window *hwc_window_data = NULL;
-
- LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
- if (hwc_window_data->client_type == HAL_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_BACKEND_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 *hwc_data)
-{
- int num = 0;
- tdm_exynos_hwc_window *hwc_window_data = NULL;
-
- LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
- if (hwc_window_data->client_type == HAL_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 *hwc_data)
-{
- tdm_exynos_output *output_data = hwc_data->output_data;
- tdm_exynos_layer *layer_data = NULL;
-
- LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
- if (layer_data->capabilities & TDM_EXYNOS_LAYER_CAPABILITY_PRIMARY)
- return layer_data->zpos;
- }
-
- return 0;
-}
-#endif
-
-static tbm_surface_queue_h
-_exynos_hwc_window_get_tbm_buffer_queue(hal_tdm_hwc_window *hwc_window, hal_tdm_error *error)
-{
- tdm_exynos_hwc_window *hwc_window_data = NULL;
- tbm_surface_queue_h tqueue = NULL;
- int width, height;
- tbm_format format;
-
- if (error)
- *error = HAL_TDM_ERROR_INVALID_PARAMETER;
-
- TDM_BACKEND_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 = HAL_TDM_ERROR_OPERATION_FAILED;
- TDM_BACKEND_RETURN_VAL_IF_FAIL(tqueue != NULL, NULL);
-
- if (error)
- *error = HAL_TDM_ERROR_NONE;
-
- return tqueue;
-
-}
-
-hal_tdm_hwc_window *
-_exynos_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_hwc_window_info *info, hal_tdm_error *error)
-{
- tdm_exynos_hwc_window *hwc_window_data = NULL;
- tdm_exynos_hwc *hwc_data = hwc;
-
- if (error)
- *error = HAL_TDM_ERROR_NONE;
-
- if (!hwc_data) {
- TDM_BACKEND_ERR("invalid params");
- if (error)
- *error = HAL_TDM_ERROR_INVALID_PARAMETER;
- return NULL;
- }
-
- hwc_window_data = calloc(1, sizeof(tdm_exynos_hwc_window));
- if (!hwc_window_data) {
- TDM_BACKEND_ERR("alloc failed");
- if (error)
- *error = HAL_TDM_ERROR_OUT_OF_MEMORY;
- return NULL;
- }
-
- hwc_window_data->client_type = HAL_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(hal_tdm_hwc_window_info));
-
- LIST_INITHEAD(&hwc_window_data->link);
-
- return hwc_window_data;
-}
-
-hal_tdm_error
-exynos_hwc_initailize_target_window(tdm_exynos_hwc *hwc_data, int width, int height)
-{
- hal_tdm_hwc_window_info info = {0};
- hal_tdm_error ret = HAL_TDM_ERROR_NONE;
- tdm_exynos_hwc_window *target_hwc_window;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, HAL_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_BACKEND_ERR("create target hwc window failed (%d)", ret);
- return HAL_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_hwc_window *
-exynos_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_error *error)
-{
- tdm_exynos_hwc *hwc_data = hwc;
- tdm_exynos_hwc_window *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_BACKEND_DBG("hwc_window_data(%p) create", hwc_window_data);
- if (error)
- *error = HAL_TDM_ERROR_NONE;
-
- return hwc_window_data;
-}
-
-hal_tdm_error
-exynos_hwc_get_video_supported_formats(hal_tdm_hwc *hwc, const tbm_format **formats, int *count)
-{
- tdm_exynos_hwc *hwc_data = hwc;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(formats != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(count != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- // TODO:
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_hwc_get_capabilities(hal_tdm_hwc *hwc, hal_tdm_hwc_capability *capabilities)
-{
- tdm_exynos_hwc *hwc_data = hwc;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(capabilities != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- *capabilities = 0;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_hwc_get_available_properties(hal_tdm_hwc *hwc, const hal_tdm_prop **props, int *count)
-{
- tdm_exynos_hwc *hwc_data = hwc;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- // TODO:
-
- return HAL_TDM_ERROR_NONE;
-}
-
-tbm_surface_queue_h
-exynos_hwc_get_client_target_buffer_queue(hal_tdm_hwc *hwc, hal_tdm_error *error)
-{
- tdm_exynos_hwc *hwc_data = hwc;
- tbm_surface_queue_h tqueue = NULL;
-
- if (error)
- *error = HAL_TDM_ERROR_INVALID_PARAMETER;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, NULL);
-
- if (hwc_data->target_hwc_window == NULL) {
- if (error)
- *error = HAL_TDM_ERROR_OPERATION_FAILED;
- return NULL;
- }
-
- tqueue = _exynos_hwc_window_get_tbm_buffer_queue(hwc_data->target_hwc_window, error);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(tqueue, NULL);
-
- if (error)
- *error = HAL_TDM_ERROR_NONE;
-
- return tqueue;
-}
-
-hal_tdm_error
-exynos_hwc_set_client_target_buffer(hal_tdm_hwc *hwc, tbm_surface_h buffer,
- hal_tdm_region damage)
-{
- tdm_exynos_hwc *hwc_data = hwc;
- hal_tdm_error err;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window != NULL, HAL_TDM_ERROR_OPERATION_FAILED);
-
- err = exynos_hwc_window_set_buffer(hwc_data->target_hwc_window, buffer);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(err == HAL_TDM_ERROR_NONE, err);
-
- err = exynos_hwc_window_set_buffer_damage(hwc_data->target_hwc_window, damage);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(err == HAL_TDM_ERROR_NONE, err);
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_hwc_validate(hal_tdm_hwc *hwc, hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types)
-{
- tdm_exynos_hwc *hwc_data = hwc;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(num_types != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- _exynos_hwc_adapt_policy(hwc_data, composited_wnds, num_wnds);
-
- TDM_BACKEND_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_BACKEND_DBG(" !!!!!!! BUT NEED TO ACCEPT CHANES.!!!!!!!!");
- }
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_hwc_get_changed_composition_types(hal_tdm_hwc *hwc, uint32_t *num_elements, hal_tdm_hwc_window **hwc_wnds,
- hal_tdm_hwc_window_composition *composition_types)
-{
- tdm_exynos_hwc *hwc_data = hwc;
- tdm_exynos_hwc_window *hwc_window_data = NULL;
- int num = 0;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(num_elements != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- if ((hwc_wnds == NULL) || (composition_types == NULL)) {
- *num_elements = _exynos_hwc_get_changed_number(hwc_data);
- return HAL_TDM_ERROR_NONE;
- }
-
- LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
- if (hwc_window_data->client_type == HAL_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_hwc_accept_validation(hal_tdm_hwc *hwc)
-{
- tdm_exynos_hwc *hwc_data = hwc;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- TDM_BACKEND_DBG(" ==============Accept Changes Done=================================");
-
- _exynos_hwc_assigned_layer_zpos_update(hwc_data);
- hwc_data->need_validate = 0;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_hwc_commit(hal_tdm_hwc *hwc, int sync, void *user_data)
-{
- tdm_exynos_hwc *hwc_data = hwc;
- tdm_exynos_output *output_data = NULL;
- hal_tdm_error ret;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- output_data = hwc_data->output_data;
-
- ret = _exynos_hwc_prepare_commit(hwc_data);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret);
-
- ret = exynos_output_commit(output_data, sync, user_data);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret);
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_hwc_set_commit_handler(hal_tdm_hwc *hwc, hal_tdm_hwc_commit_handler func)
-{
- tdm_exynos_hwc *hwc_data = hwc;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- hwc_data->commit_func = func;
-
- return HAL_TDM_ERROR_NONE;
-}
\ No newline at end of file
+++ /dev/null
-/**************************************************************************
-
-libtdm_exynos
-
-Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_backend_exynos.h"
-
-tdm_exynos_layer *
-_exynos_output_get_layer(tdm_exynos_output *output_data, int index);
-
-void
-exynos_hwc_window_destroy(hal_tdm_hwc_window *hwc_window)
-{
- tdm_exynos_hwc_window *hwc_window_data = hwc_window;
-
- TDM_BACKEND_RETURN_IF_FAIL(hwc_window_data != NULL);
-
- LIST_DEL(&hwc_window_data->link);
-
- free(hwc_window_data);
-}
-
-hal_tdm_error
-exynos_hwc_window_set_composition_type(hal_tdm_hwc_window *hwc_window,
- hal_tdm_hwc_window_composition comp_type)
-{
- tdm_exynos_hwc_window *hwc_window_data = hwc_window;
- tdm_exynos_hwc *hwc_data = hwc_window_data->hwc_data;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_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 HAL_TDM_ERROR_NONE;
-
- hwc_window_data->client_type = comp_type;
-
- /* if the type is none, reset all status */
- if (hwc_window_data->client_type == HAL_TDM_HWC_WIN_COMPOSITION_NONE) {
- hwc_window_data->client_type = HAL_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_hwc_window_set_buffer_damage(hal_tdm_hwc_window *hwc_window, hal_tdm_region damage)
-{
- tdm_exynos_hwc_window *hwc_window_data = hwc_window;
- tdm_exynos_hwc *hwc_data = hwc_window_data->hwc_data;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- /* TODO:: */
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_hwc_window_set_info(hal_tdm_hwc_window *hwc_window, hal_tdm_hwc_window_info *info)
-{
- tdm_exynos_hwc_window *hwc_window_data = hwc_window;
- tdm_exynos_hwc *hwc_data;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
- hwc_data = hwc_window_data->hwc_data;
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- if (!memcmp(&hwc_window_data->info, info, sizeof(hal_tdm_hwc_window_info)))
- return HAL_TDM_ERROR_NONE;
-
- hwc_window_data->info = *info;
- hwc_data->need_validate = 1;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_hwc_window_set_buffer(hal_tdm_hwc_window *hwc_window, tbm_surface_h surface)
-{
- tdm_exynos_hwc_window *hwc_window_data = hwc_window;
- hal_tdm_error err = HAL_TDM_ERROR_OPERATION_FAILED;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, err);
-
- if (hwc_window_data->surface == surface)
- return HAL_TDM_ERROR_NONE;
-
- hwc_window_data->surface = surface;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_hwc_window_set_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value value)
-{
- tdm_exynos_hwc_window *hwc_window_data = hwc_window;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
-#if 0
- output_data = hwc_window_data->output_data;
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- layer_data = _exynos_output_get_layer(output_data, hwc_window_data->assigned_layer_zpos);
-
- return tdm_exynos_layer_set_property(layer_data, id, value);
-#endif
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_hwc_window_get_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value *value)
-{
- tdm_exynos_hwc_window *hwc_window_data = hwc_window;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
-#if 0
- output_data = hwc_window_data->output_data;
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- layer_data = _exynos_output_get_layer(output_data, hwc_window_data->assigned_layer_zpos);
-
- return tdm_exynos_layer_get_property(layer_data, id, value);
-#endif
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_hwc_window_get_constraints(hal_tdm_hwc_window *hwc_window, int *constraints)
-{
- tdm_exynos_hwc_window *hwc_window_data = hwc_window;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- return HAL_TDM_ERROR_NONE;
-}
+++ /dev/null
-/**************************************************************************
-
-libtdm_exynos
-
-Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_backend_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->display_data->drm_fd, display_buffer->fb_id);
- if (ret < 0) {
- TDM_BACKEND_ERR("rm fb failed");
- return;
- }
- TDM_BACKEND_DBG("drmModeRmFB success!!! fb_id:%d", display_buffer->fb_id);
- } else
- TDM_BACKEND_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_display *display_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));
- TDM_BACKEND_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_BACKEND_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_BACKEND_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->display_data = display_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(display_data->drm_fd, width, height, format,
- handles, pitches, offsets, &display_buffer->fb_id, 0);
- if (ret < 0) {
- TDM_BACKEND_ERR("add fb failed: %m");
- free(display_buffer);
- return NULL;
- }
- TDM_BACKEND_DBG("display_data->drm_fd : %d, display_buffer->fb_id:%u", display_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;
-}
-
-hal_tdm_error
-tdm_exynos_layer_get_capability(tdm_exynos_layer *layer_data, tdm_exynos_caps_layer *caps)
-{
- tdm_exynos_display *display_data;
- drmModePlanePtr plane = NULL;
- drmModeObjectPropertiesPtr props = NULL;
- int i, fmt_count;
- hal_tdm_error ret;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(caps, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- memset(caps, 0, sizeof(tdm_exynos_caps_layer));
-
- display_data = layer_data->display_data;
- plane = drmModeGetPlane(display_data->drm_fd, layer_data->plane_id);
- if (!plane) {
- TDM_BACKEND_ERR("get plane failed: %m");
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- goto failed_get;
- }
-
- caps->capabilities = layer_data->capabilities;
- caps->zpos = layer_data->zpos; /* if VIDEO layer_data, zpos is -1 */
-
- caps->formats = calloc(1, sizeof(tbm_format) * plane->count_formats);
- if (!caps->formats) {
- ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
- TDM_BACKEND_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(display_data->drm_fd, layer_data->plane_id,
- DRM_MODE_OBJECT_PLANE);
- if (!props) {
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- TDM_BACKEND_ERR("get plane properties failed: %m\n");
- goto failed_get;
- }
-
- caps->props = calloc(1, sizeof(hal_tdm_prop) * props->count_props);
- if (!caps->props) {
- ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
- TDM_BACKEND_ERR("alloc failed\n");
- goto failed_get;
- }
-
- caps->prop_count = 0;
- for (i = 0; i < props->count_props; i++) {
- drmModePropertyPtr prop = drmModeGetProperty(display_data->drm_fd,
- props->props[i]);
- if (!prop)
- continue;
- if (!strncmp(prop->name, "type", HAL_TDM_NAME_LEN)) {
- drmModeFreeProperty(prop);
- continue;
- }
- if (!strncmp(prop->name, "zpos", HAL_TDM_NAME_LEN)) {
- drmModeFreeProperty(prop);
- continue;
- }
- snprintf(caps->props[caps->prop_count].name, HAL_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 HAL_TDM_ERROR_NONE;
-failed_get:
- drmModeFreeObjectProperties(props);
- drmModeFreePlane(plane);
- free(caps->formats);
- free(caps->props);
- memset(caps, 0, sizeof(tdm_exynos_caps_layer));
- return ret;
-}
-
-hal_tdm_error
-tdm_exynos_layer_set_property(tdm_exynos_layer *layer_data, unsigned int id, hal_tdm_value value)
-{
- tdm_exynos_display *display_data;
- int ret;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data->plane_id > 0, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- display_data = layer_data->display_data;
- ret = drmModeObjectSetProperty(display_data->drm_fd,
- layer_data->plane_id, DRM_MODE_OBJECT_PLANE,
- id, value.u32);
- if (ret < 0) {
- TDM_BACKEND_ERR("set property failed: %m");
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-tdm_exynos_layer_get_property(tdm_exynos_layer *layer_data, unsigned int id, hal_tdm_value *value)
-{
- tdm_exynos_display *display_data;
- drmModeObjectPropertiesPtr props;
- hal_tdm_error ret = HAL_TDM_ERROR_INVALID_PARAMETER;
- int i;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data->plane_id > 0, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(value, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- display_data = layer_data->display_data;
- props = drmModeObjectGetProperties(display_data->drm_fd, layer_data->plane_id,
- DRM_MODE_OBJECT_PLANE);
- if (props == NULL) {
- TDM_BACKEND_ERR("get property failed: %m");
- return HAL_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 = HAL_TDM_ERROR_NONE;
- break;
- }
-
- drmModeFreeObjectProperties(props);
-
- if (ret != HAL_TDM_ERROR_NONE)
- TDM_BACKEND_ERR("unknown property id: %ud", id);
-
- return ret;
-}
-
-hal_tdm_error
-tdm_exynos_layer_set_info(tdm_exynos_layer *layer_data, tdm_exynos_layer_info *info)
-{
- TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(info, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- layer_data->info = *info;
- layer_data->info_changed = 1;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-tdm_exynos_layer_get_info(tdm_exynos_layer *layer_data, tdm_exynos_layer_info *info)
-{
- TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(info, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- *info = layer_data->info;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-tdm_exynos_layer_set_buffer(tdm_exynos_layer *layer_data, tbm_surface_h buffer)
-{
- tdm_exynos_display *display_data;
- tdm_exynos_display_buffer *display_buffer;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(buffer, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- display_data = layer_data->display_data;
-
- display_buffer = _tdm_exynos_display_get_buffer(display_data, buffer);
- if (!display_buffer) {
- TDM_BACKEND_ERR("alloc failed");
- return HAL_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-tdm_exynos_layer_unset_buffer(tdm_exynos_layer *layer_data)
-{
- TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- if (layer_data->display_buffer &&
- (!(layer_data->capabilities & TDM_EXYNOS_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-tdm_exynos_layer_get_supported_format(tdm_exynos_layer *layer_data, const tbm_format **out_formats,
- int *out_format_count)
-{
- tdm_exynos_display *display_data;
- drmModePlanePtr plane = NULL;
- int i, j;
- hal_tdm_error ret;
- tbm_format *formats = NULL;
- int format_count = 0;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(out_formats, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(out_format_count, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- if (layer_data->formats) {
- *out_formats = layer_data->formats;
- *out_format_count = layer_data->format_count;
-
- return HAL_TDM_ERROR_NONE;
- }
-
- display_data = layer_data->display_data;
- plane = drmModeGetPlane(display_data->drm_fd, layer_data->plane_id);
- if (!plane) {
- TDM_BACKEND_ERR("get plane failed: %m");
- ret = HAL_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 = HAL_TDM_ERROR_OUT_OF_MEMORY;
- TDM_BACKEND_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 HAL_TDM_ERROR_NONE;
-failed_get:
- drmModeFreePlane(plane);
- free(formats);
- *out_formats = NULL;
- *out_format_count = 0;
- return ret;
-}
-
-hal_tdm_error
-tdm_exynos_layer_get_available_properties(tdm_exynos_layer *layer_data, const hal_tdm_prop **out_props,
- int *out_prop_count)
-{
- tdm_exynos_display *display_data;
- drmModePlanePtr plane = NULL;
- drmModeObjectPropertiesPtr props = NULL;
- int i;
- hal_tdm_error ret;
- hal_tdm_prop *tdm_props = NULL;
- int prop_count;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(out_props, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(out_prop_count, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- if (layer_data->props) {
- *out_props = layer_data->props;
- *out_prop_count = layer_data->prop_count;
-
- return HAL_TDM_ERROR_NONE;
- }
-
- display_data = layer_data->display_data;
- plane = drmModeGetPlane(display_data->drm_fd, layer_data->plane_id);
- if (!plane) {
- TDM_BACKEND_ERR("get plane failed: %m");
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- goto failed_get;
- }
-
- props = drmModeObjectGetProperties(display_data->drm_fd, layer_data->plane_id,
- DRM_MODE_OBJECT_PLANE);
- if (!props) {
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- TDM_BACKEND_ERR("get plane properties failed: %m\n");
- goto failed_get;
- }
-
- tdm_props = calloc(1, sizeof(hal_tdm_prop) * props->count_props);
- if (!tdm_props) {
- ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
- TDM_BACKEND_ERR("alloc failed\n");
- goto failed_get;
- }
-
- prop_count = 0;
- for (i = 0; i < props->count_props; i++) {
- drmModePropertyPtr prop = drmModeGetProperty(display_data->drm_fd,
- props->props[i]);
- if (!prop)
- continue;
- if (!strncmp(prop->name, "type", HAL_TDM_NAME_LEN)) {
- drmModeFreeProperty(prop);
- continue;
- }
- if (!strncmp(prop->name, "zpos", HAL_TDM_NAME_LEN)) {
- drmModeFreeProperty(prop);
- continue;
- }
- snprintf(tdm_props[prop_count].name, HAL_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 HAL_TDM_ERROR_NONE;
-failed_get:
- drmModeFreeObjectProperties(props);
- drmModeFreePlane(plane);
- *out_props = NULL;
- *out_prop_count = 0;
-
- return ret;
-}
+++ /dev/null
-/**************************************************************************
-
-libtdm_exynos
-
-Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_backend_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 hal_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 HAL_TDM_ERROR_INVALID_PARAMETER;
- return HAL_TDM_ERROR_NONE;
-}
-
-static hal_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_BACKEND_ERR("buf_w(%u) not 2's multiple or less than %u", buf_w, MIN_WIDTH);
- return HAL_TDM_ERROR_BAD_REQUEST;
- }
-
- if (dst_x > crtc_w || dst_y > crtc_h) {
- TDM_BACKEND_ERR("dst_pos(%u,%u) is out of crtc(%ux%u)", dst_x, dst_y, crtc_w, crtc_h);
- return HAL_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_BACKEND_ERR("visible_w(%d) less than %u", end - start, MIN_WIDTH);
- return HAL_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;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(*new_src_w > 0, HAL_TDM_ERROR_BAD_REQUEST);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(*new_dst_w > 0, HAL_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_BACKEND_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 HAL_TDM_ERROR_NONE;
-}
-
-static drmModeModeInfoPtr
-_tdm_exynos_output_get_mode(tdm_exynos_output *output_data)
-{
- int i;
-
- if (!output_data->current_mode) {
- TDM_BACKEND_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, HAL_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, HAL_TDM_NAME_LEN)))
- return drm_mode;
- }
- }
-
- return NULL;
-}
-
-static hal_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_BACKEND_ERR("get vblank counter failed: %m");
- *msc = 0;
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- *msc = vbl.reply.sequence;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-static hal_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_BACKEND_ERR("wait vblank failed: %m");
- *target_msc = 0;
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- *target_msc = vbl.reply.sequence;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-static void
-_tdm_exynos_output_transform_layer_info(int width, int height, tdm_exynos_layer_info *info)
-{
- hal_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 hal_tdm_error
-_tdm_exynos_output_commit_primary_layer(tdm_exynos_layer *layer_data,
- void *user_data, int *do_waitvblank)
-{
- tdm_exynos_display *display_data = layer_data->display_data;
- tdm_exynos_output *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_exynos_layer_info layer_info = layer_data->info;
- drmModeModeInfoPtr mode;
-
- if (!layer_data->display_buffer) {
- TDM_BACKEND_ERR("primary layer_data should have a buffer for modestting");
- return HAL_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(display_data->drm_fd, output_data->crtc_id);
- if (!crtc) {
- TDM_BACKEND_ERR("getting crtc failed");
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
- crtc_w = crtc->width;
- crtc_h = crtc->height;
- if (crtc_w == 0) {
- TDM_BACKEND_ERR("getting crtc width failed");
- drmModeFreeCrtc(crtc);
- return HAL_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_BACKEND_ERR("couldn't find proper mode");
- return HAL_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) != HAL_TDM_ERROR_NONE)
- TDM_BACKEND_WRN("not going to set crtc(%u)", output_data->crtc_id);
-
- if (layer_info.src_config.pos.x != new_x)
- TDM_BACKEND_DBG("src_x changed: %u => %u", layer_info.src_config.pos.x,
- new_x);
- if (layer_info.src_config.pos.y != new_y)
- TDM_BACKEND_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_BACKEND_DBG("SetCrtc: drm_fd(%d) crtc_id(%u) fb_id(%u) mode(%ux%u, %uhz) pos(%u %u)",
- display_data->drm_fd, output_data->crtc_id, layer_data->display_buffer->fb_id,
- mode->hdisplay, mode->vdisplay, mode->vrefresh, fx, fy);
-
- if (drmModeSetCrtc(display_data->drm_fd, output_data->crtc_id,
- layer_data->display_buffer->fb_id, fx, fy,
- &output_data->connector_id, 1, mode)) {
- TDM_BACKEND_ERR("set crtc failed: %m");
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- tdm_exynos_output_update_status(output_data, HAL_TDM_OUTPUT_CONN_STATUS_MODE_SETTED);
-
- *do_waitvblank = 1;
-
- return HAL_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 *event_data = calloc(1, sizeof(tdm_exynos_event));
-
- if (!event_data) {
- TDM_BACKEND_ERR("alloc failed");
- return HAL_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;
-
- TDM_BACKEND_DBG("PageFlip: drm_fd(%d) crtc_id(%u) fb_id(%u)",
- display_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(display_data->drm_fd, output_data->crtc_id,
- layer_data->display_buffer->fb_id, DRM_MODE_PAGE_FLIP_EVENT, event_data)) {
- TDM_BACKEND_ERR("pageflip failed: %m");
- free(event_data);
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
- *do_waitvblank = 0;
- } else {
- /* to call a user commit handler whenever committed */
- *do_waitvblank = 1;
- }
- }
-
- return HAL_TDM_ERROR_NONE;
-}
-
-static hal_tdm_error
-_tdm_exynos_output_commit_layer(tdm_exynos_layer *layer_data)
-{
- tdm_exynos_display *display_data = layer_data->display_data;
- tdm_exynos_output *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_exynos_layer_info layer_info = layer_data->info;
-
- if (!layer_data->display_buffer_changed && !layer_data->info_changed)
- return HAL_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(display_data->drm_fd, output_data->crtc_id);
- if (!crtc) {
- TDM_BACKEND_ERR("getting crtc failed");
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
- crtc_w = crtc->width;
- crtc_h = crtc->height;
- if (crtc_w == 0) {
- TDM_BACKEND_ERR("getting crtc width failed");
- drmModeFreeCrtc(crtc);
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
- drmModeFreeCrtc(crtc);
- }
-
- layer_data->display_buffer_changed = 0;
- layer_data->info_changed = 0;
-
- if (!layer_data->display_buffer) {
- TDM_BACKEND_DBG("SetPlane: drm_fd(%d) plane_id(%u) crtc_id(%u) off",
- display_data->drm_fd, layer_data->plane_id, output_data->crtc_id);
-
- if (drmModeSetPlane(display_data->drm_fd, layer_data->plane_id,
- output_data->crtc_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
- TDM_BACKEND_ERR("unset plane(%u) filed: %m", layer_data->plane_id);
-
- return HAL_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) != HAL_TDM_ERROR_NONE) {
- TDM_BACKEND_WRN("not going to set plane(%u)", layer_data->plane_id);
- return HAL_TDM_ERROR_NONE;
- }
-
- if (layer_info.src_config.pos.x != new_src_x)
- TDM_BACKEND_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_BACKEND_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_BACKEND_DBG("dst_x changed: %u => %u", layer_info.dst_pos.x, new_dst_x);
- if (layer_info.dst_pos.w != new_dst_w)
- TDM_BACKEND_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_BACKEND_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)",
- display_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(display_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_BACKEND_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",
- display_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 HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- return HAL_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 *event_data = user_data;
- tdm_exynos_output *output_data;
- tdm_exynos_hwc *hwc_data;
-
- if (!event_data) {
- TDM_BACKEND_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 (hwc_data->commit_func)
- hwc_data->commit_func(hwc_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);
-}
-
-hal_tdm_error
-tdm_exynos_output_update_status(tdm_exynos_output *output_data,
- hal_tdm_output_conn_status status)
-{
- tdm_exynos_layer *layer_data = NULL;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- if (output_data->status == status)
- return HAL_TDM_ERROR_NONE;
-
- output_data->status = status;
-
- LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
- if (status == HAL_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_output_get_capability(hal_tdm_output *output, hal_tdm_caps_output *caps)
-{
- tdm_exynos_output *output_data = output;
- tdm_exynos_display *display_data;
- drmModeConnectorPtr connector = NULL;
- drmModeCrtcPtr crtc = NULL;
- drmModeObjectPropertiesPtr props = NULL;
- int i;
- hal_tdm_error ret;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(caps, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- memset(caps, 0, sizeof(hal_tdm_caps_output));
-
- display_data = output_data->display_data;
-
- snprintf(caps->maker, HAL_TDM_NAME_LEN, "unknown");
- snprintf(caps->model, HAL_TDM_NAME_LEN, "unknown");
- snprintf(caps->name, HAL_TDM_NAME_LEN, "unknown");
-
- caps->type = output_data->connector_type;
- caps->type_id = output_data->connector_type_id;
-
- connector = drmModeGetConnector(display_data->drm_fd, output_data->connector_id);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(connector, HAL_TDM_ERROR_OPERATION_FAILED);
-
- caps->mode_count = connector->count_modes;
- caps->modes = calloc(1, sizeof(hal_tdm_output_mode) * caps->mode_count);
- if (!caps->modes) {
- ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
- TDM_BACKEND_ERR("alloc failed\n");
- goto failed_get;
- }
- if (caps->mode_count != output_data->count_modes) {
- drmModeModeInfoPtr new_drm_modes;
- hal_tdm_output_mode *new_output_modes;
-
- new_drm_modes = calloc(connector->count_modes,
- sizeof(drmModeModeInfo));
- if (!new_drm_modes) {
- ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
- TDM_BACKEND_ERR("alloc failed drm_modes\n");
- goto failed_get;
- }
- new_output_modes = calloc(connector->count_modes,
- sizeof(hal_tdm_output_mode));
- if (!new_output_modes) {
- ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
- TDM_BACKEND_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 = HAL_TDM_OUTPUT_CONN_STATUS_CONNECTED;
- else
- output_data->status = HAL_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 = display_data->mode_res->min_height;
- caps->min_h = display_data->mode_res->min_width;
- caps->max_w = display_data->mode_res->max_height;
- caps->max_h = display_data->mode_res->max_width;
- } else {
- caps->mmWidth = connector->mmWidth;
- caps->mmHeight = connector->mmHeight;
- caps->min_w = display_data->mode_res->min_width;
- caps->min_h = display_data->mode_res->min_height;
- caps->max_w = display_data->mode_res->max_width;
- caps->max_h = display_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(display_data->drm_fd, output_data->crtc_id);
- if (!crtc) {
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- TDM_BACKEND_ERR("get crtc failed: %m\n");
- goto failed_get;
- }
-
- props = drmModeObjectGetProperties(display_data->drm_fd, output_data->crtc_id,
- DRM_MODE_OBJECT_CRTC);
- if (!props) {
- ret = HAL_TDM_ERROR_OPERATION_FAILED;
- TDM_BACKEND_ERR("get crtc properties failed: %m\n");
- goto failed_get;
- }
-
- caps->props = calloc(1, sizeof(hal_tdm_prop) * props->count_props);
- if (!caps->props) {
- ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
- TDM_BACKEND_ERR("alloc failed\n");
- goto failed_get;
- }
-
- caps->prop_count = 0;
- for (i = 0; i < props->count_props; i++) {
- drmModePropertyPtr prop = drmModeGetProperty(display_data->drm_fd,
- props->props[i]);
- if (!prop)
- continue;
- snprintf(caps->props[caps->prop_count].name, HAL_TDM_NAME_LEN, "%s", prop->name);
- caps->props[caps->prop_count].id = props->props[i];
- caps->prop_count++;
- drmModeFreeProperty(prop);
- }
-
- caps->capabilities |= HAL_TDM_OUTPUT_CAPABILITY_HWC;
-
- drmModeFreeObjectProperties(props);
- drmModeFreeCrtc(crtc);
- drmModeFreeConnector(connector);
-
- return HAL_TDM_ERROR_NONE;
-failed_get:
- drmModeFreeCrtc(crtc);
- drmModeFreeObjectProperties(props);
- drmModeFreeConnector(connector);
- free(caps->modes);
- free(caps->props);
- memset(caps, 0, sizeof(hal_tdm_caps_output));
- return ret;
-}
-
-hal_tdm_error
-exynos_output_set_property(hal_tdm_output *output, unsigned int id, hal_tdm_value value)
-{
- tdm_exynos_output *output_data = output;
- tdm_exynos_display *display_data;
- int ret;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data->crtc_id > 0, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- display_data = output_data->display_data;
- ret = drmModeObjectSetProperty(display_data->drm_fd,
- output_data->crtc_id, DRM_MODE_OBJECT_CRTC,
- id, value.u32);
- if (ret < 0) {
- TDM_BACKEND_ERR("set property failed: %m");
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_output_get_property(hal_tdm_output *output, unsigned int id,
- hal_tdm_value *value)
-{
- tdm_exynos_output *output_data = output;
- tdm_exynos_display *display_data;
- drmModeObjectPropertiesPtr props;
- int i;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data->crtc_id > 0, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(value, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- display_data = output_data->display_data;
- props = drmModeObjectGetProperties(display_data->drm_fd, output_data->crtc_id,
- DRM_MODE_OBJECT_CRTC);
- if (props == NULL) {
- TDM_BACKEND_ERR("get property failed: %m");
- return HAL_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_output_wait_vblank(hal_tdm_output *output, int interval, int sync,
- void *user_data)
-{
- tdm_exynos_output *output_data = output;
- tdm_exynos_display *display_data;
- tdm_exynos_event *event_data;
- uint target_msc;
- hal_tdm_error ret;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- event_data = calloc(1, sizeof(tdm_exynos_event));
- if (!event_data) {
- TDM_BACKEND_ERR("alloc failed");
- return HAL_TDM_ERROR_OUT_OF_MEMORY;
- }
-
- display_data = output_data->display_data;
-
- ret = _tdm_exynos_output_get_cur_msc(display_data->drm_fd, output_data->pipe,
- &target_msc);
- if (ret != HAL_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(display_data->drm_fd, output_data->pipe,
- &target_msc, event_data);
- if (ret != HAL_TDM_ERROR_NONE)
- goto failed_vblank;
-
- return HAL_TDM_ERROR_NONE;
-failed_vblank:
- free(event_data);
- return ret;
-}
-
-hal_tdm_error
-exynos_output_set_vblank_handler(hal_tdm_output *output,
- hal_tdm_output_vblank_handler func)
-{
- tdm_exynos_output *output_data = output;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- output_data->vblank_func = func;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_output_commit(hal_tdm_output *output, int sync, void *user_data)
-{
- tdm_exynos_output *output_data = output;
- tdm_exynos_display *display_data;
- tdm_exynos_layer *layer_data = NULL;
- hal_tdm_error ret;
- int do_waitvblank = 1;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- display_data = output_data->display_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 != HAL_TDM_ERROR_NONE)
- return ret;
- } else {
- ret = _tdm_exynos_output_commit_layer(layer_data);
- if (ret != HAL_TDM_ERROR_NONE)
- return ret;
- }
- }
-
- if (do_waitvblank == 1) {
- tdm_exynos_event *event_data = calloc(1, sizeof(tdm_exynos_event));
- uint target_msc;
-
- if (!event_data) {
- TDM_BACKEND_ERR("alloc failed");
- return HAL_TDM_ERROR_OUT_OF_MEMORY;
- }
-
- ret = _tdm_exynos_output_get_cur_msc(display_data->drm_fd, output_data->pipe,
- &target_msc);
- if (ret != HAL_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;
-
- ret = _tdm_exynos_output_wait_vblank(display_data->drm_fd, output_data->pipe,
- &target_msc, event_data);
- if (ret != HAL_TDM_ERROR_NONE) {
- free(event_data);
- return ret;
- }
- }
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_output_set_commit_handler(hal_tdm_output *output,
- hal_tdm_output_commit_handler func)
-{
- tdm_exynos_output *output_data = output;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- output_data->commit_func = func;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_output_set_dpms(hal_tdm_output *output, hal_tdm_output_dpms dpms_value)
-{
- tdm_exynos_output *output_data = output;
- tdm_exynos_display *display_data;
- int ret;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- display_data = output_data->display_data;
- ret = drmModeObjectSetProperty(display_data->drm_fd,
- output_data->connector_id, DRM_MODE_OBJECT_CONNECTOR,
- output_data->dpms_prop_id, dpms_value);
- if (ret < 0) {
- TDM_BACKEND_ERR("set dpms failed: %m");
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_output_get_dpms(hal_tdm_output *output, hal_tdm_output_dpms *dpms_value)
-{
- tdm_exynos_output *output_data = output;
- tdm_exynos_display *display_data;
- drmModeObjectPropertiesPtr props;
- int i;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(dpms_value, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- display_data = output_data->display_data;
- props = drmModeObjectGetProperties(display_data->drm_fd,
- output_data->connector_id, DRM_MODE_OBJECT_CONNECTOR);
- if (props == NULL) {
- TDM_BACKEND_ERR("get property failed: %m");
- return HAL_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_output_set_mode(hal_tdm_output *output, const hal_tdm_output_mode *mode)
-{
- tdm_exynos_output *output_data = output;
- hal_tdm_error ret = HAL_TDM_ERROR_NONE;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(mode, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- /* create or replace the target_window when the output mode is set */
- ret = exynos_hwc_initailize_target_window(output_data->hwc_data, mode->hdisplay, mode->vdisplay);
- if (ret != HAL_TDM_ERROR_NONE) {
- TDM_BACKEND_ERR("create target hwc window failed (%d)", ret);
- return ret;
- }
-
- output_data->current_mode = mode;
- output_data->mode_changed = 1;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_output_get_mode(hal_tdm_output *output, const hal_tdm_output_mode **mode)
-{
- tdm_exynos_output *output_data = output;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(mode, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- *mode = output_data->current_mode;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_capture*
-exynos_output_create_capture(hal_tdm_output *output, hal_tdm_error *error)
-{
- tdm_exynos_output *output_data = output;
- tdm_exynos_display *display_data;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, NULL);
-
- display_data = output_data->display_data;
-
- if (display_data->use_ippv2)
- return tdm_exynos_capture_create_output(display_data, output, error);
- else
- return tdm_exynos_capture_legacy_create_output(display_data, output, error);
-}
-
-hal_tdm_error
-exynos_output_set_status_handler(hal_tdm_output *output,
- hal_tdm_output_status_handler func,
- void *user_data)
-{
- tdm_exynos_output *output_data = output;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- output_data->status_func = func;
- output_data->status_user_data = user_data;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_hwc *
-exynos_output_get_hwc(hal_tdm_output *output, hal_tdm_error *error)
-{
- tdm_exynos_hwc *hwc_data = NULL;
- tdm_exynos_output *output_data = output;
-
- if (!output_data) {
- TDM_BACKEND_ERR("invalid params");
- if (error)
- *error = HAL_TDM_ERROR_INVALID_PARAMETER;
- return NULL;
- }
-
- if (output_data->hwc_data) {
- TDM_BACKEND_INFO("hwc_data already exists");
- if (error)
- *error = HAL_TDM_ERROR_NONE;
- return output_data->hwc_data;
- }
-
- hwc_data = calloc(1, sizeof(tdm_exynos_hwc));
- if (!hwc_data) {
- TDM_BACKEND_ERR("alloc failed");
- if (error)
- *error = HAL_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 = HAL_TDM_ERROR_NONE;
-
- return hwc_data;
-}
+++ /dev/null
-/**************************************************************************
-
-libtdm_exynos
-
-Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_backend_exynos.h"
-
-typedef struct _tdm_exynos_pp_data {
- tdm_exynos_display *display_data;
-
- hal_tdm_info_pp info;
-
- struct list_head pending_buffer_list;
- struct list_head buffer_list;
-
- hal_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 hal_tdm_transform_to_drm(hal_tdm_transform t)
-{
- switch (t) {
- case HAL_TDM_TRANSFORM_NORMAL:
- return DRM_MODE_ROTATE_0;
- case HAL_TDM_TRANSFORM_90:
- return DRM_MODE_ROTATE_90;
- case HAL_TDM_TRANSFORM_180:
- return DRM_MODE_ROTATE_180;
- case HAL_TDM_TRANSFORM_270:
- return DRM_MODE_ROTATE_270;
- case HAL_TDM_TRANSFORM_FLIPPED:
- return DRM_MODE_REFLECT_Y;
- case HAL_TDM_TRANSFORM_FLIPPED_90:
- return DRM_MODE_REFLECT_Y | DRM_MODE_ROTATE_90;
- case HAL_TDM_TRANSFORM_FLIPPED_180:
- return DRM_MODE_REFLECT_Y | DRM_MODE_ROTATE_180;
- case HAL_TDM_TRANSFORM_FLIPPED_270:
- return DRM_MODE_REFLECT_Y | DRM_MODE_ROTATE_270;
- }
- return 0;
-}
-
-static hal_tdm_error
-_tdm_exynos_pp_process(tdm_exynos_pp_data *pp_data, tdm_exynos_pp_buffer *buffer)
-{
- tdm_exynos_display *display_data = pp_data->display_data;
- hal_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 = hal_tdm_transform_to_drm(info->transform);
-
- CLEAR(arg);
- arg.flags = DRM_EXYNOS_IPP_FLAG_EVENT | DRM_EXYNOS_IPP_FLAG_NONBLOCK;
- arg.ipp_id = display_data->ipp_module_id;
- arg.params_size = sizeof(task);
- arg.params_ptr = (unsigned long)(&task);
- arg.user_data = (__u64)(uintptr_t)buffer;
-
- ret = ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_COMMIT, &arg);
- if (ret) {
- TDM_BACKEND_ERR("ipp commit failed. %xx pp_data(%p), buffer(%p). %m", DRM_IOCTL_EXYNOS_IPP_COMMIT, pp_data, buffer);
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- return HAL_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_BACKEND_ERR("invalid params");
- return;
- }
-
- if (!pp_list_init)
- return;
-
- pp_data = dequeued_buffer->pp_data;
-
- TDM_BACKEND_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_BACKEND_DBG("dequeued: %p", dequeued_buffer);
- break;
- }
- }
-
- if (!pp_data->first_event) {
- TDM_BACKEND_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;
-
-hal_tdm_error
-tdm_exynos_pp_init(tdm_exynos_display *display_data)
-{
- struct drm_exynos_ioctl_ipp_get_caps caps_arg;
- struct drm_exynos_ioctl_ipp_get_res res_arg;
- uint32_t *ipps;
- int i;
-
- display_data->ipp_module_id = -1;
-
- CLEAR(res_arg);
- if (ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_RESOURCES,
- &res_arg)) {
- TDM_BACKEND_ERR("failed to get Exynos IPP resources");
- return HAL_TDM_ERROR_NO_CAPABILITY;
- }
-
- ipps = calloc(res_arg.count_ipps, sizeof(*ipps));
- if (!ipps) {
- TDM_BACKEND_ERR("alloc failed");
- return HAL_TDM_ERROR_OUT_OF_MEMORY;
- }
-
- res_arg.ipp_id_ptr = (unsigned long)ipps;
- if (ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_RESOURCES,
- &res_arg)) {
- TDM_BACKEND_ERR("failed to get Exynos IPP resources");
- free(ipps);
- return HAL_TDM_ERROR_NO_CAPABILITY;
- }
-
- for (i = 0; i < res_arg.count_ipps; i++) {
- CLEAR(caps_arg);
- caps_arg.ipp_id = ipps[i];
- if (ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_CAPS,
- &caps_arg)) {
- TDM_BACKEND_ERR("failed to get IPP capabilities");
- free(ipps);
- return HAL_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 HAL_TDM_ERROR_NO_CAPABILITY;
- }
-
- TDM_BACKEND_INFO("selected Exynos IPP module id %d", ipps[i]);
- display_data->ipp_module_id = ipps[i];
- free(ipps);
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-tdm_exynos_pp_get_capability(tdm_exynos_display *display_data, hal_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_BACKEND_ERR("invalid params");
- return HAL_TDM_ERROR_INVALID_PARAMETER;
- }
-
- CLEAR(caps_arg);
- caps_arg.ipp_id = display_data->ipp_module_id;
- if (ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_CAPS,
- &caps_arg)) {
- TDM_BACKEND_ERR("failed to get IPP capabilities");
- return HAL_TDM_ERROR_NO_CAPABILITY;
- }
-
- formats = calloc(caps_arg.formats_count, sizeof(*formats));
- if (!formats) {
- TDM_BACKEND_ERR("alloc failed");
- return HAL_TDM_ERROR_OUT_OF_MEMORY;
- }
-
- caps_arg.formats_ptr = (unsigned long) formats;
- if (ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_CAPS,
- &caps_arg)) {
- TDM_BACKEND_ERR("failed to get IPP capabilities");
- free(formats);
- return HAL_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 = HAL_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_BACKEND_ERR("alloc failed");
- free(formats);
- return HAL_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_pp *
-tdm_exynos_pp_create(tdm_exynos_display *display_data, hal_tdm_error *error)
-{
- tdm_exynos_pp_data *pp_data = calloc(1, sizeof(tdm_exynos_pp_data));
- if (!pp_data) {
- TDM_BACKEND_ERR("alloc failed");
- if (error)
- *error = HAL_TDM_ERROR_OUT_OF_MEMORY;
- return NULL;
- }
-
- pp_data->display_data = display_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(hal_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);
-}
-
-hal_tdm_error
-exynos_pp_set_info(hal_tdm_pp *pp, hal_tdm_info_pp *info)
-{
- tdm_exynos_pp_data *pp_data = pp;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(info, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- if (info->sync) {
- TDM_BACKEND_ERR("not support sync mode currently");
- return HAL_TDM_ERROR_INVALID_PARAMETER;
- }
-
- pp_data->info = *info;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_pp_attach(hal_tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst)
-{
- tdm_exynos_pp_data *pp_data = pp;
- tdm_exynos_pp_buffer *buffer;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(src, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(dst, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- buffer = calloc(1, sizeof(tdm_exynos_pp_buffer));
- if (!buffer) {
- TDM_BACKEND_ERR("alloc failed");
- return HAL_TDM_ERROR_NONE;
- }
-
- LIST_ADDTAIL(&buffer->link, &pp_data->pending_buffer_list);
- buffer->src = src;
- buffer->dst = dst;
- buffer->pp_data = pp_data;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_pp_commit(hal_tdm_pp *pp)
-{
- tdm_exynos_pp_data *pp_data = pp;
- tdm_exynos_pp_buffer *b = NULL, *bb = NULL;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_pp_set_done_handler(hal_tdm_pp *pp, hal_tdm_pp_done_handler func,
- void *user_data)
-{
- tdm_exynos_pp_data *pp_data = pp;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- pp_data->done_func = func;
- pp_data->done_user_data = user_data;
-
- return HAL_TDM_ERROR_NONE;
-}
+++ /dev/null
-/**************************************************************************
-
-libtdm_exynos
-
-Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tdm_backend_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_display *display_data;
-
- unsigned int prop_id;
-
- hal_tdm_info_pp info;
- int info_changed;
-
- struct list_head pending_buffer_list;
- struct list_head buffer_list;
-
- hal_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 hal_tdm_error
-_tdm_exynos_pp_legacy_set(tdm_exynos_pp_legacy_data *pp_data)
-{
- tdm_exynos_display *display_data = pp_data->display_data;
- hal_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(hal_tdm_size));
- memcpy(&property.config[0].pos, &info->src_config.pos, sizeof(hal_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(hal_tdm_size));
- memcpy(&property.config[1].pos, &info->dst_config.pos, sizeof(hal_tdm_pos));
- property.cmd = IPP_CMD_M2M;
- property.prop_id = pp_data->prop_id;
-
- TDM_BACKEND_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_BACKEND_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(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_SET_PROPERTY, &property);
- if (ret) {
- TDM_BACKEND_ERR("failed: %m");
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- TDM_BACKEND_DBG("success. prop_id(%d) ", property.prop_id);
- pp_data->prop_id = property.prop_id;
- return HAL_TDM_ERROR_NONE;
-}
-
-static hal_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_display *display_data = pp_data->display_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_BACKEND_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(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
- if (ret) {
- TDM_BACKEND_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 HAL_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_BACKEND_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(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
- if (ret) {
- TDM_BACKEND_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 HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- TDM_BACKEND_DBG("success. prop_id(%d)", buf.prop_id);
-
- return HAL_TDM_ERROR_NONE;
-}
-
-static hal_tdm_error
-_tdm_exynos_pp_legacy_cmd(tdm_exynos_pp_legacy_data *pp_data, enum drm_exynos_ipp_ctrl cmd)
-{
- tdm_exynos_display *display_data = pp_data->display_data;
- struct drm_exynos_ipp_cmd_ctrl ctrl;
- int ret = 0;
-
- ctrl.prop_id = pp_data->prop_id;
- ctrl.ctrl = cmd;
-
- TDM_BACKEND_DBG("prop_id(%d) ctrl(%d). ", ctrl.prop_id, ctrl.ctrl);
-
- ret = ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_CMD_CTRL, &ctrl);
- if (ret) {
- TDM_BACKEND_ERR("failed. prop_id(%d) ctrl(%d). %m", ctrl.prop_id, ctrl.ctrl);
- return HAL_TDM_ERROR_OPERATION_FAILED;
- }
-
- TDM_BACKEND_DBG("success. prop_id(%d) ", ctrl.prop_id);
-
- return HAL_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_BACKEND_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_BACKEND_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_BACKEND_DBG("dequeued: %d", dequeued_buffer->index);
- break;
- }
- }
-
- if (!dequeued_buffer) {
- TDM_BACKEND_ERR("not found buffer index: %d", buf_idx[0]);
- return;
- }
-
- if (!pp_data->first_event) {
- TDM_BACKEND_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);
-}
-
-hal_tdm_error
-tdm_exynos_pp_legacy_get_capability(tdm_exynos_display *display_data, hal_tdm_caps_pp *caps)
-{
- int i;
-
- if (!caps) {
- TDM_BACKEND_ERR("invalid params");
- return HAL_TDM_ERROR_INVALID_PARAMETER;
- }
-
- caps->capabilities = HAL_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_BACKEND_ERR("alloc failed");
- return HAL_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_pp *
-tdm_exynos_pp_legacy_create(tdm_exynos_display *display_data, hal_tdm_error *error)
-{
- tdm_exynos_pp_legacy_data *pp_data = calloc(1, sizeof(tdm_exynos_pp_legacy_data));
- if (!pp_data) {
- TDM_BACKEND_ERR("alloc failed");
- if (error)
- *error = HAL_TDM_ERROR_OUT_OF_MEMORY;
- return NULL;
- }
-
- pp_data->display_data = display_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(hal_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);
-}
-
-hal_tdm_error
-exynos_pp_legacy_set_info(hal_tdm_pp *pp, hal_tdm_info_pp *info)
-{
- tdm_exynos_pp_legacy_data *pp_data = pp;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(info, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- if (info->sync) {
- TDM_BACKEND_ERR("not support sync mode currently");
- return HAL_TDM_ERROR_INVALID_PARAMETER;
- }
-
- pp_data->info = *info;
- pp_data->info_changed = 1;
-
- return HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_pp_legacy_attach(hal_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;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(src, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(dst, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- buffer = calloc(1, sizeof(tdm_exynos_pp_legacy_buffer));
- if (!buffer) {
- TDM_BACKEND_ERR("alloc failed");
- return HAL_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_pp_legacy_commit(hal_tdm_pp *pp)
-{
- tdm_exynos_pp_legacy_data *pp_data = pp;
- tdm_exynos_pp_legacy_buffer *b = NULL, *bb = NULL;
- hal_tdm_error ret;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_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 HAL_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_BACKEND_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 HAL_TDM_ERROR_NONE;
-}
-
-hal_tdm_error
-exynos_pp_legacy_set_done_handler(hal_tdm_pp *pp, hal_tdm_pp_done_handler func,
- void *user_data)
-{
- tdm_exynos_pp_legacy_data *pp_data = pp;
-
- TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_TDM_ERROR_INVALID_PARAMETER);
- TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
-
- pp_data->done_func = func;
- pp_data->done_user_data = user_data;
-
- return HAL_TDM_ERROR_NONE;
-}
+++ /dev/null
-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
+++ /dev/null
-#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
-};
-
+++ /dev/null
-#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_ */
+++ /dev/null
-#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, ¢er);
-
- 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;
-}
+++ /dev/null
-#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_ */
+++ /dev/null
-#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, ¢er);
-
- 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;
-}
+++ /dev/null
-#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_ */
+++ /dev/null
-#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);
-}
+++ /dev/null
-#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_ */
+++ /dev/null
-#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;
-}
+++ /dev/null
-#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_ */
+++ /dev/null
-#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
+++ /dev/null
-#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_ */
+++ /dev/null
-#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;
-}
+++ /dev/null
-#ifndef _TDM_EXYNOS_HWC_WINDOW_H_
-#define _TDM_EXYNOS_HWC_WINDOW_H_
-
-#include "tdm_exynos.h"
-
-#endif /* _TDM_EXYNOS_HWC_WINDOW_H_ */
+++ /dev/null
-#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;
-}
+++ /dev/null
-#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_ */
+++ /dev/null
-#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;
-}
+++ /dev/null
-#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_ */
+++ /dev/null
-#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;
-}
+++ /dev/null
-#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_ */
+++ /dev/null
-#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;
-}
+++ /dev/null
-#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_ */
+++ /dev/null
-#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_ */
--- /dev/null
+/**************************************************************************
+
+libtdm_exynos
+
+Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_backend_exynos.h"
+
+#if HAVE_UDEV
+#include <libudev.h>
+#endif
+
+#define EXYNOS_DRM_NAME "exynos"
+
+unsigned int exynos_screen_prerotation_hint;
+
+#ifdef HAVE_UDEV
+static hal_tdm_error
+_tdm_exynos_udev_fd_handler(int fd, hal_tdm_event_loop_mask mask, void *user_data)
+{
+ tdm_exynos_display *display_data = (tdm_exynos_display *)user_data;
+ struct udev_device *dev;
+ const char *hotplug;
+ struct stat s;
+ dev_t udev_devnum;
+ int ret;
+
+ dev = udev_monitor_receive_device(display_data->uevent_monitor);
+ if (!dev) {
+ TDM_BACKEND_ERR("couldn't receive device");
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ udev_devnum = udev_device_get_devnum(dev);
+
+ ret = fstat(display_data->drm_fd, &s);
+ if (ret == -1) {
+ TDM_BACKEND_ERR("fstat failed");
+ udev_device_unref(dev);
+ return HAL_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_BACKEND_INFO("HotPlug");
+ tdm_exynos_display_update_output_status(display_data);
+ }
+
+ udev_device_unref(dev);
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+static struct udev_monitor *
+_tdm_exynos_create_udev_monitor()
+{
+ struct udev *u = NULL;
+ struct udev_monitor *mon = NULL;
+
+ u = udev_new();
+ if (!u) {
+ TDM_BACKEND_ERR("couldn't create udev");
+ goto failed;
+ }
+
+ mon = udev_monitor_new_from_netlink(u, "udev");
+ if (!mon) {
+ TDM_BACKEND_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_BACKEND_ERR("add match subsystem failed");
+ goto failed;
+ }
+
+ TDM_BACKEND_INFO("hotplug monitor created");
+
+ return mon;
+
+failed:
+ if (mon)
+ udev_monitor_unref(mon);
+ if (u)
+ udev_unref(u);
+
+ return NULL;
+}
+
+static void
+_tdm_exynos_destroy_udev_monitor(struct udev_monitor *mon)
+{
+ struct udev *u;
+
+ if (!mon)
+ return;
+
+ u = udev_monitor_get_udev(mon);
+ udev_monitor_unref(mon);
+ udev_unref(u);
+
+ TDM_BACKEND_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_BACKEND_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_BACKEND_WRN("Cannot open drm device.. search by udev");
+ udev = udev_new();
+ if (!udev) {
+ TDM_BACKEND_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_BACKEND_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_BACKEND_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_BACKEND_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_BACKEND_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;
+}
+
+static void
+_tdm_exynos_display_deinitialize(tdm_exynos_display *display_data)
+{
+ if (display_data->use_ippv2)
+ drmRemoveUserHandler(display_data->drm_fd, _tdm_exynos_drm_user_handler);
+ else
+ drmRemoveUserHandler(display_data->drm_fd, _tdm_exynos_drm_user_handler_legacy);
+
+ tdm_exynos_display_destroy_output_list(display_data);
+
+ if (display_data->plane_res)
+ drmModeFreePlaneResources(display_data->plane_res);
+ if (display_data->mode_res)
+ drmModeFreeResources(display_data->mode_res);
+}
+
+static hal_tdm_error
+_tdm_exynos_display_initialize(tdm_exynos_display *display_data)
+{
+ hal_tdm_error ret;
+ drmVersionPtr drm_version;
+
+ drm_version = drmGetVersion(display_data->drm_fd);
+ if (!drm_version) {
+ TDM_BACKEND_ERR("no drm version: %m");
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ goto done;
+ } else {
+ TDM_BACKEND_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))
+ display_data->use_ippv2 = 1;
+ drmFreeVersion(drm_version);
+ }
+
+ if (display_data->use_ippv2)
+ drmAddUserHandler(display_data->drm_fd, _tdm_exynos_drm_user_handler);
+ else
+ drmAddUserHandler(display_data->drm_fd, _tdm_exynos_drm_user_handler_legacy);
+
+ if (drmSetClientCap(display_data->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) < 0)
+ TDM_BACKEND_WRN("Set DRM_CLIENT_CAP_UNIVERSAL_PLANES failed");
+
+ display_data->mode_res = drmModeGetResources(display_data->drm_fd);
+ if (!display_data->mode_res) {
+ TDM_BACKEND_ERR("no drm resource: %m");
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ goto done;
+ }
+
+ display_data->plane_res = drmModeGetPlaneResources(display_data->drm_fd);
+ if (!display_data->plane_res) {
+ TDM_BACKEND_ERR("no drm plane resource: %m");
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ goto done;
+ }
+
+ if (display_data->plane_res->count_planes <= 0) {
+ TDM_BACKEND_ERR("no drm plane resource");
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ goto done;
+ }
+
+ ret = tdm_exynos_display_get_property(display_data,
+ display_data->plane_res->planes[0],
+ DRM_MODE_OBJECT_PLANE, "zpos", NULL,
+ &display_data->is_immutable_zpos);
+ if (ret == HAL_TDM_ERROR_NONE) {
+ display_data->has_zpos_info = 1;
+ if (display_data->is_immutable_zpos)
+ TDM_BACKEND_DBG("plane has immutable zpos info");
+ } else
+ TDM_BACKEND_DBG("plane doesn't have zpos info");
+
+ if (display_data->use_ippv2) {
+ ret = tdm_exynos_pp_init(display_data);
+ if (ret != HAL_TDM_ERROR_NONE)
+ goto done;
+ }
+
+ ret = tdm_exynos_display_create_output_list(display_data);
+ if (ret != HAL_TDM_ERROR_NONE)
+ goto done;
+
+ ret = tdm_exynos_display_create_layer_list(display_data);
+ if (ret != HAL_TDM_ERROR_NONE)
+ goto done;
+
+done:
+ return ret;
+}
+
+static hal_tdm_error
+_tdm_exynos_master_drm_fd_handler(hal_tdm_fd master_drm_fd, void *user_data)
+{
+ tdm_exynos_display *display_data = (tdm_exynos_display *) user_data;
+ hal_tdm_error ret;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ display_data->drm_fd = master_drm_fd;
+ TDM_BACKEND_INFO("Get the master drm_fd(%d)!\n", display_data->drm_fd);
+
+ // initialize display with a master drm_fd
+ ret = _tdm_exynos_display_initialize(display_data);
+ if (ret != HAL_TDM_ERROR_NONE) {
+ TDM_BACKEND_ERR("fail to _tdm_exynos_display_initialize!\n");
+ _tdm_exynos_display_deinitialize(display_data);
+
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+int
+hal_backend_tdm_exynos_exit(void *data)
+{
+ hal_tdm_backend_data *backend_data = (hal_tdm_backend_data *)data;
+ tdm_exynos_display *display_data;
+
+ TDM_BACKEND_INFO("deinit");
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(backend_data != NULL, -1);
+
+ display_data = (tdm_exynos_display *)backend_data->display;
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data != NULL, -1);
+
+ if (backend_data->capture_funcs) {
+ free(backend_data->capture_funcs);
+ backend_data->capture_funcs = NULL;
+ }
+ if (backend_data->pp_funcs) {
+ free(backend_data->pp_funcs);
+ backend_data->pp_funcs = NULL;
+ }
+ if (backend_data->hwc_window_funcs) {
+ free(backend_data->hwc_window_funcs);
+ backend_data->hwc_window_funcs = NULL;
+ }
+ if (backend_data->hwc_funcs) {
+ free(backend_data->hwc_funcs);
+ backend_data->hwc_funcs = NULL;
+ }
+ if (backend_data->output_funcs) {
+ free(backend_data->output_funcs);
+ backend_data->output_funcs = NULL;
+ }
+ if (backend_data->display_funcs) {
+ free(backend_data->display_funcs);
+ backend_data->display_funcs = NULL;
+ }
+
+ _tdm_exynos_display_deinitialize(display_data);
+
+#ifdef HAVE_UDEV
+ if (display_data->uevent_monitor)
+ _tdm_exynos_destroy_udev_monitor(display_data->uevent_monitor);
+#endif
+
+ if (display_data->drm_fd >= 0)
+ close(display_data->drm_fd);
+
+ free(display_data);
+ free(backend_data);
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+static int
+hal_backend_tdm_exynos_init(void **data)
+{
+ hal_tdm_backend_data *backend_data = NULL;
+ hal_tdm_display_funcs *display_funcs = NULL;
+ hal_tdm_output_funcs *output_funcs = NULL;
+ hal_tdm_hwc_funcs *hwc_funcs = NULL;
+ hal_tdm_hwc_window_funcs *hwc_window_funcs = NULL;
+ hal_tdm_pp_funcs *pp_funcs = NULL;
+ hal_tdm_capture_funcs *capture_funcs = NULL;
+ tdm_exynos_display *display_data = NULL;
+ hal_tdm_error ret;
+ int drm_fd;
+ const char *value;
+#ifdef HAVE_UDEV
+ static struct udev_monitor *mon;
+ hal_tdm_event_source *udev_event_source;
+#endif
+
+ /* allocate a hal_tdm_backend_data */
+ backend_data = calloc(1, sizeof(struct _hal_tdm_backend_data));
+ if (!backend_data) {
+ TDM_BACKEND_ERR("fail to alloc backend_data!\n");
+ *data = NULL;
+ return -1;
+ }
+ *data = backend_data;
+
+ /* allocate a hal_tdm_display */
+ display_data = calloc(1, sizeof(struct _tdm_exynos_display));
+ if (!display_data) {
+ TDM_BACKEND_ERR("fail to alloc display_data!\n");
+ goto failed;
+ }
+ backend_data->display = (hal_tdm_display *)display_data;
+
+ LIST_INITHEAD(&display_data->output_list);
+ LIST_INITHEAD(&display_data->buffer_list);
+
+ value = (const char*)getenv("SCREEN_PREROTATION_HINT");
+ if (value) {
+ char *end;
+ exynos_screen_prerotation_hint = strtol(value, &end, 10);
+ TDM_BACKEND_INFO("SCREEN_PREROTATION_HINT = %d", exynos_screen_prerotation_hint);
+ }
+
+ // check if drm_fd is master fd.
+ drm_fd = _tdm_exynos_open_drm();
+ if (drm_fd < 0) {
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ goto failed;
+ }
+
+ // set true when backend has a drm_device.
+ backend_data->has_drm_device = 1;
+
+ if (drmIsMaster(drm_fd)) {
+ // drm_fd is a master drm_fd.
+ backend_data->drm_info.drm_fd = drm_fd;
+ backend_data->drm_info.is_master = 1;
+
+ display_data->drm_fd = drm_fd;
+ TDM_BACKEND_INFO("Get the master drm_fd(%d)!\n", display_data->drm_fd);
+
+ // initialize display with a master drm_fd
+ ret = _tdm_exynos_display_initialize(display_data);
+ if (ret != HAL_TDM_ERROR_NONE) {
+ TDM_BACKEND_ERR("fail to _tdm_exynos_display_initialize!\n");
+ goto failed;
+ }
+ } else {
+ // drm_fd is not a master drm_fd.
+ // request a master drm_fd
+ close(drm_fd);
+ backend_data->drm_info.drm_fd = -1;
+ backend_data->drm_info.is_master = 0;
+ backend_data->drm_info.master_drm_fd_func = _tdm_exynos_master_drm_fd_handler;
+ backend_data->drm_info.user_data = display_data;
+
+ TDM_BACKEND_INFO("A backend requests an master drm_fd.\n");
+ }
+
+#ifdef HAVE_UDEV
+ mon = _tdm_exynos_create_udev_monitor();
+ if (!mon) {
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ goto failed;
+ }
+ display_data->uevent_monitor = mon;
+
+ /* alloc and register udev_event_source */
+ udev_event_source = calloc(1, sizeof(struct _hal_tdm_event_source));
+ if (!udev_event_source) {
+ TDM_BACKEND_ERR("fail to alloc udev_event_source!\n");
+ goto failed;
+ }
+ udev_event_source->event_fd = udev_monitor_get_fd(mon);
+ udev_event_source->func = _tdm_exynos_udev_fd_handler;
+ udev_event_source->user_data = display_data;
+
+ backend_data->event_sources[0] = udev_event_source;
+ backend_data->num_event_sources++;
+#endif
+
+ /* alloc and register display_funcs */
+ display_funcs = calloc(1, sizeof(struct _hal_tdm_display_funcs));
+ if (!display_funcs) {
+ TDM_BACKEND_ERR("fail to alloc display_funcs!\n");
+ goto failed;
+ }
+ backend_data->display_funcs = display_funcs;
+
+ display_funcs->display_get_capability = exynos_display_get_capability;
+ display_funcs->display_get_pp_capability = exynos_display_get_pp_capability;
+ display_funcs->display_get_capture_capability = exynos_display_get_capture_capability;
+ display_funcs->display_get_outputs = exynos_display_get_outputs;
+ display_funcs->display_get_fd = exynos_display_get_fd;
+ display_funcs->display_handle_events = exynos_display_handle_events;
+ display_funcs->display_create_pp = exynos_display_create_pp;
+
+ /* alloc and register output_funcs */
+ output_funcs = calloc(1, sizeof(struct _hal_tdm_output_funcs));
+ if (!output_funcs) {
+ TDM_BACKEND_ERR("fail to alloc output_funcs!\n");
+ goto failed;
+ }
+ backend_data->output_funcs = output_funcs;
+
+ output_funcs->output_get_capability = exynos_output_get_capability;
+ output_funcs->output_set_property = exynos_output_set_property;
+ output_funcs->output_get_property = exynos_output_get_property;
+ output_funcs->output_wait_vblank = exynos_output_wait_vblank;
+ output_funcs->output_set_vblank_handler = exynos_output_set_vblank_handler;
+ output_funcs->output_set_dpms = exynos_output_set_dpms;
+ output_funcs->output_get_dpms = exynos_output_get_dpms;
+ output_funcs->output_set_mode = exynos_output_set_mode;
+ output_funcs->output_get_mode = exynos_output_get_mode;
+ output_funcs->output_create_capture = exynos_output_create_capture;
+#ifdef HAVE_UDEV
+ output_funcs->output_set_status_handler = exynos_output_set_status_handler;
+#endif
+ output_funcs->output_get_hwc = exynos_output_get_hwc;
+
+ /* alloc and register hwc_funcs */
+ hwc_funcs = calloc(1, sizeof(struct _hal_tdm_hwc_funcs));
+ if (!hwc_funcs) {
+ TDM_BACKEND_ERR("fail to alloc hwc_funcs!\n");
+ goto failed;
+ }
+ backend_data->hwc_funcs = hwc_funcs;
+
+ hwc_funcs->hwc_create_window = exynos_hwc_create_window;
+ hwc_funcs->hwc_get_video_supported_formats = exynos_hwc_get_video_supported_formats;
+ hwc_funcs->hwc_get_capabilities = exynos_hwc_get_capabilities;
+ hwc_funcs->hwc_get_available_properties = exynos_hwc_get_available_properties;
+ hwc_funcs->hwc_get_client_target_buffer_queue = exynos_hwc_get_client_target_buffer_queue;
+ hwc_funcs->hwc_set_client_target_buffer = exynos_hwc_set_client_target_buffer;
+ hwc_funcs->hwc_validate = exynos_hwc_validate;
+ hwc_funcs->hwc_get_changed_composition_types = exynos_hwc_get_changed_composition_types;
+ hwc_funcs->hwc_accept_validation = exynos_hwc_accept_validation;
+ hwc_funcs->hwc_commit = exynos_hwc_commit;
+ hwc_funcs->hwc_set_commit_handler = exynos_hwc_set_commit_handler;
+
+ /* alloc and register hwc_window_funcs */
+ hwc_window_funcs = calloc(1, sizeof(struct _hal_tdm_hwc_window_funcs));
+ if (!hwc_window_funcs) {
+ TDM_BACKEND_ERR("fail to alloc hwc_window_funcs!\n");
+ goto failed;
+ }
+ backend_data->hwc_window_funcs = hwc_window_funcs;
+
+ hwc_window_funcs->hwc_window_destroy = exynos_hwc_window_destroy;
+ hwc_window_funcs->hwc_window_acquire_buffer_queue = NULL;
+ hwc_window_funcs->hwc_window_release_buffer_queue = NULL;
+ hwc_window_funcs->hwc_window_set_composition_type = exynos_hwc_window_set_composition_type;
+ hwc_window_funcs->hwc_window_set_buffer_damage = exynos_hwc_window_set_buffer_damage;
+ hwc_window_funcs->hwc_window_set_info = exynos_hwc_window_set_info;
+ hwc_window_funcs->hwc_window_set_buffer = exynos_hwc_window_set_buffer;
+ hwc_window_funcs->hwc_window_set_property = exynos_hwc_window_set_property;
+ hwc_window_funcs->hwc_window_get_property = exynos_hwc_window_get_property;
+ hwc_window_funcs->hwc_window_get_constraints = exynos_hwc_window_get_constraints;
+
+ /* alloc and register pp_funcs */
+ pp_funcs = calloc(1, sizeof(struct _hal_tdm_pp_funcs));
+ if (!pp_funcs) {
+ TDM_BACKEND_ERR("fail to alloc pp_funcs!\n");
+ goto failed;
+ }
+ backend_data->pp_funcs = pp_funcs;
+
+ if (display_data->use_ippv2) {
+ pp_funcs->pp_destroy = exynos_pp_destroy;
+ pp_funcs->pp_set_info = exynos_pp_set_info;
+ pp_funcs->pp_attach = exynos_pp_attach;
+ pp_funcs->pp_commit = exynos_pp_commit;
+ pp_funcs->pp_set_done_handler = exynos_pp_set_done_handler;
+ } else {
+ pp_funcs->pp_destroy = exynos_pp_legacy_destroy;
+ pp_funcs->pp_set_info = exynos_pp_legacy_set_info;
+ pp_funcs->pp_attach = exynos_pp_legacy_attach;
+ pp_funcs->pp_commit = exynos_pp_legacy_commit;
+ pp_funcs->pp_set_done_handler = exynos_pp_legacy_set_done_handler;
+ }
+
+ /* alloc and register capture_funcs */
+ capture_funcs = calloc(1, sizeof(struct _hal_tdm_capture_funcs));
+ if (!capture_funcs) {
+ TDM_BACKEND_ERR("fail to alloc pp_funcs!\n");
+ goto failed;
+ }
+ backend_data->capture_funcs = capture_funcs;
+
+ if (display_data->use_ippv2) {
+ capture_funcs->capture_destroy = exynos_capture_destroy;
+ capture_funcs->capture_set_info = exynos_capture_set_info;
+ capture_funcs->capture_attach = exynos_capture_attach;
+ capture_funcs->capture_commit = exynos_capture_commit;
+ capture_funcs->capture_set_done_handler = exynos_capture_set_done_handler;
+ } else {
+ capture_funcs->capture_destroy = exynos_capture_legacy_destroy;
+ capture_funcs->capture_set_info = exynos_capture_legacy_set_info;
+ capture_funcs->capture_attach = exynos_capture_legacy_attach;
+ capture_funcs->capture_commit = exynos_capture_legacy_commit;
+ capture_funcs->capture_set_done_handler = exynos_capture_legacy_set_done_handler;
+ }
+
+ TDM_BACKEND_INFO("init success!");
+
+ return HAL_TDM_ERROR_NONE;
+
+failed:
+ TDM_BACKEND_ERR("init failed!");
+
+ hal_backend_tdm_exynos_exit((void *)backend_data);
+
+ return -1;
+}
+
+hal_backend hal_backend_tdm_data = {
+ "exynos",
+ "Samsung",
+ HAL_ABI_VERSION_TIZEN_6_5,
+ hal_backend_tdm_exynos_init,
+ hal_backend_tdm_exynos_exit
+};
--- /dev/null
+/**************************************************************************
+
+libtdm_exynos
+
+Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef _TDM_EXYNOS_H_
+#define _TDM_EXYNOS_H_
+
+#include "tdm_backend_exynos_types.h"
+
+extern unsigned int exynos_screen_prerotation_hint;
+
+/* display funcs */
+hal_tdm_error exynos_display_get_capability(hal_tdm_display *display, hal_tdm_caps_display *caps);
+hal_tdm_error exynos_display_get_pp_capability(hal_tdm_display *display, hal_tdm_caps_pp *caps);
+hal_tdm_error exynos_display_get_capture_capability(hal_tdm_display *display, hal_tdm_caps_capture *caps);
+hal_tdm_output **exynos_display_get_outputs(hal_tdm_display *display, int *count, hal_tdm_error *error);
+hal_tdm_error exynos_display_get_fd(hal_tdm_display *display, int *fd);
+hal_tdm_error exynos_display_handle_events(hal_tdm_display *display);
+hal_tdm_pp* exynos_display_create_pp(hal_tdm_display *display, hal_tdm_error *error);
+
+/* output funcs */
+hal_tdm_error exynos_output_get_capability(hal_tdm_output *output, hal_tdm_caps_output *caps);
+hal_tdm_error exynos_output_set_property(hal_tdm_output *output, unsigned int id, hal_tdm_value value);
+hal_tdm_error exynos_output_get_property(hal_tdm_output *output, unsigned int id, hal_tdm_value *value);
+hal_tdm_error exynos_output_wait_vblank(hal_tdm_output *output, int interval, int sync, void *user_data);
+hal_tdm_error exynos_output_set_vblank_handler(hal_tdm_output *output, hal_tdm_output_vblank_handler func);
+hal_tdm_error exynos_output_commit(hal_tdm_output *output, int sync, void *user_data);
+hal_tdm_error exynos_output_set_commit_handler(hal_tdm_output *output, hal_tdm_output_commit_handler func);
+hal_tdm_error exynos_output_set_dpms(hal_tdm_output *output, hal_tdm_output_dpms dpms_value);
+hal_tdm_error exynos_output_get_dpms(hal_tdm_output *output, hal_tdm_output_dpms *dpms_value);
+hal_tdm_error exynos_output_set_mode(hal_tdm_output *output, const hal_tdm_output_mode *mode);
+hal_tdm_error exynos_output_get_mode(hal_tdm_output *output, const hal_tdm_output_mode **mode);
+hal_tdm_capture *exynos_output_create_capture(hal_tdm_output *output, hal_tdm_error *error);
+hal_tdm_error exynos_output_set_status_handler(hal_tdm_output *output, hal_tdm_output_status_handler func, void *user_data);
+hal_tdm_hwc *exynos_output_get_hwc(hal_tdm_output *output, hal_tdm_error *error);
+
+/* hwc funcs */
+hal_tdm_hwc_window *exynos_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_error *error);
+hal_tdm_error exynos_hwc_get_video_supported_formats(hal_tdm_hwc *hwc, const tbm_format **formats, int *count);
+hal_tdm_error exynos_hwc_get_capabilities(hal_tdm_hwc *hwc, hal_tdm_hwc_capability *capabilities);
+hal_tdm_error exynos_hwc_get_available_properties(hal_tdm_hwc *hwc, const hal_tdm_prop **props, int *count);
+tbm_surface_queue_h exynos_hwc_get_client_target_buffer_queue(hal_tdm_hwc *hwc, hal_tdm_error *error);
+hal_tdm_error exynos_hwc_set_client_target_buffer(hal_tdm_hwc *hwc, tbm_surface_h buffer, hal_tdm_region damage);
+hal_tdm_error exynos_hwc_validate(hal_tdm_hwc *hwc, hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types);
+hal_tdm_error exynos_hwc_get_changed_composition_types(hal_tdm_hwc *hwc, uint32_t *num_elements, hal_tdm_hwc_window **hwc_wnds, hal_tdm_hwc_window_composition *composition_types);
+hal_tdm_error exynos_hwc_accept_validation(hal_tdm_hwc *hwc);
+hal_tdm_error exynos_hwc_commit(hal_tdm_hwc *hwc, int sync, void *user_data);
+hal_tdm_error exynos_hwc_set_commit_handler(hal_tdm_hwc *hwc, hal_tdm_hwc_commit_handler func);
+
+/* hwc_window funcs */
+void exynos_hwc_window_destroy(hal_tdm_hwc_window *hwc_window);
+hal_tdm_error exynos_hwc_window_set_composition_type(hal_tdm_hwc_window *hwc_window, hal_tdm_hwc_window_composition composition_type);
+hal_tdm_error exynos_hwc_window_set_buffer_damage(hal_tdm_hwc_window *hwc_window, hal_tdm_region damage);
+hal_tdm_error exynos_hwc_window_set_info(hal_tdm_hwc_window *hwc_window, hal_tdm_hwc_window_info *info);
+hal_tdm_error exynos_hwc_window_set_buffer(hal_tdm_hwc_window *hwc_window, tbm_surface_h surface);
+hal_tdm_error exynos_hwc_window_set_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value value);
+hal_tdm_error exynos_hwc_window_get_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value *value);
+hal_tdm_error exynos_hwc_window_get_constraints(hal_tdm_hwc_window *hwc_window, int *constraints);
+
+/* pp funcs */
+void exynos_pp_legacy_destroy(hal_tdm_pp *pp);
+hal_tdm_error exynos_pp_legacy_set_info(hal_tdm_pp *pp, hal_tdm_info_pp *info);
+hal_tdm_error exynos_pp_legacy_attach(hal_tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst);
+hal_tdm_error exynos_pp_legacy_commit(hal_tdm_pp *pp);
+hal_tdm_error exynos_pp_legacy_set_done_handler(hal_tdm_pp *pp, hal_tdm_pp_done_handler func, void *user_data);
+
+void exynos_pp_destroy(hal_tdm_pp *pp);
+hal_tdm_error exynos_pp_set_info(hal_tdm_pp *pp, hal_tdm_info_pp *info);
+hal_tdm_error exynos_pp_attach(hal_tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst);
+hal_tdm_error exynos_pp_commit(hal_tdm_pp *pp);
+hal_tdm_error exynos_pp_set_done_handler(hal_tdm_pp *pp, hal_tdm_pp_done_handler func, void *user_data);
+
+/* capture funcs */
+void exynos_capture_legacy_destroy(hal_tdm_capture *capture);
+hal_tdm_error exynos_capture_legacy_set_info(hal_tdm_capture *capture, hal_tdm_info_capture *info);
+hal_tdm_error exynos_capture_legacy_attach(hal_tdm_capture *capture, tbm_surface_h buffer);
+hal_tdm_error exynos_capture_legacy_commit(hal_tdm_capture *capture);
+hal_tdm_error exynos_capture_legacy_set_done_handler(hal_tdm_pp *pp, hal_tdm_capture_done_handler func, void *user_data);
+
+void exynos_capture_destroy(hal_tdm_capture *capture);
+hal_tdm_error exynos_capture_set_info(hal_tdm_capture *capture, hal_tdm_info_capture *info);
+hal_tdm_error exynos_capture_attach(hal_tdm_capture *capture, tbm_surface_h buffer);
+hal_tdm_error exynos_capture_commit(hal_tdm_capture *capture);
+hal_tdm_error exynos_capture_set_done_handler(hal_tdm_pp *pp, hal_tdm_capture_done_handler func, void *user_data);
+
+/* exynos display */
+void tdm_exynos_display_update_output_status(tdm_exynos_display *display_data);
+hal_tdm_error tdm_exynos_display_create_output_list(tdm_exynos_display *display_data);
+void tdm_exynos_display_destroy_output_list(tdm_exynos_display *display_data);
+hal_tdm_error tdm_exynos_display_create_layer_list(tdm_exynos_display *display_data);
+hal_tdm_error tdm_exynos_display_set_property(tdm_exynos_display *display_data, unsigned int obj_id, unsigned int obj_type, const char *name, unsigned int value);
+hal_tdm_error tdm_exynos_display_get_property(tdm_exynos_display *display_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, hal_tdm_output_mode *tdm_mode);
+
+/* exynos output */
+void tdm_exynos_output_cb_event(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data);
+hal_tdm_error tdm_exynos_output_update_status(tdm_exynos_output *output_data, hal_tdm_output_conn_status status);
+
+/* exynos hwc */
+hal_tdm_error exynos_hwc_initailize_target_window(tdm_exynos_hwc *hwc_data, int width, int height);
+
+/* exynos layer */
+hal_tdm_error tdm_exynos_layer_get_capability(tdm_exynos_layer *layer_data, tdm_exynos_caps_layer *caps);
+hal_tdm_error tdm_exynos_layer_set_property(tdm_exynos_layer *layer_data, unsigned int id, hal_tdm_value value);
+hal_tdm_error tdm_exynos_layer_get_property(tdm_exynos_layer *layer_data, unsigned int id, hal_tdm_value *value);
+hal_tdm_error tdm_exynos_layer_set_info(tdm_exynos_layer *layer_data, tdm_exynos_layer_info *info);
+hal_tdm_error tdm_exynos_layer_get_info(tdm_exynos_layer *layer_data, tdm_exynos_layer_info *info);
+hal_tdm_error tdm_exynos_layer_set_buffer(tdm_exynos_layer *layer_data, tbm_surface_h buffer);
+hal_tdm_error tdm_exynos_layer_unset_buffer(tdm_exynos_layer *layer_data);
+hal_tdm_error tdm_exynos_layer_get_supported_format(tdm_exynos_layer *layer_data, const tbm_format **out_formats, int *out_format_count);
+hal_tdm_error tdm_exynos_layer_get_available_properties(tdm_exynos_layer *layer_data, const hal_tdm_prop **out_props, int *out_prop_count);
+
+/* exynos pp */
+hal_tdm_error tdm_exynos_pp_legacy_get_capability(tdm_exynos_display *display_data, hal_tdm_caps_pp *caps);
+hal_tdm_pp *tdm_exynos_pp_legacy_create(tdm_exynos_display *display_data, hal_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);
+
+hal_tdm_error tdm_exynos_pp_init(tdm_exynos_display *display_data);
+hal_tdm_error tdm_exynos_pp_get_capability(tdm_exynos_display *display_data, hal_tdm_caps_pp *caps);
+hal_tdm_pp *tdm_exynos_pp_create(tdm_exynos_display *display_data, hal_tdm_error *error);
+void tdm_exynos_pp_handler(unsigned int tv_sec, unsigned int tv_usec, void *data);
+
+/* exynos capture */
+hal_tdm_error tdm_exynos_capture_legacy_get_capability(tdm_exynos_display *display_data, hal_tdm_caps_capture *caps);
+hal_tdm_pp *tdm_exynos_capture_legacy_create_output(tdm_exynos_display *display_data, hal_tdm_output *output, hal_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);
+
+hal_tdm_error tdm_exynos_capture_get_capability(tdm_exynos_display *display_data, hal_tdm_caps_capture *caps);
+hal_tdm_pp *tdm_exynos_capture_create_output(tdm_exynos_display *display_data, hal_tdm_output *output, hal_tdm_error *error);
+
+/* exynos format */
+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_H_ */
--- /dev/null
+/**************************************************************************
+
+libtdm_exynos
+
+Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#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 <linux/fb.h>
+#include <drm.h>
+#include <drm_fourcc.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 <hal-common.h>
+#include <hal-tdm-types.h>
+#include <hal-tdm-interface.h>
+#include <pixman.h>
+
+#include "tdm_backend_log.h"
+#include "tdm_backend_list.h"
+
+/* exynos module internal macros, structures */
+#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)
+
+typedef struct _tdm_exynos_display tdm_exynos_display;
+typedef struct _tdm_exynos_output tdm_exynos_output;
+typedef struct _tdm_exynos_layer tdm_exynos_layer;
+typedef struct _tdm_exynos_hwc tdm_exynos_hwc;
+typedef struct _tdm_exynos_hwc_window tdm_exynos_hwc_window;
+typedef struct _tdm_exynos_event tdm_exynos_event;
+typedef struct _tdm_exynos_display_buffer tdm_exynos_display_buffer;
+
+typedef enum {
+ TDM_EXYNOS_EVENT_TYPE_WAIT,
+ TDM_EXYNOS_EVENT_TYPE_COMMIT,
+ TDM_EXYNOS_EVENT_TYPE_PAGEFLIP,
+} tdm_exynos_event_type;
+
+typedef enum {
+ TDM_EXYNOS_LAYER_CAPABILITY_CURSOR = (1 << 0), /**< cursor */
+ TDM_EXYNOS_LAYER_CAPABILITY_PRIMARY = (1 << 1), /**< primary */
+ TDM_EXYNOS_LAYER_CAPABILITY_OVERLAY = (1 << 2), /**< overlay */
+ TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC = (1 << 4), /**< graphic */
+ TDM_EXYNOS_LAYER_CAPABILITY_VIDEO = (1 << 5), /**< video */
+ TDM_EXYNOS_LAYER_CAPABILITY_SCALE = (1 << 8), /**< if a layer_data has scale capability */
+ TDM_EXYNOS_LAYER_CAPABILITY_TRANSFORM = (1 << 9), /**< if a layer_data has transform capability */
+ TDM_EXYNOS_LAYER_CAPABILITY_SCANOUT = (1 << 10), /**< if a layer_data allows a scanout buffer only */
+ TDM_EXYNOS_LAYER_CAPABILITY_RESEVED_MEMORY = (1 << 11), /**< if a layer_data allows a reserved buffer only */
+ TDM_EXYNOS_LAYER_CAPABILITY_NO_CROP = (1 << 12), /**< if a layer_data has no cropping capability */
+} tdm_exynos_layer_capability;
+
+struct _tdm_exynos_display {
+ int drm_fd;
+
+#if HAVE_UDEV
+ struct udev_monitor *uevent_monitor;
+#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;
+
+ struct list_head output_list;
+ struct list_head buffer_list;
+
+ int use_ippv2;
+ int ipp_module_id;
+};
+
+struct _tdm_exynos_output {
+ struct list_head link;
+
+ /* data which are fixed at initializing */
+ tdm_exynos_display *display_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;
+ hal_tdm_output_mode *output_modes;
+ hal_tdm_output_type connector_type;
+ unsigned int connector_type_id;
+ struct list_head layer_list;
+ tdm_exynos_layer *primary_layer;
+
+ /* not fixed data below */
+ hal_tdm_output_vblank_handler vblank_func;
+ hal_tdm_output_commit_handler commit_func;
+
+ hal_tdm_output_conn_status status;
+ hal_tdm_output_status_handler status_func;
+ void *status_user_data;
+
+ int mode_changed;
+ const hal_tdm_output_mode *current_mode;
+
+ int crtc_set;
+
+ /* hwc data */
+ tdm_exynos_hwc *hwc_data;
+};
+
+typedef struct _tdm_exynos_layer_info {
+ hal_tdm_info_config src_config;
+ hal_tdm_pos dst_pos;
+ hal_tdm_transform transform;
+} tdm_exynos_layer_info;
+
+typedef struct _tdm_exynos_caps_layer {
+ tdm_exynos_layer_capability capabilities; /**< The capabilities of layer_data */
+
+ /**
+ * The z-order
+ * GRAPHIC layers are non-changeable. The zpos of GRAPHIC layers starts
+ * from 0. If there are 4 GRAPHIC layers, The zpos SHOULD be 0, 1, 2, 3.\n
+ * But the zpos of VIDEO layer_data is changeable by layer_set_video_pos() function
+ * of #tdm_func_layer. And The zpos of VIDEO layers is less than GRAPHIC
+ * layers or more than GRAPHIC layers.
+ * ie, ..., -2, -1, 4, 5, ... (if 0 <= GRAPHIC layer_data's zpos < 4).
+ * The zpos of VIDEO layers is @b relative. It doesn't need to start
+ * from -1 or 4. Let's suppose that there are two VIDEO layers.
+ * One has -2 zpos. Another has -4 zpos. Then -2 Video layer_data is higher
+ * than -4 VIDEO layer_data.
+ */
+ int zpos;
+
+ unsigned int format_count; /**< The count of available formats */
+ tbm_format *formats; /**< The @b newly-allocated array of formats. will be freed in frontend. */
+
+ unsigned int prop_count; /**< The count of available properties */
+ hal_tdm_prop *props; /**< The @b newly-allocated array of properties. will be freed in frontend. */
+} tdm_exynos_caps_layer;
+
+struct _tdm_exynos_layer {
+ struct list_head link;
+
+ /* data which are fixed at initializing */
+ tdm_exynos_display *display_data;
+ tdm_exynos_output *output_data;
+ uint32_t plane_id;
+ tdm_exynos_layer_capability capabilities;
+ int zpos;
+
+ /* not fixed data below */
+ tdm_exynos_layer_info 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;
+
+ hal_tdm_prop *props;
+ int prop_count;
+};
+
+struct _tdm_exynos_hwc {
+ tdm_exynos_hwc_window *target_hwc_window;
+
+ int need_validate;
+ int need_target_window;
+
+ int target_window_zpos;
+
+ tdm_exynos_output *output_data;
+ struct list_head hwc_window_list;
+
+ hal_tdm_hwc_commit_handler commit_func;
+};
+
+struct _tdm_exynos_hwc_window {
+ struct list_head link;
+
+ /* data which are fixed at initializing */
+ tdm_exynos_hwc *hwc_data;
+
+ /* not fixed data below */
+ hal_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
+ */
+ hal_tdm_hwc_window_composition client_type;
+ hal_tdm_hwc_window_composition validated_type;
+
+ int candidate_layer_zpos;
+ int assigned_layer_zpos;
+};
+
+struct _tdm_exynos_display_buffer {
+ tdm_exynos_display *display_data;
+ unsigned int fb_id;
+ tbm_surface_h buffer;
+ int width;
+};
+
+struct _tdm_exynos_event {
+ tdm_exynos_event_type type;
+ tdm_exynos_output *output_data;
+ void *user_data;
+};
+
+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_ */
--- /dev/null
+/*
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ */
+
+/**
+ * \file
+ * List macros heavily inspired by the Linux kernel
+ * list handling. No list looping yet.
+ *
+ * Is not threadsafe, so common operations need to
+ * be protected using an external mutex.
+ */
+#ifndef _U_DOUBLE_LIST_H_
+#define _U_DOUBLE_LIST_H_
+
+#include <stddef.h>
+
+struct list_head {
+ struct list_head *prev;
+ struct list_head *next;
+};
+
+static inline void list_inithead(struct list_head *item)
+{
+ item->prev = item;
+ item->next = item;
+}
+
+static inline void list_add(struct list_head *item, struct list_head *list)
+{
+ item->prev = list;
+ item->next = list->next;
+ list->next->prev = item;
+ list->next = item;
+}
+
+static inline void list_addtail(struct list_head *item, struct list_head *list)
+{
+ item->next = list;
+ item->prev = list->prev;
+ list->prev->next = item;
+ list->prev = item;
+}
+
+static inline void list_replace(struct list_head *from, struct list_head *to)
+{
+ to->prev = from->prev;
+ to->next = from->next;
+ from->next->prev = to;
+ from->prev->next = to;
+}
+
+static inline void list_del(struct list_head *item)
+{
+ item->prev->next = item->next;
+ item->next->prev = item->prev;
+}
+
+static inline void list_delinit(struct list_head *item)
+{
+ item->prev->next = item->next;
+ item->next->prev = item->prev;
+ item->next = item;
+ item->prev = item;
+}
+
+static inline int list_length(struct list_head *item)
+{
+ struct list_head *next;
+ int length = 0;
+
+ next = item->next;
+ while (next != item) {
+ length++;
+ next = next->next;
+ }
+
+ return length;
+}
+
+#define LIST_INITHEAD(__item) list_inithead(__item)
+#define LIST_ADD(__item, __list) list_add(__item, __list)
+#define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list)
+#define LIST_REPLACE(__from, __to) list_replace(__from, __to)
+#define LIST_DEL(__item) list_del(__item)
+#define LIST_DELINIT(__item) list_delinit(__item)
+#define LIST_LENGTH(__item) list_length(__item)
+
+#define LIST_ENTRY(__type, __item, __field) \
+ ((__type *)(((char *)(__item)) - offsetof(__type, __field)))
+
+#define LIST_FIRST_ENTRY(__ptr, __type, __field) \
+ LIST_ENTRY(__type, (__ptr)->next, __field)
+
+#define LIST_LAST_ENTRY(__ptr, __type, __field) \
+ LIST_ENTRY(__type, (__ptr)->prev, __field)
+
+#define LIST_IS_EMPTY(__list) \
+ ((__list)->next == (__list))
+
+#ifndef container_of
+#define container_of(ptr, sample, member) \
+ (void *)((char *)(ptr) \
+ - ((char *)&(sample)->member - (char *)(sample)))
+#endif
+
+#define LIST_FOR_EACH_ENTRY(pos, head, member) \
+ for (pos = container_of((head)->next, pos, member); \
+ &pos->member != (head); \
+ pos = container_of(pos->member.next, pos, member))
+
+#define LIST_FOR_EACH_ENTRY_REV(pos, head, member) \
+ for (pos = container_of((head)->prev, pos, member); \
+ &pos->member != (head); \
+ pos = container_of(pos->member.prev, pos, member))
+
+#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \
+ for (pos = container_of((head)->next, pos, member), \
+ storage = container_of(pos->member.next, pos, member); \
+ &pos->member != (head); \
+ pos = storage, storage = container_of(storage->member.next, storage, member))
+
+#define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \
+ for (pos = container_of((head)->prev, pos, member), \
+ storage = container_of(pos->member.prev, pos, member); \
+ &pos->member != (head); \
+ pos = storage, storage = container_of(storage->member.prev, storage, member))
+
+#define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \
+ for (pos = container_of((start), pos, member); \
+ &pos->member != (head); \
+ pos = container_of(pos->member.next, pos, member))
+
+#define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \
+ for (pos = container_of((start), pos, member); \
+ &pos->member != (head); \
+ pos = container_of(pos->member.prev, pos, member))
+
+#define LIST_FIND_ITEM(item, head, type, member, found) \
+ do { \
+ type *pos = NULL; \
+ found = NULL; \
+ LIST_FOR_EACH_ENTRY(pos, head, member) \
+ if (pos == item) { found = item; break; } \
+ } while (0)
+
+#endif /*_U_DOUBLE_LIST_H_*/
--- /dev/null
+/**************************************************************************
+
+libtdm_vc4
+
+Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "tdm_backend_log.h"
+
+#undef LOG_TAG
+#define LOG_TAG "TDM_BACKEND"
+
+unsigned int tbm_log_debug_level = TDM_BACKEND_LOG_LEVEL_INFO;
+
+static void
+_tdm_backend_log_dlog_print(int level, const char *fmt, va_list arg)
+{
+ log_priority dlog_prio;
+
+ switch (level) {
+ case TDM_BACKEND_LOG_LEVEL_ERR:
+ dlog_prio = DLOG_ERROR;
+ break;
+ case TDM_BACKEND_LOG_LEVEL_WRN:
+ dlog_prio = DLOG_WARN;
+ break;
+ case TDM_BACKEND_LOG_LEVEL_INFO:
+ dlog_prio = DLOG_INFO;
+ break;
+ case TDM_BACKEND_LOG_LEVEL_DBG:
+ dlog_prio = DLOG_DEBUG;
+ break;
+ default:
+ return;
+ }
+ __dlog_vprint(LOG_ID_SYSTEM, dlog_prio, LOG_TAG, fmt, arg);
+}
+
+void
+tdm_backend_log_print(int level, const char *fmt, ...)
+{
+ va_list arg;
+
+ if (level > tbm_log_debug_level)
+ return;
+
+ va_start(arg, fmt);
+ _tdm_backend_log_dlog_print(level, fmt, arg);
+ va_end(arg);
+}
\ No newline at end of file
--- /dev/null
+/**************************************************************************
+
+libtbm_exynos
+
+Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef __TDM_BACKEND_LOG_H__
+#define __TDM_BACKEND_LOG_H__
+
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <time.h>
+#include <dlog.h>
+
+enum {
+ TDM_BACKEND_LOG_LEVEL_NONE,
+ TDM_BACKEND_LOG_LEVEL_ERR,
+ TDM_BACKEND_LOG_LEVEL_WRN,
+ TDM_BACKEND_LOG_LEVEL_INFO,
+ TDM_BACKEND_LOG_LEVEL_DBG,
+};
+
+
+/* log level */
+void tdm_backend_log_print(int level, const char *fmt, ...);
+
+#define TDM_BACKEND_DBG(fmt, args...) \
+ do { \
+ struct timespec ts; \
+ clock_gettime(CLOCK_MONOTONIC, &ts); \
+ tdm_backend_log_print(TDM_BACKEND_LOG_LEVEL_DBG, "[%5d.%06d][%d][%s %d]"fmt, \
+ (int)ts.tv_sec, (int)ts.tv_nsec / 1000, \
+ (int)syscall(SYS_gettid), __FUNCTION__, __LINE__, ##args); \
+ } while (0)
+
+#define TDM_BACKEND_INFO(fmt, args...) \
+ do { \
+ struct timespec ts; \
+ clock_gettime(CLOCK_MONOTONIC, &ts); \
+ tdm_backend_log_print(TDM_BACKEND_LOG_LEVEL_INFO, "[%5d.%06d][%d][%s %d]"fmt, \
+ (int)ts.tv_sec, (int)ts.tv_nsec / 1000, \
+ (int)syscall(SYS_gettid), __FUNCTION__, __LINE__, ##args); \
+ } while (0)
+
+#define TDM_BACKEND_WRN(fmt, args...) \
+ do { \
+ struct timespec ts; \
+ clock_gettime(CLOCK_MONOTONIC, &ts); \
+ tdm_backend_log_print(TDM_BACKEND_LOG_LEVEL_WRN, "[%5d.%06d][%d][%s %d]"fmt, \
+ (int)ts.tv_sec, (int)ts.tv_nsec / 1000, \
+ (int)syscall(SYS_gettid), __FUNCTION__, __LINE__, ##args); \
+ } while (0)
+
+#define TDM_BACKEND_ERR(fmt, args...) \
+ do { \
+ struct timespec ts; \
+ clock_gettime(CLOCK_MONOTONIC, &ts); \
+ tdm_backend_log_print(TDM_BACKEND_LOG_LEVEL_ERR, "[%5d.%06d][%d][%s %d]"fmt, \
+ (int)ts.tv_sec, (int)ts.tv_nsec / 1000, \
+ (int)syscall(SYS_gettid), __FUNCTION__, __LINE__, ##args); \
+ } while (0)
+
+#define TDM_BACKEND_RETURN_IF_FAIL(cond) {\
+ if (!(cond)) {\
+ TDM_BACKEND_ERR("'%s' failed.\n", #cond);\
+ return;\
+ } \
+}
+#define TDM_BACKEND_RETURN_VAL_IF_FAIL(cond, val) {\
+ if (!(cond)) {\
+ TDM_BACKEND_ERR("'%s' failed.\n", #cond);\
+ return val;\
+ } \
+}
+#define TDM_BACKEND_GOTO_VAL_IF_FAIL(cond, val) {\
+ if (!(cond)) {\
+ TDM_BACKEND_ERR("'%s' failed.\n", #cond);\
+ goto val;\
+ } \
+}
+
+#endif /* __TDM_BACKEND_LOG_H__ */
\ No newline at end of file
--- /dev/null
+/**************************************************************************
+
+libtdm_exynos
+
+Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_backend_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_display *display_data;
+
+ tdm_exynos_output *output_data;
+
+ hal_tdm_info_capture info;
+ int info_changed;
+
+ struct list_head pending_buffer_list;
+ struct list_head buffer_list;
+
+ struct {
+#if 0 // DO NOT SUPPORT
+ hal_tdm_event_loop_source *timer_source;
+#endif
+ int startd;
+ int first_event;
+ } stream;
+
+ hal_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, hal_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, hal_tdm_pos *scale)
+{
+ float ratio;
+ hal_tdm_pos center = {0,};
+
+ _tdm_exynos_capture_oneshot_center_rect(src_w, src_h, dst_w, dst_h, ¢er);
+
+ 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(hal_tdm_pos *out_rect, hal_tdm_pos *dst_rect, hal_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 *layer_data, hal_tdm_pos *src_crop, hal_tdm_pos *showing_rect)
+{
+ tdm_exynos_output *output_data = capture_data->output_data;
+ float ratio_x, ratio_y;
+ hal_tdm_pos out_rect;
+ hal_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 *layer_data,
+ hal_tdm_pos *dst_pos, hal_tdm_pos *showing_pos, hal_tdm_pos *dst_crop,
+ hal_tdm_transform transform)
+{
+ tdm_exynos_output *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 == HAL_TDM_TRANSFORM_NORMAL || transform == HAL_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 == HAL_TDM_TRANSFORM_90 || transform == HAL_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 == HAL_TDM_TRANSFORM_180 || transform == HAL_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 == HAL_TDM_TRANSFORM_270 || transform == HAL_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_BACKEND_ERR("oneshot: get_crop unknown case error");
+ }
+}
+
+static pixman_format_code_t
+_tdm_exynos_pixman_format_get(tbm_format format)
+{
+ switch (format) {
+ case TBM_FORMAT_ARGB8888:
+ return PIXMAN_a8r8g8b8;
+ case TBM_FORMAT_XRGB8888:
+ return PIXMAN_x8r8g8b8;
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static hal_tdm_error
+_tdm_exynos_capture_convert_buffer(tbm_surface_h srcbuf, tbm_surface_h dstbuf,
+ hal_tdm_pos *srcpos, hal_tdm_pos *dstpos,
+ hal_tdm_transform transform, int over)
+{
+ tbm_surface_info_s src_info, dst_info;
+ pixman_image_t *src_img = NULL, *dst_img = NULL;
+ pixman_format_code_t src_format, dst_format;
+ double scale_x, scale_y;
+ int rotate_step, bos;
+ pixman_transform_t t;
+ struct pixman_f_transform ft;
+ pixman_op_t op;
+ int src_stride, dst_stride;
+ int buf_width, err;
+ hal_tdm_error ret = HAL_TDM_ERROR_OPERATION_FAILED;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(srcbuf != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(dstbuf != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ bos = tbm_surface_internal_get_num_bos(srcbuf);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(bos == 1, HAL_TDM_ERROR_OPERATION_FAILED);
+
+ bos = tbm_surface_internal_get_num_bos(dstbuf);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(bos == 1, HAL_TDM_ERROR_OPERATION_FAILED);
+
+ err = tbm_surface_map(srcbuf, TBM_OPTION_READ, &src_info);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(err == TBM_SURFACE_ERROR_NONE, HAL_TDM_ERROR_OPERATION_FAILED);
+
+ err = tbm_surface_map(dstbuf, TBM_OPTION_WRITE, &dst_info);
+ TDM_BACKEND_GOTO_VAL_IF_FAIL(err == TBM_SURFACE_ERROR_NONE, unmap_srcbuf);
+
+ /* not handle buffers which have 2 more gem handles */
+ TDM_BACKEND_GOTO_VAL_IF_FAIL(src_info.planes[0].ptr != NULL, unmap_dstbuf);
+ TDM_BACKEND_GOTO_VAL_IF_FAIL(dst_info.planes[0].ptr != NULL, unmap_dstbuf);
+
+ src_format = _tdm_exynos_pixman_format_get(src_info.format);
+ TDM_BACKEND_GOTO_VAL_IF_FAIL(src_format > 0, unmap_dstbuf);
+ dst_format = _tdm_exynos_pixman_format_get(dst_info.format);
+ TDM_BACKEND_GOTO_VAL_IF_FAIL(dst_format > 0, unmap_dstbuf);
+
+ buf_width = src_info.planes[0].stride >> 2;
+ src_stride = src_info.planes[0].stride;
+ src_img = pixman_image_create_bits(src_format, buf_width, src_info.height,
+ (uint32_t*)src_info.planes[0].ptr, src_stride);
+ TDM_BACKEND_GOTO_VAL_IF_FAIL(src_img, unref_img);
+
+ buf_width = dst_info.planes[0].stride >> 2;
+ dst_stride = dst_info.planes[0].stride;
+ dst_img = pixman_image_create_bits(dst_format, buf_width, dst_info.height,
+ (uint32_t*)dst_info.planes[0].ptr, dst_stride);
+ TDM_BACKEND_GOTO_VAL_IF_FAIL(dst_img, unref_img);
+
+ pixman_f_transform_init_identity(&ft);
+
+ if (transform & HAL_TDM_TRANSFORM_FLIPPED) {
+ pixman_f_transform_scale(&ft, NULL, -1, 1);
+ pixman_f_transform_translate(&ft, NULL, dstpos->w, 0);
+ }
+
+ rotate_step = transform & 0x3;
+ if (rotate_step > 0) {
+ int c, s, tx = 0, ty = 0;
+ switch (rotate_step) {
+ case 1:
+ c = 0, s = -1, tx = -dstpos->w;
+ break;
+ case 2:
+ c = -1, s = 0, tx = -dstpos->w, ty = -dstpos->h;
+ break;
+ case 3:
+ c = 0, s = 1, ty = -dstpos->h;
+ break;
+ }
+ pixman_f_transform_translate(&ft, NULL, tx, ty);
+ pixman_f_transform_rotate(&ft, NULL, c, s);
+ }
+
+ if (rotate_step % 2 == 0) {
+ scale_x = (double)srcpos->w / dstpos->w;
+ scale_y = (double)srcpos->h / dstpos->h;
+ } else {
+ scale_x = (double)srcpos->w / dstpos->h;
+ scale_y = (double)srcpos->h / dstpos->w;
+ }
+
+ pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
+ pixman_f_transform_translate(&ft, NULL, srcpos->x, srcpos->y);
+ pixman_transform_from_pixman_f_transform(&t, &ft);
+ pixman_image_set_transform(src_img, &t);
+
+ op = (!over) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER;
+
+ pixman_image_composite(op, src_img, NULL, dst_img, 0, 0, 0, 0,
+ dstpos->x, dstpos->y, dstpos->w, dstpos->h);
+
+ ret = HAL_TDM_ERROR_NONE;
+
+unref_img:
+ if (src_img)
+ pixman_image_unref(src_img);
+ if (dst_img)
+ pixman_image_unref(dst_img);
+unmap_dstbuf:
+ tbm_surface_unmap(dstbuf);
+unmap_srcbuf:
+ tbm_surface_unmap(srcbuf);
+
+ return ret;
+}
+
+static void
+_tdm_exynos_capture_oneshot_composite_layers_sw(tdm_exynos_capture_data *capture_data, tbm_surface_h buffer)
+{
+ tdm_exynos_output *output_data = capture_data->output_data;
+ tdm_exynos_layer *layer_data = NULL;
+ tbm_surface_info_s buf_info;
+ int err;
+
+ err = tbm_surface_get_info(buffer, &buf_info);
+ TDM_BACKEND_RETURN_IF_FAIL(err == TBM_SURFACE_ERROR_NONE);
+
+ LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+ tbm_surface_h buf;
+ hal_tdm_pos dst_pos;
+ hal_tdm_pos showing_pos;
+ hal_tdm_pos src_crop;
+ hal_tdm_pos dst_crop;
+ hal_tdm_transform transform = HAL_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_BACKEND_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_exynos_capture_convert_buffer(buf, buffer, &src_crop, &dst_crop, transform, 1);
+ }
+}
+
+static hal_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+tdm_exynos_capture_get_capability(tdm_exynos_display *display_data, hal_tdm_caps_capture *caps)
+{
+ int i;
+
+ if (!caps) {
+ TDM_BACKEND_ERR("invalid params");
+ return HAL_TDM_ERROR_INVALID_PARAMETER;
+ }
+
+ caps->capabilities = HAL_TDM_CAPTURE_CAPABILITY_OUTPUT|
+ HAL_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_BACKEND_ERR("alloc failed");
+ return HAL_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_capture *
+tdm_exynos_capture_create_output(tdm_exynos_display *display_data, hal_tdm_output *output, hal_tdm_error *error)
+{
+ tdm_exynos_capture_data *capture_data = calloc(1, sizeof(tdm_exynos_capture_data));
+ if (!capture_data) {
+ TDM_BACKEND_ERR("alloc failed");
+ if (error)
+ *error = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ capture_data->display_data = display_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_BACKEND_DBG("capture(%p) create", capture_data);
+
+ return capture_data;
+}
+
+void
+exynos_capture_destroy(hal_tdm_capture *capture)
+{
+ tdm_exynos_capture_data *capture_data = capture;
+ tdm_exynos_capture_buffer *b = NULL, *bb = NULL;
+
+ if (!capture_data)
+ return;
+
+ TDM_BACKEND_DBG("capture(%p) destroy", capture_data);
+
+#if 0 // DO NOT SUPPORT
+ if (capture_data->stream.timer_source)
+ hal_tdm_event_loop_source_remove(capture_data->stream.timer_source);
+#endif
+
+ 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);
+ tbm_surface_internal_unref(b->ui_buffer);
+ free(b);
+ }
+
+ LIST_DEL(&capture_data->link);
+
+ free(capture_data);
+}
+
+hal_tdm_error
+exynos_capture_set_info(hal_tdm_capture *capture, hal_tdm_info_capture *info)
+{
+ tdm_exynos_capture_data *capture_data = capture;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(info, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ capture_data->info = *info;
+ capture_data->info_changed = 1;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_capture_attach(hal_tdm_capture *capture, tbm_surface_h buffer)
+{
+ tdm_exynos_capture_data *capture_data = capture;
+ tdm_exynos_capture_buffer *b;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(buffer, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ b = calloc(1, sizeof(tdm_exynos_capture_buffer));
+ if (!b) {
+ TDM_BACKEND_ERR("alloc failed");
+ return HAL_TDM_ERROR_NONE;
+ }
+
+ LIST_ADDTAIL(&b->link, &capture_data->pending_buffer_list);
+
+ b->index = _get_index(capture_data);
+ b->buffer = buffer;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_capture_commit(hal_tdm_capture *capture)
+{
+ tdm_exynos_capture_data *capture_data = capture;
+ hal_tdm_error ret = HAL_TDM_ERROR_INVALID_PARAMETER;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ if (capture_data->info.type == HAL_TDM_CAPTURE_TYPE_ONESHOT)
+ ret = _tdm_exynos_capture_commit_oneshot(capture_data);
+
+ return ret;
+}
+
+hal_tdm_error
+exynos_capture_set_done_handler(hal_tdm_capture *capture, hal_tdm_capture_done_handler func, void *user_data)
+{
+ tdm_exynos_capture_data *capture_data = capture;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ capture_data->done_func = func;
+ capture_data->done_user_data = user_data;
+
+ return HAL_TDM_ERROR_NONE;
+}
--- /dev/null
+/**************************************************************************
+
+libtdm_exynos
+
+Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_backend_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_display *display_data;
+
+ tdm_exynos_output *output_data;
+
+ hal_tdm_info_capture info;
+ int info_changed;
+
+ struct list_head pending_buffer_list;
+ struct list_head buffer_list;
+
+ struct {
+#if 0 // DO NOT SUPPORT
+ hal_tdm_event_loop_source *timer_source;
+#endif
+ unsigned int prop_id;
+
+ int startd;
+ int first_event;
+ } stream;
+
+ hal_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;
+}
+
+#if 0 // DO NOT SUPPORT
+static hal_tdm_error
+_tdm_exynos_capture_legacy_stream_pp_set(tdm_exynos_capture_legacy_data *capture_data, tbm_surface_h ui_buffer)
+{
+ tdm_exynos_display *display_data = capture_data->display_data;
+ hal_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(hal_tdm_size));
+ memcpy(&property.config[1].pos, &info->dst_config.pos, sizeof(hal_tdm_pos));
+ property.cmd = IPP_CMD_M2M;
+ property.prop_id = capture_data->stream.prop_id;
+
+ TDM_BACKEND_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_BACKEND_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(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_SET_PROPERTY, &property);
+ if (ret) {
+ TDM_BACKEND_ERR("failed: %m");
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ TDM_BACKEND_DBG("success. prop_id(%d) ", property.prop_id);
+ capture_data->stream.prop_id = property.prop_id;
+ return HAL_TDM_ERROR_NONE;
+}
+#endif
+
+static hal_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_display *display_data = capture_data->display_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_BACKEND_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(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
+ if (ret) {
+ TDM_BACKEND_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 HAL_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_BACKEND_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(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
+ if (ret) {
+ TDM_BACKEND_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 HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ TDM_BACKEND_DBG("success. prop_id(%d)", buf.prop_id);
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+static hal_tdm_error
+_tdm_exynos_capture_legacy_stream_pp_cmd(tdm_exynos_capture_legacy_data *capture_data, enum drm_exynos_ipp_ctrl cmd)
+{
+ tdm_exynos_display *display_data = capture_data->display_data;
+ struct drm_exynos_ipp_cmd_ctrl ctrl;
+ int ret = 0;
+
+ ctrl.prop_id = capture_data->stream.prop_id;
+ ctrl.ctrl = cmd;
+
+ TDM_BACKEND_DBG("prop_id(%d) ctrl(%d). ", ctrl.prop_id, ctrl.ctrl);
+
+ ret = ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_CMD_CTRL, &ctrl);
+ if (ret) {
+ TDM_BACKEND_ERR("failed. prop_id(%d) ctrl(%d). %m", ctrl.prop_id, ctrl.ctrl);
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ TDM_BACKEND_DBG("success. prop_id(%d) ", ctrl.prop_id);
+
+ return HAL_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_BACKEND_ERR("invalid params");
+ return;
+ }
+
+ LIST_FOR_EACH_ENTRY(d, &capture_list, link) {
+ if (d == capture_data) {
+ found = d;
+ break;
+ }
+ }
+ if (!found)
+ return;
+
+ TDM_BACKEND_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_BACKEND_DBG("dequeued: %d", dequeued_buffer->index);
+ break;
+ }
+ }
+
+ if (!dequeued_buffer) {
+ TDM_BACKEND_ERR("not found buffer index: %d", buf_idx[0]);
+ return;
+ }
+
+ if (!capture_data->stream.first_event) {
+ TDM_BACKEND_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);
+
+ tbm_surface_internal_unref(dequeued_buffer->ui_buffer);
+
+ free(dequeued_buffer);
+}
+
+#if 0 // DO NOT SUPPORT
+static hal_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;
+ hal_tdm_error ret;
+
+ hal_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 HAL_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 HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ b = LIST_FIRST_ENTRY(&capture_data->pending_buffer_list, tdm_exynos_capture_legacy_buffer, link);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(b != NULL, HAL_TDM_ERROR_OPERATION_FAILED);
+
+ LIST_DEL(&b->link);
+ b->ui_buffer = hal_tdm_buffer_ref_backend(ui_buffer);
+ _tdm_exynos_capture_legacy_stream_pp_queue(capture_data, b, IPP_BUF_ENQUEUE);
+ TDM_BACKEND_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 HAL_TDM_ERROR_NONE;
+}
+#endif
+
+static hal_tdm_error
+_tdm_exynos_capture_legacy_commit_stream(tdm_exynos_capture_legacy_data *capture_data)
+{
+#if 0 // DO NOT SUPPORT
+ 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->display_data->dpy,
+ _tdm_exynos_capture_legacy_stream_timer_handler,
+ capture_data, NULL);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data->stream.timer_source != NULL, HAL_TDM_ERROR_OUT_OF_MEMORY);
+ }
+
+ hal_tdm_event_loop_source_timer_update(capture_data->stream.timer_source, ms);
+#endif
+ return HAL_TDM_ERROR_NONE;
+}
+
+static void
+_tdm_exynos_capture_legacy_oneshot_center_rect(int src_w, int src_h, int dst_w, int dst_h, hal_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, hal_tdm_pos *scale)
+{
+ float ratio;
+ hal_tdm_pos center = {0,};
+
+ _tdm_exynos_capture_legacy_oneshot_center_rect(src_w, src_h, dst_w, dst_h, ¢er);
+
+ 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(hal_tdm_pos *out_rect, hal_tdm_pos *dst_rect, hal_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 *layer_data, hal_tdm_pos *src_crop, hal_tdm_pos *showing_rect)
+{
+ tdm_exynos_output *output_data = capture_data->output_data;
+ float ratio_x, ratio_y;
+ hal_tdm_pos out_rect;
+ hal_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 *layer_data,
+ hal_tdm_pos *dst_pos, hal_tdm_pos *showing_pos, hal_tdm_pos *dst_crop,
+ hal_tdm_transform transform)
+{
+ tdm_exynos_output *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 == HAL_TDM_TRANSFORM_NORMAL || transform == HAL_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 == HAL_TDM_TRANSFORM_90 || transform == HAL_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 == HAL_TDM_TRANSFORM_180 || transform == HAL_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 == HAL_TDM_TRANSFORM_270 || transform == HAL_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_BACKEND_ERR("oneshot: get_crop unknown case error");
+ }
+}
+
+static pixman_format_code_t
+_tdm_exynos_pixman_format_get(tbm_format format)
+{
+ switch (format) {
+ case TBM_FORMAT_ARGB8888:
+ return PIXMAN_a8r8g8b8;
+ case TBM_FORMAT_XRGB8888:
+ return PIXMAN_x8r8g8b8;
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static hal_tdm_error
+_tdm_exynos_capture_convert_buffer(tbm_surface_h srcbuf, tbm_surface_h dstbuf,
+ hal_tdm_pos *srcpos, hal_tdm_pos *dstpos,
+ hal_tdm_transform transform, int over)
+{
+ tbm_surface_info_s src_info, dst_info;
+ pixman_image_t *src_img = NULL, *dst_img = NULL;
+ pixman_format_code_t src_format, dst_format;
+ double scale_x, scale_y;
+ int rotate_step, bos;
+ pixman_transform_t t;
+ struct pixman_f_transform ft;
+ pixman_op_t op;
+ int src_stride, dst_stride;
+ int buf_width, err;
+ hal_tdm_error ret = HAL_TDM_ERROR_OPERATION_FAILED;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(srcbuf != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(dstbuf != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ bos = tbm_surface_internal_get_num_bos(srcbuf);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(bos == 1, HAL_TDM_ERROR_OPERATION_FAILED);
+
+ bos = tbm_surface_internal_get_num_bos(dstbuf);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(bos == 1, HAL_TDM_ERROR_OPERATION_FAILED);
+
+ err = tbm_surface_map(srcbuf, TBM_OPTION_READ, &src_info);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(err == TBM_SURFACE_ERROR_NONE, HAL_TDM_ERROR_OPERATION_FAILED);
+
+ err = tbm_surface_map(dstbuf, TBM_OPTION_WRITE, &dst_info);
+ TDM_BACKEND_GOTO_VAL_IF_FAIL(err == TBM_SURFACE_ERROR_NONE, unmap_srcbuf);
+
+ /* not handle buffers which have 2 more gem handles */
+ TDM_BACKEND_GOTO_VAL_IF_FAIL(src_info.planes[0].ptr != NULL, unmap_dstbuf);
+ TDM_BACKEND_GOTO_VAL_IF_FAIL(dst_info.planes[0].ptr != NULL, unmap_dstbuf);
+
+ src_format = _tdm_exynos_pixman_format_get(src_info.format);
+ TDM_BACKEND_GOTO_VAL_IF_FAIL(src_format > 0, unmap_dstbuf);
+ dst_format = _tdm_exynos_pixman_format_get(dst_info.format);
+ TDM_BACKEND_GOTO_VAL_IF_FAIL(dst_format > 0, unmap_dstbuf);
+
+ buf_width = src_info.planes[0].stride >> 2;
+ src_stride = src_info.planes[0].stride;
+ src_img = pixman_image_create_bits(src_format, buf_width, src_info.height,
+ (uint32_t*)src_info.planes[0].ptr, src_stride);
+ TDM_BACKEND_GOTO_VAL_IF_FAIL(src_img, unref_img);
+
+ buf_width = dst_info.planes[0].stride >> 2;
+ dst_stride = dst_info.planes[0].stride;
+ dst_img = pixman_image_create_bits(dst_format, buf_width, dst_info.height,
+ (uint32_t*)dst_info.planes[0].ptr, dst_stride);
+ TDM_BACKEND_GOTO_VAL_IF_FAIL(dst_img, unref_img);
+
+ pixman_f_transform_init_identity(&ft);
+
+ if (transform & HAL_TDM_TRANSFORM_FLIPPED) {
+ pixman_f_transform_scale(&ft, NULL, -1, 1);
+ pixman_f_transform_translate(&ft, NULL, dstpos->w, 0);
+ }
+
+ rotate_step = transform & 0x3;
+ if (rotate_step > 0) {
+ int c, s, tx = 0, ty = 0;
+ switch (rotate_step) {
+ case 1:
+ c = 0, s = -1, tx = -dstpos->w;
+ break;
+ case 2:
+ c = -1, s = 0, tx = -dstpos->w, ty = -dstpos->h;
+ break;
+ case 3:
+ c = 0, s = 1, ty = -dstpos->h;
+ break;
+ }
+ pixman_f_transform_translate(&ft, NULL, tx, ty);
+ pixman_f_transform_rotate(&ft, NULL, c, s);
+ }
+
+ if (rotate_step % 2 == 0) {
+ scale_x = (double)srcpos->w / dstpos->w;
+ scale_y = (double)srcpos->h / dstpos->h;
+ } else {
+ scale_x = (double)srcpos->w / dstpos->h;
+ scale_y = (double)srcpos->h / dstpos->w;
+ }
+
+ pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
+ pixman_f_transform_translate(&ft, NULL, srcpos->x, srcpos->y);
+ pixman_transform_from_pixman_f_transform(&t, &ft);
+ pixman_image_set_transform(src_img, &t);
+
+ op = (!over) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER;
+
+ pixman_image_composite(op, src_img, NULL, dst_img, 0, 0, 0, 0,
+ dstpos->x, dstpos->y, dstpos->w, dstpos->h);
+
+ ret = HAL_TDM_ERROR_NONE;
+
+unref_img:
+ if (src_img)
+ pixman_image_unref(src_img);
+ if (dst_img)
+ pixman_image_unref(dst_img);
+unmap_dstbuf:
+ tbm_surface_unmap(dstbuf);
+unmap_srcbuf:
+ tbm_surface_unmap(srcbuf);
+
+ return ret;
+}
+
+static void
+_tdm_exynos_capture_legacy_oneshot_composite_layers_sw(tdm_exynos_capture_legacy_data *capture_data, tbm_surface_h buffer)
+{
+ tdm_exynos_output *output_data = capture_data->output_data;
+ tdm_exynos_layer *layer_data = NULL;
+ tbm_surface_info_s buf_info;
+ int err;
+
+ err = tbm_surface_get_info(buffer, &buf_info);
+ TDM_BACKEND_RETURN_IF_FAIL(err == TBM_SURFACE_ERROR_NONE);
+
+ LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+ tbm_surface_h buf;
+ hal_tdm_pos dst_pos;
+ hal_tdm_pos showing_pos;
+ hal_tdm_pos src_crop;
+ hal_tdm_pos dst_crop;
+ hal_tdm_transform transform = HAL_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_BACKEND_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_exynos_capture_convert_buffer(buf, buffer,
+ &src_crop, &dst_crop, transform, 1);
+ }
+}
+
+static hal_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+tdm_exynos_capture_legacy_get_capability(tdm_exynos_display *display_data, hal_tdm_caps_capture *caps)
+{
+ int i;
+
+ if (!caps) {
+ TDM_BACKEND_ERR("invalid params");
+ return HAL_TDM_ERROR_INVALID_PARAMETER;
+ }
+
+ caps->capabilities = HAL_TDM_CAPTURE_CAPABILITY_OUTPUT|
+ HAL_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_BACKEND_ERR("alloc failed");
+ return HAL_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_capture *
+tdm_exynos_capture_legacy_create_output(tdm_exynos_display *display_data, hal_tdm_output *output, hal_tdm_error *error)
+{
+ tdm_exynos_capture_legacy_data *capture_data = calloc(1, sizeof(tdm_exynos_capture_legacy_data));
+ if (!capture_data) {
+ TDM_BACKEND_ERR("alloc failed");
+ if (error)
+ *error = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ capture_data->display_data = display_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_BACKEND_DBG("capture(%p) create", capture_data);
+
+ return capture_data;
+}
+
+void
+exynos_capture_legacy_destroy(hal_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_BACKEND_DBG("capture(%p) destroy", capture_data);
+
+#if 0 // DO NOT SUPPORT
+ if (capture_data->stream.timer_source)
+ hal_tdm_event_loop_source_remove(capture_data->stream.timer_source);
+#endif
+
+ 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);
+ tbm_surface_internal_unref(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);
+}
+
+hal_tdm_error
+exynos_capture_legacy_set_info(hal_tdm_capture *capture, hal_tdm_info_capture *info)
+{
+ tdm_exynos_capture_legacy_data *capture_data = capture;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(info, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ capture_data->info = *info;
+ capture_data->info_changed = 1;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_capture_legacy_attach(hal_tdm_capture *capture, tbm_surface_h buffer)
+{
+ tdm_exynos_capture_legacy_data *capture_data = capture;
+ tdm_exynos_capture_legacy_buffer *b;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(buffer, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ b = calloc(1, sizeof(tdm_exynos_capture_legacy_buffer));
+ if (!b) {
+ TDM_BACKEND_ERR("alloc failed");
+ return HAL_TDM_ERROR_NONE;
+ }
+
+ LIST_ADDTAIL(&b->link, &capture_data->pending_buffer_list);
+
+ b->index = _get_index(capture_data);
+ b->buffer = buffer;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_capture_legacy_commit(hal_tdm_capture *capture)
+{
+ tdm_exynos_capture_legacy_data *capture_data = capture;
+ hal_tdm_error ret;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ if (capture_data->info.type == HAL_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;
+}
+
+hal_tdm_error
+exynos_capture_legacy_set_done_handler(hal_tdm_capture *capture, hal_tdm_capture_done_handler func, void *user_data)
+{
+ tdm_exynos_capture_legacy_data *capture_data = capture;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(capture_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ capture_data->done_func = func;
+ capture_data->done_user_data = user_data;
+
+ return HAL_TDM_ERROR_NONE;
+}
--- /dev/null
+/**************************************************************************
+
+libtdm_exynos
+
+Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_backend_exynos.h"
+
+#define LAYER_COUNT_FOR_NOT_FIXED 2
+#define LAYER_PRIMARY_INDEX_FOR_NOT_FIXED 1
+
+static hal_tdm_error
+_tdm_exynos_display_create_layer_list_type(tdm_exynos_display *display_data)
+{
+ hal_tdm_error ret;
+ int i;
+
+ for (i = 0; i < display_data->plane_res->count_planes; i++) {
+ tdm_exynos_output *output_data = NULL;
+ tdm_exynos_layer *layer_data;
+ drmModePlanePtr plane;
+ unsigned int type = 0;
+ int output_find = 0;
+
+ plane = drmModeGetPlane(display_data->drm_fd, display_data->plane_res->planes[i]);
+ if (!plane) {
+ TDM_BACKEND_ERR("no plane");
+ continue;
+ }
+
+ ret = tdm_exynos_display_get_property(display_data,
+ display_data->plane_res->planes[i],
+ DRM_MODE_OBJECT_PLANE, "type", &type, NULL);
+ if (ret != HAL_TDM_ERROR_NONE) {
+ TDM_BACKEND_ERR("plane(%d) doesn't have 'type' info",
+ display_data->plane_res->planes[i]);
+ drmModeFreePlane(plane);
+ continue;
+ }
+
+ layer_data = calloc(1, sizeof(tdm_exynos_layer));
+ if (!layer_data) {
+ TDM_BACKEND_ERR("alloc failed");
+ drmModeFreePlane(plane);
+ continue;
+ }
+
+ LIST_FOR_EACH_ENTRY(output_data, &display_data->output_list, link) {
+ if (plane->possible_crtcs & (1 << output_data->pipe)) {
+ output_find = 1;
+ break;
+ }
+ }
+
+ if (!output_find) {
+ TDM_BACKEND_ERR("plane(%d) couldn't found proper output", plane->plane_id);
+ drmModeFreePlane(plane);
+ free(layer_data);
+ continue;
+ }
+
+ layer_data->display_data = display_data;
+ layer_data->output_data = output_data;
+ layer_data->plane_id = display_data->plane_res->planes[i];
+
+ if (type == DRM_PLANE_TYPE_CURSOR) {
+ layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_CURSOR |
+ TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
+ layer_data->zpos = 2;
+ } else if (type == DRM_PLANE_TYPE_OVERLAY) {
+ layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_OVERLAY |
+ TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
+ layer_data->zpos = 1;
+ } else if (type == DRM_PLANE_TYPE_PRIMARY) {
+ layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_PRIMARY |
+ TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
+ layer_data->zpos = 0;
+ output_data->primary_layer = layer_data;
+ } else {
+ drmModeFreePlane(plane);
+ free(layer_data);
+ continue;
+ }
+
+ TDM_BACKEND_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 HAL_TDM_ERROR_NONE;
+}
+
+static hal_tdm_error
+_tdm_exynos_display_create_layer_list_immutable_zpos(tdm_exynos_display *display_data)
+{
+ hal_tdm_error ret;
+ int i;
+
+ for (i = 0; i < display_data->plane_res->count_planes; i++) {
+ tdm_exynos_output *output_data = NULL;
+ tdm_exynos_layer *layer_data;
+ drmModePlanePtr plane;
+ unsigned int type = 0, zpos = 0;
+ int output_find = 0;
+
+ plane = drmModeGetPlane(display_data->drm_fd, display_data->plane_res->planes[i]);
+ if (!plane) {
+ TDM_BACKEND_ERR("no plane");
+ continue;
+ }
+
+ ret = tdm_exynos_display_get_property(display_data,
+ display_data->plane_res->planes[i],
+ DRM_MODE_OBJECT_PLANE, "type", &type, NULL);
+ if (ret != HAL_TDM_ERROR_NONE) {
+ TDM_BACKEND_ERR("plane(%d) doesn't have 'type' info",
+ display_data->plane_res->planes[i]);
+ drmModeFreePlane(plane);
+ continue;
+ }
+
+ ret = tdm_exynos_display_get_property(display_data,
+ display_data->plane_res->planes[i],
+ DRM_MODE_OBJECT_PLANE, "zpos", &zpos, NULL);
+ if (ret != HAL_TDM_ERROR_NONE) {
+ TDM_BACKEND_ERR("plane(%d) doesn't have 'zpos' info",
+ display_data->plane_res->planes[i]);
+ drmModeFreePlane(plane);
+ continue;
+ }
+
+ layer_data = calloc(1, sizeof(tdm_exynos_layer));
+ if (!layer_data) {
+ TDM_BACKEND_ERR("alloc failed");
+ drmModeFreePlane(plane);
+ continue;
+ }
+
+ LIST_FOR_EACH_ENTRY(output_data, &display_data->output_list, link) {
+ if (plane->possible_crtcs & (1 << output_data->pipe)) {
+ output_find = 1;
+ break;
+ }
+ }
+
+ if (!output_find) {
+ TDM_BACKEND_ERR("plane(%d) couldn't found proper output", plane->plane_id);
+ drmModeFreePlane(plane);
+ free(layer_data);
+ continue;
+ }
+
+ layer_data->display_data = display_data;
+ layer_data->output_data = output_data;
+ layer_data->plane_id = display_data->plane_res->planes[i];
+ layer_data->zpos = zpos;
+
+ if (type == DRM_PLANE_TYPE_CURSOR)
+ layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_CURSOR |
+ TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
+ else if (type == DRM_PLANE_TYPE_OVERLAY)
+ layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_OVERLAY |
+ TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
+ else if (type == DRM_PLANE_TYPE_PRIMARY) {
+ layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_PRIMARY |
+ TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
+ output_data->primary_layer = layer_data;
+ } else {
+ drmModeFreePlane(plane);
+ free(layer_data);
+ continue;
+ }
+
+ TDM_BACKEND_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 HAL_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 hal_tdm_error
+_tdm_exynos_display_create_layer_list_not_fixed(tdm_exynos_display *display_data)
+{
+ int find_pipe = -1;
+ int zpos = 0;
+ int output_count, i;
+
+ output_count = LIST_LENGTH(&display_data->output_list);
+
+ if (display_data->plane_res->count_planes < (output_count * LAYER_COUNT_FOR_NOT_FIXED)) {
+ TDM_BACKEND_ERR("not enough layers");
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ for (i = 0; i < display_data->plane_res->count_planes; i++) {
+ tdm_exynos_output *output_data = NULL;
+ tdm_exynos_layer *layer_data;
+ drmModePlanePtr plane;
+
+ plane = drmModeGetPlane(display_data->drm_fd, display_data->plane_res->planes[i]);
+ if (!plane) {
+ TDM_BACKEND_ERR("no plane");
+ continue;
+ }
+
+ layer_data = calloc(1, sizeof(tdm_exynos_layer));
+ if (!layer_data) {
+ TDM_BACKEND_ERR("alloc failed");
+ drmModeFreePlane(plane);
+ continue;
+ }
+
+ if (i % LAYER_COUNT_FOR_NOT_FIXED == 0) {
+ find_pipe++;
+ zpos = 0;
+ }
+
+ LIST_FOR_EACH_ENTRY(output_data, &display_data->output_list, link) {
+ if (output_data->pipe == find_pipe)
+ break;
+ }
+
+ layer_data->display_data = display_data;
+ layer_data->output_data = output_data;
+ layer_data->plane_id = display_data->plane_res->planes[i];
+
+ layer_data->zpos = zpos++;
+
+ if (layer_data->zpos == LAYER_PRIMARY_INDEX_FOR_NOT_FIXED) {
+ layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_PRIMARY |
+ TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
+ output_data->primary_layer = layer_data;
+ } else {
+ hal_tdm_error ret;
+
+ layer_data->capabilities = TDM_EXYNOS_LAYER_CAPABILITY_OVERLAY |
+ TDM_EXYNOS_LAYER_CAPABILITY_GRAPHIC;
+
+ ret = tdm_exynos_display_set_property(display_data, layer_data->plane_id,
+ DRM_MODE_OBJECT_PLANE, "zpos", layer_data->zpos);
+ if (ret != HAL_TDM_ERROR_NONE) {
+ drmModeFreePlane(plane);
+ free(layer_data);
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+ }
+
+ TDM_BACKEND_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 HAL_TDM_ERROR_NONE;
+}
+
+void
+tdm_exynos_display_to_tdm_mode(drmModeModeInfoPtr drm_mode,
+ hal_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, HAL_TDM_NAME_LEN, "%s", drm_mode->name);
+}
+
+hal_tdm_error
+tdm_exynos_display_create_layer_list(tdm_exynos_display *display_data)
+{
+ tdm_exynos_output *output_data = NULL;
+ hal_tdm_error ret;
+
+ if (!display_data->has_zpos_info)
+ ret = _tdm_exynos_display_create_layer_list_type(display_data);
+ else if (display_data->is_immutable_zpos)
+ ret = _tdm_exynos_display_create_layer_list_immutable_zpos(display_data);
+ else
+ ret = _tdm_exynos_display_create_layer_list_not_fixed(display_data);
+
+ if (ret != HAL_TDM_ERROR_NONE)
+ return ret;
+
+ LIST_FOR_EACH_ENTRY(output_data, &display_data->output_list, link) {
+ if (!output_data->primary_layer) {
+ TDM_BACKEND_ERR("output(%d) no primary layer_data", output_data->pipe);
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+ }
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+void
+tdm_exynos_display_destroy_output_list(tdm_exynos_display *display_data)
+{
+ tdm_exynos_output *o = NULL, *oo = NULL;
+
+ if (LIST_IS_EMPTY(&display_data->output_list))
+ return;
+
+ LIST_FOR_EACH_ENTRY_SAFE(o, oo, &display_data->output_list, link) {
+ LIST_DEL(&o->link);
+ if (!LIST_IS_EMPTY(&o->layer_list)) {
+ tdm_exynos_layer *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_display *display_data)
+{
+ tdm_exynos_output *output_data = NULL;
+
+ if (LIST_IS_EMPTY(&display_data->output_list))
+ return;
+
+ LIST_FOR_EACH_ENTRY(output_data, &display_data->output_list, link) {
+ drmModeConnectorPtr connector;
+ hal_tdm_output_conn_status new_status;
+
+ connector = drmModeGetConnector(display_data->drm_fd,
+ output_data->connector_id);
+ if (!connector) {
+ TDM_BACKEND_ERR("no connector: %d", output_data->connector_id);
+ continue;
+ }
+
+ if (connector->connection == DRM_MODE_CONNECTED)
+ new_status = HAL_TDM_OUTPUT_CONN_STATUS_CONNECTED;
+ else
+ new_status = HAL_TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+
+ tdm_exynos_output_update_status(output_data, new_status);
+
+ drmModeFreeConnector(connector);
+ }
+}
+
+hal_tdm_error
+tdm_exynos_display_create_output_list(tdm_exynos_display *display_data)
+{
+ tdm_exynos_output *output_data;
+ int i;
+ hal_tdm_error ret;
+ int allocated = 0;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(LIST_IS_EMPTY(&display_data->output_list),
+ HAL_TDM_ERROR_OPERATION_FAILED);
+
+ for (i = 0; i < display_data->mode_res->count_connectors; i++) {
+ drmModeConnectorPtr connector;
+ drmModeEncoderPtr encoder;
+ int crtc_id = 0, c, j;
+
+ connector = drmModeGetConnector(display_data->drm_fd,
+ display_data->mode_res->connectors[i]);
+ if (!connector) {
+ TDM_BACKEND_ERR("no connector");
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ goto failed_create;
+ }
+
+ if (connector->count_encoders != 1) {
+ TDM_BACKEND_ERR("too many encoders: %d", connector->count_encoders);
+ drmModeFreeConnector(connector);
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ goto failed_create;
+ }
+
+ encoder = drmModeGetEncoder(display_data->drm_fd, connector->encoders[0]);
+ if (!encoder) {
+ TDM_BACKEND_ERR("no encoder");
+ drmModeFreeConnector(connector);
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ goto failed_create;
+ }
+
+ for (c = 0; c < display_data->mode_res->count_crtcs; c++) {
+ if (allocated & (1 << c))
+ continue;
+
+ if ((encoder->possible_crtcs & (1 << c)) == 0)
+ continue;
+
+ crtc_id = display_data->mode_res->crtcs[c];
+ allocated |= (1 << c);
+ break;
+ }
+
+ if (crtc_id == 0) {
+ TDM_BACKEND_ERR("no possible crtc");
+ drmModeFreeConnector(connector);
+ drmModeFreeEncoder(encoder);
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ goto failed_create;
+ }
+
+ output_data = calloc(1, sizeof(tdm_exynos_output));
+ if (!output_data) {
+ TDM_BACKEND_ERR("alloc failed");
+ drmModeFreeConnector(connector);
+ drmModeFreeEncoder(encoder);
+ ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ goto failed_create;
+ }
+
+ LIST_INITHEAD(&output_data->layer_list);
+
+ output_data->display_data = display_data;
+ output_data->connector_id = display_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 = HAL_TDM_OUTPUT_CONN_STATUS_CONNECTED;
+ else
+ output_data->status = HAL_TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+
+ for (j = 0; j < connector->count_props; j++) {
+ drmModePropertyPtr prop = drmModeGetProperty(display_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_BACKEND_ERR("alloc failed");
+ free(output_data);
+ drmModeFreeConnector(connector);
+ drmModeFreeEncoder(encoder);
+ ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ goto failed_create;
+ }
+ output_data->output_modes = calloc(connector->count_modes, sizeof(hal_tdm_output_mode));
+ if (!output_data->output_modes) {
+ TDM_BACKEND_ERR("alloc failed");
+ free(output_data->drm_modes);
+ free(output_data);
+ drmModeFreeConnector(connector);
+ drmModeFreeEncoder(encoder);
+ ret = HAL_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]);
+ }
+
+ LIST_ADDTAIL(&output_data->link, &display_data->output_list);
+
+ TDM_BACKEND_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_BACKEND_DBG("output count: %d", display_data->mode_res->count_connectors);
+
+ return HAL_TDM_ERROR_NONE;
+failed_create:
+ tdm_exynos_display_destroy_output_list(display_data);
+ return ret;
+}
+
+hal_tdm_error
+tdm_exynos_display_set_property(tdm_exynos_display *display_data,
+ unsigned int obj_id, unsigned int obj_type,
+ const char *name, unsigned int value)
+{
+ drmModeObjectPropertiesPtr props = NULL;
+ unsigned int i;
+
+ props = drmModeObjectGetProperties(display_data->drm_fd, obj_id, obj_type);
+ if (!props) {
+ TDM_BACKEND_ERR("drmModeObjectGetProperties failed: %m");
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+ for (i = 0; i < props->count_props; i++) {
+ drmModePropertyPtr prop = drmModeGetProperty(display_data->drm_fd,
+ props->props[i]);
+ int ret;
+ if (!prop) {
+ TDM_BACKEND_ERR("drmModeGetProperty failed: %m");
+ drmModeFreeObjectProperties(props);
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+ if (!strcmp(prop->name, name)) {
+ ret = drmModeObjectSetProperty(display_data->drm_fd, obj_id, obj_type,
+ prop->prop_id, value);
+ if (ret < 0) {
+ TDM_BACKEND_ERR("drmModeObjectSetProperty failed: %m");
+ drmModeFreeProperty(prop);
+ drmModeFreeObjectProperties(props);
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+ drmModeFreeProperty(prop);
+ drmModeFreeObjectProperties(props);
+ return HAL_TDM_ERROR_NONE;
+ }
+ drmModeFreeProperty(prop);
+ }
+
+ TDM_BACKEND_ERR("not found '%s' property", name);
+
+ drmModeFreeObjectProperties(props);
+ /* TODO
+ * kernel info error
+ * it must be changed to 'return HAL_TDM_ERROR_OPERATION_FAILED' after kernel fix.
+ */
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+tdm_exynos_display_get_property(tdm_exynos_display *display_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(display_data->drm_fd, obj_id, obj_type);
+ if (!props)
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+
+ for (i = 0; i < props->count_props; i++) {
+ drmModePropertyPtr prop = drmModeGetProperty(display_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 HAL_TDM_ERROR_NONE;
+ }
+
+ drmModeFreeProperty(prop);
+ }
+ drmModeFreeObjectProperties(props);
+ TDM_BACKEND_DBG("coundn't find '%s' property", name);
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+}
+
+hal_tdm_error
+exynos_display_get_capability(hal_tdm_display *display, hal_tdm_caps_display *caps)
+{
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(caps, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ caps->max_layer_count = -1; /* not defined */
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_display_get_pp_capability(hal_tdm_display *display, hal_tdm_caps_pp *caps)
+{
+ tdm_exynos_display *display_data = (tdm_exynos_display *)display;
+ if (display_data->use_ippv2)
+ return tdm_exynos_pp_get_capability(display_data, caps);
+ else
+ return tdm_exynos_pp_legacy_get_capability(display_data, caps);
+}
+
+hal_tdm_error
+exynos_display_get_capture_capability(hal_tdm_display *display, hal_tdm_caps_capture *caps)
+{
+ tdm_exynos_display *display_data = (tdm_exynos_display *)display;
+ if (display_data->use_ippv2)
+ return tdm_exynos_capture_get_capability(display_data, caps);
+ else
+ return tdm_exynos_capture_legacy_get_capability(display_data, caps);
+}
+
+hal_tdm_output **
+exynos_display_get_outputs(hal_tdm_display *display, int *count,
+ hal_tdm_error *error)
+{
+ tdm_exynos_display *display_data = (tdm_exynos_display *)display;
+ tdm_exynos_output *output_data = NULL;
+ hal_tdm_output **outputs;
+ hal_tdm_error ret;
+ int i;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data, NULL);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(count, NULL);
+
+ *count = 0;
+ LIST_FOR_EACH_ENTRY(output_data, &display_data->output_list, link)
+ (*count)++;
+
+ if (*count == 0) {
+ ret = HAL_TDM_ERROR_NONE;
+ goto failed_get;
+ }
+
+ /* will be freed in frontend */
+ outputs = calloc(*count, sizeof(tdm_exynos_output *));
+ if (!outputs) {
+ TDM_BACKEND_ERR("failed: alloc memory");
+ *count = 0;
+ ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ goto failed_get;
+ }
+
+ i = 0;
+ LIST_FOR_EACH_ENTRY(output_data, &display_data->output_list, link)
+ outputs[i++] = output_data;
+
+ if (error)
+ *error = HAL_TDM_ERROR_NONE;
+
+ return outputs;
+failed_get:
+ if (error)
+ *error = ret;
+ return NULL;
+}
+
+hal_tdm_error
+exynos_display_get_fd(hal_tdm_display *display, int *fd)
+{
+ tdm_exynos_display *display_data = (tdm_exynos_display *)display;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(fd, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ *fd = display_data->drm_fd;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_display_handle_events(hal_tdm_display *display)
+{
+ tdm_exynos_display *display_data = (tdm_exynos_display *)display;
+ drmEventContext ctx;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data, HAL_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(display_data->drm_fd, &ctx);
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_pp *
+exynos_display_create_pp(hal_tdm_display *display, hal_tdm_error *error)
+{
+ tdm_exynos_display *display_data = (tdm_exynos_display *)display;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data, NULL);
+
+ if (display_data->use_ippv2)
+ return tdm_exynos_pp_create(display_data, error);
+ else
+ return tdm_exynos_pp_legacy_create(display_data, error);
+}
--- /dev/null
+/**************************************************************************
+
+libtdm_exynos
+
+Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_backend_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_BACKEND_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_BACKEND_ERR("drm format '%c%c%c%c' not found", FOURCC_STR(format));
+
+ return 0;
+}
--- /dev/null
+/**************************************************************************
+
+libtdm_exynos
+
+Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_backend_exynos.h"
+
+#define MIN_WIDTH 32
+
+hal_tdm_hwc_window *
+_exynos_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_hwc_window_info *info,
+ hal_tdm_error *error);
+
+const char *
+_comp_to_str(hal_tdm_hwc_window_composition composition_type)
+{
+ if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_CLIENT)
+ return "CLIENT";
+ else if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_DEVICE)
+ return "DEVICE";
+ else if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_CURSOR)
+ return "CURSOR";
+ else if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_VIDEO)
+ return "VIDEO";
+ else if (composition_type == HAL_TDM_HWC_WIN_COMPOSITION_NONE)
+ return "SKIP";
+
+ return "unknown";
+}
+
+static int
+_can_set_hwc_window_on_hw_layer(tdm_exynos_hwc_window *hwc_window_data)
+{
+ if (!hwc_window_data->surface)
+ return 0;
+
+ if (hwc_window_data->info.transform != HAL_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 *
+_exynos_hwc_get_layer(tdm_exynos_hwc *hwc_data, int zpos)
+{
+ tdm_exynos_output *output_data = hwc_data->output_data;
+ tdm_exynos_layer *l = NULL;
+
+ LIST_FOR_EACH_ENTRY(l, &output_data->layer_list, link)
+ if (l->zpos == zpos)
+ return l;
+
+ return NULL;
+}
+
+static hal_tdm_error
+_set_hwc_window_buffer_to_layer(tdm_exynos_layer *layer_data,
+ tdm_exynos_hwc_window *hwc_window_data)
+{
+ hal_tdm_error ret;
+
+ if (hwc_window_data == NULL || !hwc_window_data->surface) {
+ ret = tdm_exynos_layer_unset_buffer(layer_data);
+ } else {
+ ret = tdm_exynos_layer_set_buffer(layer_data, hwc_window_data->surface);
+ }
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret);
+
+ return ret;
+}
+
+static tdm_exynos_hwc_window *
+_find_maped_hwc_window_to_layer(struct list_head *hwc_wnds, int layer_zpos)
+{
+ tdm_exynos_hwc_window *hwc_window_data = NULL;
+
+ LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
+ if (hwc_window_data->client_type == HAL_TDM_HWC_WIN_COMPOSITION_NONE)
+ continue;
+
+ if (hwc_window_data->assigned_layer_zpos == layer_zpos &&
+ (hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_DEVICE ||
+ hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_CURSOR ||
+ hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_VIDEO)) {
+ TDM_BACKEND_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 *hwc_data)
+{
+ tdm_exynos_layer *layer_data = NULL;
+ tdm_exynos_output *output_data = hwc_data->output_data;
+ tdm_exynos_hwc_window *hwc_window_data;
+ hal_tdm_error ret;
+
+ LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+ if (hwc_data->need_target_window && layer_data->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_data->zpos);
+
+ if (hwc_window_data) {
+ ret = tdm_exynos_layer_set_info((tdm_exynos_layer *)layer_data, (tdm_exynos_layer_info *)&(hwc_window_data->info));
+ if (ret != HAL_TDM_ERROR_NONE)
+ TDM_BACKEND_ERR("cannot set info to layer_data with %d zpos", layer_data->zpos);
+ }
+ }
+}
+
+static tdm_exynos_hwc_window *
+_exynos_hwc_find_assigned_hwc_window(struct list_head *hwc_wnds, int layer_zpos)
+{
+ tdm_exynos_hwc_window *hwc_window_data = NULL;
+
+ LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
+ if (hwc_window_data->client_type == HAL_TDM_HWC_WIN_COMPOSITION_NONE)
+ continue;
+
+ if (hwc_window_data->assigned_layer_zpos == layer_zpos) {
+ return hwc_window_data;
+ }
+ }
+
+ return NULL;
+}
+
+static hal_tdm_error
+_exynos_hwc_prepare_commit(tdm_exynos_hwc *hwc_data) {
+ tdm_exynos_layer *layer_data = NULL;
+ tdm_exynos_hwc_window *hwc_window_data = NULL;
+ tdm_exynos_output *output_data = hwc_data->output_data;
+
+ _update_layers_info(hwc_data);
+
+ /* set target hwc window */
+ if (hwc_data->need_target_window) {
+ layer_data = _exynos_hwc_get_layer(hwc_data, hwc_data->target_window_zpos);
+ _set_hwc_window_buffer_to_layer(layer_data, hwc_data->target_hwc_window);
+ }
+
+ LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+ if (hwc_data->need_target_window && layer_data == output_data->primary_layer)
+ continue;
+
+ hwc_window_data = _exynos_hwc_find_assigned_hwc_window(&hwc_data->hwc_window_list, layer_data->zpos);
+ if (hwc_window_data) {
+ _set_hwc_window_buffer_to_layer(layer_data, hwc_window_data);
+ } else {
+ /* do not set the null on the primary layer_data */
+ if (layer_data != output_data->primary_layer)
+ _set_hwc_window_buffer_to_layer(layer_data, NULL);
+ }
+ }
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+static int
+_exynos_hwc_get_primary_layer_zpos(tdm_exynos_hwc *hwc_data)
+{
+ tdm_exynos_output *output_data = hwc_data->output_data;
+ tdm_exynos_layer *layer_data = NULL;
+
+ LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+ if (layer_data->capabilities & TDM_EXYNOS_LAYER_CAPABILITY_PRIMARY)
+ return layer_data->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 *hwc_data , hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds)
+{
+ tdm_exynos_output *output_data = hwc_data->output_data;
+ tdm_exynos_hwc_window **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**)composited_wnds;
+
+ TDM_BACKEND_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 != HAL_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_data policy */
+ for (i = 0; i < num_wnds; i++) {
+ if (composited_list[i]->client_type == HAL_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_data */
+ ++min_zpos;
+ --available_layers;
+ continue;
+ }
+
+ composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_CLIENT;
+ composited_list[i]->candidate_layer_zpos = -1;
+
+ /* The validate type of all windows below this window are HAL_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 == HAL_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_BACKEND_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 == HAL_TDM_HWC_WIN_COMPOSITION_VIDEO)
+ continue;
+ if (available_layers == 0)
+ break;
+
+ if (composited_list[i]->client_type == HAL_TDM_HWC_WIN_COMPOSITION_DEVICE ||
+ composited_list[i]->client_type == HAL_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_BACKEND_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 == HAL_TDM_HWC_WIN_COMPOSITION_VIDEO)
+ continue;
+
+ composited_list[i]->validated_type = HAL_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 *hwc_data)
+{
+ tdm_exynos_hwc_window *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 == HAL_TDM_HWC_WIN_COMPOSITION_NONE)
+ continue;
+
+ if (hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_DEVICE ||
+ hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_CURSOR ||
+ hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_VIDEO)
+ TDM_BACKEND_DBG(" window(%p) type: %s -> %s : is mapped to layer_data 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_BACKEND_DBG(" window(%p) type: %s -> %s : is composited to layer_data 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 *hwc_data)
+{
+ tdm_exynos_hwc_window *hwc_window_data = NULL;
+
+ LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
+ if (hwc_window_data->client_type == HAL_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_BACKEND_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 *hwc_data)
+{
+ int num = 0;
+ tdm_exynos_hwc_window *hwc_window_data = NULL;
+
+ LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
+ if (hwc_window_data->client_type == HAL_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 *hwc_data)
+{
+ tdm_exynos_output *output_data = hwc_data->output_data;
+ tdm_exynos_layer *layer_data = NULL;
+
+ LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+ if (layer_data->capabilities & TDM_EXYNOS_LAYER_CAPABILITY_PRIMARY)
+ return layer_data->zpos;
+ }
+
+ return 0;
+}
+#endif
+
+static tbm_surface_queue_h
+_exynos_hwc_window_get_tbm_buffer_queue(hal_tdm_hwc_window *hwc_window, hal_tdm_error *error)
+{
+ tdm_exynos_hwc_window *hwc_window_data = NULL;
+ tbm_surface_queue_h tqueue = NULL;
+ int width, height;
+ tbm_format format;
+
+ if (error)
+ *error = HAL_TDM_ERROR_INVALID_PARAMETER;
+
+ TDM_BACKEND_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 = HAL_TDM_ERROR_OPERATION_FAILED;
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(tqueue != NULL, NULL);
+
+ if (error)
+ *error = HAL_TDM_ERROR_NONE;
+
+ return tqueue;
+
+}
+
+hal_tdm_hwc_window *
+_exynos_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_hwc_window_info *info, hal_tdm_error *error)
+{
+ tdm_exynos_hwc_window *hwc_window_data = NULL;
+ tdm_exynos_hwc *hwc_data = hwc;
+
+ if (error)
+ *error = HAL_TDM_ERROR_NONE;
+
+ if (!hwc_data) {
+ TDM_BACKEND_ERR("invalid params");
+ if (error)
+ *error = HAL_TDM_ERROR_INVALID_PARAMETER;
+ return NULL;
+ }
+
+ hwc_window_data = calloc(1, sizeof(tdm_exynos_hwc_window));
+ if (!hwc_window_data) {
+ TDM_BACKEND_ERR("alloc failed");
+ if (error)
+ *error = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ hwc_window_data->client_type = HAL_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(hal_tdm_hwc_window_info));
+
+ LIST_INITHEAD(&hwc_window_data->link);
+
+ return hwc_window_data;
+}
+
+hal_tdm_error
+exynos_hwc_initailize_target_window(tdm_exynos_hwc *hwc_data, int width, int height)
+{
+ hal_tdm_hwc_window_info info = {0};
+ hal_tdm_error ret = HAL_TDM_ERROR_NONE;
+ tdm_exynos_hwc_window *target_hwc_window;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, HAL_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_BACKEND_ERR("create target hwc window failed (%d)", ret);
+ return HAL_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_hwc_window *
+exynos_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_error *error)
+{
+ tdm_exynos_hwc *hwc_data = hwc;
+ tdm_exynos_hwc_window *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_BACKEND_DBG("hwc_window_data(%p) create", hwc_window_data);
+ if (error)
+ *error = HAL_TDM_ERROR_NONE;
+
+ return hwc_window_data;
+}
+
+hal_tdm_error
+exynos_hwc_get_video_supported_formats(hal_tdm_hwc *hwc, const tbm_format **formats, int *count)
+{
+ tdm_exynos_hwc *hwc_data = hwc;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(formats != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(count != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ // TODO:
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_hwc_get_capabilities(hal_tdm_hwc *hwc, hal_tdm_hwc_capability *capabilities)
+{
+ tdm_exynos_hwc *hwc_data = hwc;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(capabilities != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ *capabilities = 0;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_hwc_get_available_properties(hal_tdm_hwc *hwc, const hal_tdm_prop **props, int *count)
+{
+ tdm_exynos_hwc *hwc_data = hwc;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ // TODO:
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+tbm_surface_queue_h
+exynos_hwc_get_client_target_buffer_queue(hal_tdm_hwc *hwc, hal_tdm_error *error)
+{
+ tdm_exynos_hwc *hwc_data = hwc;
+ tbm_surface_queue_h tqueue = NULL;
+
+ if (error)
+ *error = HAL_TDM_ERROR_INVALID_PARAMETER;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, NULL);
+
+ if (hwc_data->target_hwc_window == NULL) {
+ if (error)
+ *error = HAL_TDM_ERROR_OPERATION_FAILED;
+ return NULL;
+ }
+
+ tqueue = _exynos_hwc_window_get_tbm_buffer_queue(hwc_data->target_hwc_window, error);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(tqueue, NULL);
+
+ if (error)
+ *error = HAL_TDM_ERROR_NONE;
+
+ return tqueue;
+}
+
+hal_tdm_error
+exynos_hwc_set_client_target_buffer(hal_tdm_hwc *hwc, tbm_surface_h buffer,
+ hal_tdm_region damage)
+{
+ tdm_exynos_hwc *hwc_data = hwc;
+ hal_tdm_error err;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window != NULL, HAL_TDM_ERROR_OPERATION_FAILED);
+
+ err = exynos_hwc_window_set_buffer(hwc_data->target_hwc_window, buffer);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(err == HAL_TDM_ERROR_NONE, err);
+
+ err = exynos_hwc_window_set_buffer_damage(hwc_data->target_hwc_window, damage);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(err == HAL_TDM_ERROR_NONE, err);
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_hwc_validate(hal_tdm_hwc *hwc, hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types)
+{
+ tdm_exynos_hwc *hwc_data = hwc;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(num_types != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ _exynos_hwc_adapt_policy(hwc_data, composited_wnds, num_wnds);
+
+ TDM_BACKEND_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_BACKEND_DBG(" !!!!!!! BUT NEED TO ACCEPT CHANES.!!!!!!!!");
+ }
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_hwc_get_changed_composition_types(hal_tdm_hwc *hwc, uint32_t *num_elements, hal_tdm_hwc_window **hwc_wnds,
+ hal_tdm_hwc_window_composition *composition_types)
+{
+ tdm_exynos_hwc *hwc_data = hwc;
+ tdm_exynos_hwc_window *hwc_window_data = NULL;
+ int num = 0;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(num_elements != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ if ((hwc_wnds == NULL) || (composition_types == NULL)) {
+ *num_elements = _exynos_hwc_get_changed_number(hwc_data);
+ return HAL_TDM_ERROR_NONE;
+ }
+
+ LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
+ if (hwc_window_data->client_type == HAL_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_hwc_accept_validation(hal_tdm_hwc *hwc)
+{
+ tdm_exynos_hwc *hwc_data = hwc;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ TDM_BACKEND_DBG(" ==============Accept Changes Done=================================");
+
+ _exynos_hwc_assigned_layer_zpos_update(hwc_data);
+ hwc_data->need_validate = 0;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_hwc_commit(hal_tdm_hwc *hwc, int sync, void *user_data)
+{
+ tdm_exynos_hwc *hwc_data = hwc;
+ tdm_exynos_output *output_data = NULL;
+ hal_tdm_error ret;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ output_data = hwc_data->output_data;
+
+ ret = _exynos_hwc_prepare_commit(hwc_data);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret);
+
+ ret = exynos_output_commit(output_data, sync, user_data);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret);
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_hwc_set_commit_handler(hal_tdm_hwc *hwc, hal_tdm_hwc_commit_handler func)
+{
+ tdm_exynos_hwc *hwc_data = hwc;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ hwc_data->commit_func = func;
+
+ return HAL_TDM_ERROR_NONE;
+}
\ No newline at end of file
--- /dev/null
+/**************************************************************************
+
+libtdm_exynos
+
+Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_backend_exynos.h"
+
+tdm_exynos_layer *
+_exynos_output_get_layer(tdm_exynos_output *output_data, int index);
+
+void
+exynos_hwc_window_destroy(hal_tdm_hwc_window *hwc_window)
+{
+ tdm_exynos_hwc_window *hwc_window_data = hwc_window;
+
+ TDM_BACKEND_RETURN_IF_FAIL(hwc_window_data != NULL);
+
+ LIST_DEL(&hwc_window_data->link);
+
+ free(hwc_window_data);
+}
+
+hal_tdm_error
+exynos_hwc_window_set_composition_type(hal_tdm_hwc_window *hwc_window,
+ hal_tdm_hwc_window_composition comp_type)
+{
+ tdm_exynos_hwc_window *hwc_window_data = hwc_window;
+ tdm_exynos_hwc *hwc_data = hwc_window_data->hwc_data;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_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 HAL_TDM_ERROR_NONE;
+
+ hwc_window_data->client_type = comp_type;
+
+ /* if the type is none, reset all status */
+ if (hwc_window_data->client_type == HAL_TDM_HWC_WIN_COMPOSITION_NONE) {
+ hwc_window_data->client_type = HAL_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_hwc_window_set_buffer_damage(hal_tdm_hwc_window *hwc_window, hal_tdm_region damage)
+{
+ tdm_exynos_hwc_window *hwc_window_data = hwc_window;
+ tdm_exynos_hwc *hwc_data = hwc_window_data->hwc_data;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ /* TODO:: */
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_hwc_window_set_info(hal_tdm_hwc_window *hwc_window, hal_tdm_hwc_window_info *info)
+{
+ tdm_exynos_hwc_window *hwc_window_data = hwc_window;
+ tdm_exynos_hwc *hwc_data;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+ hwc_data = hwc_window_data->hwc_data;
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ if (!memcmp(&hwc_window_data->info, info, sizeof(hal_tdm_hwc_window_info)))
+ return HAL_TDM_ERROR_NONE;
+
+ hwc_window_data->info = *info;
+ hwc_data->need_validate = 1;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_hwc_window_set_buffer(hal_tdm_hwc_window *hwc_window, tbm_surface_h surface)
+{
+ tdm_exynos_hwc_window *hwc_window_data = hwc_window;
+ hal_tdm_error err = HAL_TDM_ERROR_OPERATION_FAILED;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, err);
+
+ if (hwc_window_data->surface == surface)
+ return HAL_TDM_ERROR_NONE;
+
+ hwc_window_data->surface = surface;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_hwc_window_set_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value value)
+{
+ tdm_exynos_hwc_window *hwc_window_data = hwc_window;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+#if 0
+ output_data = hwc_window_data->output_data;
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ layer_data = _exynos_output_get_layer(output_data, hwc_window_data->assigned_layer_zpos);
+
+ return tdm_exynos_layer_set_property(layer_data, id, value);
+#endif
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_hwc_window_get_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value *value)
+{
+ tdm_exynos_hwc_window *hwc_window_data = hwc_window;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+#if 0
+ output_data = hwc_window_data->output_data;
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ layer_data = _exynos_output_get_layer(output_data, hwc_window_data->assigned_layer_zpos);
+
+ return tdm_exynos_layer_get_property(layer_data, id, value);
+#endif
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_hwc_window_get_constraints(hal_tdm_hwc_window *hwc_window, int *constraints)
+{
+ tdm_exynos_hwc_window *hwc_window_data = hwc_window;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ return HAL_TDM_ERROR_NONE;
+}
--- /dev/null
+/**************************************************************************
+
+libtdm_exynos
+
+Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_backend_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->display_data->drm_fd, display_buffer->fb_id);
+ if (ret < 0) {
+ TDM_BACKEND_ERR("rm fb failed");
+ return;
+ }
+ TDM_BACKEND_DBG("drmModeRmFB success!!! fb_id:%d", display_buffer->fb_id);
+ } else
+ TDM_BACKEND_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_display *display_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));
+ TDM_BACKEND_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_BACKEND_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_BACKEND_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->display_data = display_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(display_data->drm_fd, width, height, format,
+ handles, pitches, offsets, &display_buffer->fb_id, 0);
+ if (ret < 0) {
+ TDM_BACKEND_ERR("add fb failed: %m");
+ free(display_buffer);
+ return NULL;
+ }
+ TDM_BACKEND_DBG("display_data->drm_fd : %d, display_buffer->fb_id:%u", display_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;
+}
+
+hal_tdm_error
+tdm_exynos_layer_get_capability(tdm_exynos_layer *layer_data, tdm_exynos_caps_layer *caps)
+{
+ tdm_exynos_display *display_data;
+ drmModePlanePtr plane = NULL;
+ drmModeObjectPropertiesPtr props = NULL;
+ int i, fmt_count;
+ hal_tdm_error ret;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(caps, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ memset(caps, 0, sizeof(tdm_exynos_caps_layer));
+
+ display_data = layer_data->display_data;
+ plane = drmModeGetPlane(display_data->drm_fd, layer_data->plane_id);
+ if (!plane) {
+ TDM_BACKEND_ERR("get plane failed: %m");
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ goto failed_get;
+ }
+
+ caps->capabilities = layer_data->capabilities;
+ caps->zpos = layer_data->zpos; /* if VIDEO layer_data, zpos is -1 */
+
+ caps->formats = calloc(1, sizeof(tbm_format) * plane->count_formats);
+ if (!caps->formats) {
+ ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ TDM_BACKEND_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(display_data->drm_fd, layer_data->plane_id,
+ DRM_MODE_OBJECT_PLANE);
+ if (!props) {
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ TDM_BACKEND_ERR("get plane properties failed: %m\n");
+ goto failed_get;
+ }
+
+ caps->props = calloc(1, sizeof(hal_tdm_prop) * props->count_props);
+ if (!caps->props) {
+ ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ TDM_BACKEND_ERR("alloc failed\n");
+ goto failed_get;
+ }
+
+ caps->prop_count = 0;
+ for (i = 0; i < props->count_props; i++) {
+ drmModePropertyPtr prop = drmModeGetProperty(display_data->drm_fd,
+ props->props[i]);
+ if (!prop)
+ continue;
+ if (!strncmp(prop->name, "type", HAL_TDM_NAME_LEN)) {
+ drmModeFreeProperty(prop);
+ continue;
+ }
+ if (!strncmp(prop->name, "zpos", HAL_TDM_NAME_LEN)) {
+ drmModeFreeProperty(prop);
+ continue;
+ }
+ snprintf(caps->props[caps->prop_count].name, HAL_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 HAL_TDM_ERROR_NONE;
+failed_get:
+ drmModeFreeObjectProperties(props);
+ drmModeFreePlane(plane);
+ free(caps->formats);
+ free(caps->props);
+ memset(caps, 0, sizeof(tdm_exynos_caps_layer));
+ return ret;
+}
+
+hal_tdm_error
+tdm_exynos_layer_set_property(tdm_exynos_layer *layer_data, unsigned int id, hal_tdm_value value)
+{
+ tdm_exynos_display *display_data;
+ int ret;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data->plane_id > 0, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ display_data = layer_data->display_data;
+ ret = drmModeObjectSetProperty(display_data->drm_fd,
+ layer_data->plane_id, DRM_MODE_OBJECT_PLANE,
+ id, value.u32);
+ if (ret < 0) {
+ TDM_BACKEND_ERR("set property failed: %m");
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+tdm_exynos_layer_get_property(tdm_exynos_layer *layer_data, unsigned int id, hal_tdm_value *value)
+{
+ tdm_exynos_display *display_data;
+ drmModeObjectPropertiesPtr props;
+ hal_tdm_error ret = HAL_TDM_ERROR_INVALID_PARAMETER;
+ int i;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data->plane_id > 0, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(value, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ display_data = layer_data->display_data;
+ props = drmModeObjectGetProperties(display_data->drm_fd, layer_data->plane_id,
+ DRM_MODE_OBJECT_PLANE);
+ if (props == NULL) {
+ TDM_BACKEND_ERR("get property failed: %m");
+ return HAL_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 = HAL_TDM_ERROR_NONE;
+ break;
+ }
+
+ drmModeFreeObjectProperties(props);
+
+ if (ret != HAL_TDM_ERROR_NONE)
+ TDM_BACKEND_ERR("unknown property id: %ud", id);
+
+ return ret;
+}
+
+hal_tdm_error
+tdm_exynos_layer_set_info(tdm_exynos_layer *layer_data, tdm_exynos_layer_info *info)
+{
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(info, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ layer_data->info = *info;
+ layer_data->info_changed = 1;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+tdm_exynos_layer_get_info(tdm_exynos_layer *layer_data, tdm_exynos_layer_info *info)
+{
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(info, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ *info = layer_data->info;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+tdm_exynos_layer_set_buffer(tdm_exynos_layer *layer_data, tbm_surface_h buffer)
+{
+ tdm_exynos_display *display_data;
+ tdm_exynos_display_buffer *display_buffer;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(buffer, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ display_data = layer_data->display_data;
+
+ display_buffer = _tdm_exynos_display_get_buffer(display_data, buffer);
+ if (!display_buffer) {
+ TDM_BACKEND_ERR("alloc failed");
+ return HAL_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+tdm_exynos_layer_unset_buffer(tdm_exynos_layer *layer_data)
+{
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ if (layer_data->display_buffer &&
+ (!(layer_data->capabilities & TDM_EXYNOS_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+tdm_exynos_layer_get_supported_format(tdm_exynos_layer *layer_data, const tbm_format **out_formats,
+ int *out_format_count)
+{
+ tdm_exynos_display *display_data;
+ drmModePlanePtr plane = NULL;
+ int i, j;
+ hal_tdm_error ret;
+ tbm_format *formats = NULL;
+ int format_count = 0;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(out_formats, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(out_format_count, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ if (layer_data->formats) {
+ *out_formats = layer_data->formats;
+ *out_format_count = layer_data->format_count;
+
+ return HAL_TDM_ERROR_NONE;
+ }
+
+ display_data = layer_data->display_data;
+ plane = drmModeGetPlane(display_data->drm_fd, layer_data->plane_id);
+ if (!plane) {
+ TDM_BACKEND_ERR("get plane failed: %m");
+ ret = HAL_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 = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ TDM_BACKEND_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 HAL_TDM_ERROR_NONE;
+failed_get:
+ drmModeFreePlane(plane);
+ free(formats);
+ *out_formats = NULL;
+ *out_format_count = 0;
+ return ret;
+}
+
+hal_tdm_error
+tdm_exynos_layer_get_available_properties(tdm_exynos_layer *layer_data, const hal_tdm_prop **out_props,
+ int *out_prop_count)
+{
+ tdm_exynos_display *display_data;
+ drmModePlanePtr plane = NULL;
+ drmModeObjectPropertiesPtr props = NULL;
+ int i;
+ hal_tdm_error ret;
+ hal_tdm_prop *tdm_props = NULL;
+ int prop_count;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(out_props, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(out_prop_count, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ if (layer_data->props) {
+ *out_props = layer_data->props;
+ *out_prop_count = layer_data->prop_count;
+
+ return HAL_TDM_ERROR_NONE;
+ }
+
+ display_data = layer_data->display_data;
+ plane = drmModeGetPlane(display_data->drm_fd, layer_data->plane_id);
+ if (!plane) {
+ TDM_BACKEND_ERR("get plane failed: %m");
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ goto failed_get;
+ }
+
+ props = drmModeObjectGetProperties(display_data->drm_fd, layer_data->plane_id,
+ DRM_MODE_OBJECT_PLANE);
+ if (!props) {
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ TDM_BACKEND_ERR("get plane properties failed: %m\n");
+ goto failed_get;
+ }
+
+ tdm_props = calloc(1, sizeof(hal_tdm_prop) * props->count_props);
+ if (!tdm_props) {
+ ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ TDM_BACKEND_ERR("alloc failed\n");
+ goto failed_get;
+ }
+
+ prop_count = 0;
+ for (i = 0; i < props->count_props; i++) {
+ drmModePropertyPtr prop = drmModeGetProperty(display_data->drm_fd,
+ props->props[i]);
+ if (!prop)
+ continue;
+ if (!strncmp(prop->name, "type", HAL_TDM_NAME_LEN)) {
+ drmModeFreeProperty(prop);
+ continue;
+ }
+ if (!strncmp(prop->name, "zpos", HAL_TDM_NAME_LEN)) {
+ drmModeFreeProperty(prop);
+ continue;
+ }
+ snprintf(tdm_props[prop_count].name, HAL_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 HAL_TDM_ERROR_NONE;
+failed_get:
+ drmModeFreeObjectProperties(props);
+ drmModeFreePlane(plane);
+ *out_props = NULL;
+ *out_prop_count = 0;
+
+ return ret;
+}
--- /dev/null
+/**************************************************************************
+
+libtdm_exynos
+
+Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_backend_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 hal_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 HAL_TDM_ERROR_INVALID_PARAMETER;
+ return HAL_TDM_ERROR_NONE;
+}
+
+static hal_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_BACKEND_ERR("buf_w(%u) not 2's multiple or less than %u", buf_w, MIN_WIDTH);
+ return HAL_TDM_ERROR_BAD_REQUEST;
+ }
+
+ if (dst_x > crtc_w || dst_y > crtc_h) {
+ TDM_BACKEND_ERR("dst_pos(%u,%u) is out of crtc(%ux%u)", dst_x, dst_y, crtc_w, crtc_h);
+ return HAL_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_BACKEND_ERR("visible_w(%d) less than %u", end - start, MIN_WIDTH);
+ return HAL_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;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(*new_src_w > 0, HAL_TDM_ERROR_BAD_REQUEST);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(*new_dst_w > 0, HAL_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_BACKEND_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 HAL_TDM_ERROR_NONE;
+}
+
+static drmModeModeInfoPtr
+_tdm_exynos_output_get_mode(tdm_exynos_output *output_data)
+{
+ int i;
+
+ if (!output_data->current_mode) {
+ TDM_BACKEND_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, HAL_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, HAL_TDM_NAME_LEN)))
+ return drm_mode;
+ }
+ }
+
+ return NULL;
+}
+
+static hal_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_BACKEND_ERR("get vblank counter failed: %m");
+ *msc = 0;
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ *msc = vbl.reply.sequence;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+static hal_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_BACKEND_ERR("wait vblank failed: %m");
+ *target_msc = 0;
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ *target_msc = vbl.reply.sequence;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+static void
+_tdm_exynos_output_transform_layer_info(int width, int height, tdm_exynos_layer_info *info)
+{
+ hal_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 hal_tdm_error
+_tdm_exynos_output_commit_primary_layer(tdm_exynos_layer *layer_data,
+ void *user_data, int *do_waitvblank)
+{
+ tdm_exynos_display *display_data = layer_data->display_data;
+ tdm_exynos_output *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_exynos_layer_info layer_info = layer_data->info;
+ drmModeModeInfoPtr mode;
+
+ if (!layer_data->display_buffer) {
+ TDM_BACKEND_ERR("primary layer_data should have a buffer for modestting");
+ return HAL_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(display_data->drm_fd, output_data->crtc_id);
+ if (!crtc) {
+ TDM_BACKEND_ERR("getting crtc failed");
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+ crtc_w = crtc->width;
+ crtc_h = crtc->height;
+ if (crtc_w == 0) {
+ TDM_BACKEND_ERR("getting crtc width failed");
+ drmModeFreeCrtc(crtc);
+ return HAL_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_BACKEND_ERR("couldn't find proper mode");
+ return HAL_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) != HAL_TDM_ERROR_NONE)
+ TDM_BACKEND_WRN("not going to set crtc(%u)", output_data->crtc_id);
+
+ if (layer_info.src_config.pos.x != new_x)
+ TDM_BACKEND_DBG("src_x changed: %u => %u", layer_info.src_config.pos.x,
+ new_x);
+ if (layer_info.src_config.pos.y != new_y)
+ TDM_BACKEND_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_BACKEND_DBG("SetCrtc: drm_fd(%d) crtc_id(%u) fb_id(%u) mode(%ux%u, %uhz) pos(%u %u)",
+ display_data->drm_fd, output_data->crtc_id, layer_data->display_buffer->fb_id,
+ mode->hdisplay, mode->vdisplay, mode->vrefresh, fx, fy);
+
+ if (drmModeSetCrtc(display_data->drm_fd, output_data->crtc_id,
+ layer_data->display_buffer->fb_id, fx, fy,
+ &output_data->connector_id, 1, mode)) {
+ TDM_BACKEND_ERR("set crtc failed: %m");
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ tdm_exynos_output_update_status(output_data, HAL_TDM_OUTPUT_CONN_STATUS_MODE_SETTED);
+
+ *do_waitvblank = 1;
+
+ return HAL_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 *event_data = calloc(1, sizeof(tdm_exynos_event));
+
+ if (!event_data) {
+ TDM_BACKEND_ERR("alloc failed");
+ return HAL_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;
+
+ TDM_BACKEND_DBG("PageFlip: drm_fd(%d) crtc_id(%u) fb_id(%u)",
+ display_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(display_data->drm_fd, output_data->crtc_id,
+ layer_data->display_buffer->fb_id, DRM_MODE_PAGE_FLIP_EVENT, event_data)) {
+ TDM_BACKEND_ERR("pageflip failed: %m");
+ free(event_data);
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+ *do_waitvblank = 0;
+ } else {
+ /* to call a user commit handler whenever committed */
+ *do_waitvblank = 1;
+ }
+ }
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+static hal_tdm_error
+_tdm_exynos_output_commit_layer(tdm_exynos_layer *layer_data)
+{
+ tdm_exynos_display *display_data = layer_data->display_data;
+ tdm_exynos_output *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_exynos_layer_info layer_info = layer_data->info;
+
+ if (!layer_data->display_buffer_changed && !layer_data->info_changed)
+ return HAL_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(display_data->drm_fd, output_data->crtc_id);
+ if (!crtc) {
+ TDM_BACKEND_ERR("getting crtc failed");
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+ crtc_w = crtc->width;
+ crtc_h = crtc->height;
+ if (crtc_w == 0) {
+ TDM_BACKEND_ERR("getting crtc width failed");
+ drmModeFreeCrtc(crtc);
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+ drmModeFreeCrtc(crtc);
+ }
+
+ layer_data->display_buffer_changed = 0;
+ layer_data->info_changed = 0;
+
+ if (!layer_data->display_buffer) {
+ TDM_BACKEND_DBG("SetPlane: drm_fd(%d) plane_id(%u) crtc_id(%u) off",
+ display_data->drm_fd, layer_data->plane_id, output_data->crtc_id);
+
+ if (drmModeSetPlane(display_data->drm_fd, layer_data->plane_id,
+ output_data->crtc_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
+ TDM_BACKEND_ERR("unset plane(%u) filed: %m", layer_data->plane_id);
+
+ return HAL_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) != HAL_TDM_ERROR_NONE) {
+ TDM_BACKEND_WRN("not going to set plane(%u)", layer_data->plane_id);
+ return HAL_TDM_ERROR_NONE;
+ }
+
+ if (layer_info.src_config.pos.x != new_src_x)
+ TDM_BACKEND_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_BACKEND_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_BACKEND_DBG("dst_x changed: %u => %u", layer_info.dst_pos.x, new_dst_x);
+ if (layer_info.dst_pos.w != new_dst_w)
+ TDM_BACKEND_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_BACKEND_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)",
+ display_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(display_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_BACKEND_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",
+ display_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 HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ return HAL_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 *event_data = user_data;
+ tdm_exynos_output *output_data;
+ tdm_exynos_hwc *hwc_data;
+
+ if (!event_data) {
+ TDM_BACKEND_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 (hwc_data->commit_func)
+ hwc_data->commit_func(hwc_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);
+}
+
+hal_tdm_error
+tdm_exynos_output_update_status(tdm_exynos_output *output_data,
+ hal_tdm_output_conn_status status)
+{
+ tdm_exynos_layer *layer_data = NULL;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ if (output_data->status == status)
+ return HAL_TDM_ERROR_NONE;
+
+ output_data->status = status;
+
+ LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+ if (status == HAL_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_output_get_capability(hal_tdm_output *output, hal_tdm_caps_output *caps)
+{
+ tdm_exynos_output *output_data = output;
+ tdm_exynos_display *display_data;
+ drmModeConnectorPtr connector = NULL;
+ drmModeCrtcPtr crtc = NULL;
+ drmModeObjectPropertiesPtr props = NULL;
+ int i;
+ hal_tdm_error ret;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(caps, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ memset(caps, 0, sizeof(hal_tdm_caps_output));
+
+ display_data = output_data->display_data;
+
+ snprintf(caps->maker, HAL_TDM_NAME_LEN, "unknown");
+ snprintf(caps->model, HAL_TDM_NAME_LEN, "unknown");
+ snprintf(caps->name, HAL_TDM_NAME_LEN, "unknown");
+
+ caps->type = output_data->connector_type;
+ caps->type_id = output_data->connector_type_id;
+
+ connector = drmModeGetConnector(display_data->drm_fd, output_data->connector_id);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(connector, HAL_TDM_ERROR_OPERATION_FAILED);
+
+ caps->mode_count = connector->count_modes;
+ caps->modes = calloc(1, sizeof(hal_tdm_output_mode) * caps->mode_count);
+ if (!caps->modes) {
+ ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ TDM_BACKEND_ERR("alloc failed\n");
+ goto failed_get;
+ }
+ if (caps->mode_count != output_data->count_modes) {
+ drmModeModeInfoPtr new_drm_modes;
+ hal_tdm_output_mode *new_output_modes;
+
+ new_drm_modes = calloc(connector->count_modes,
+ sizeof(drmModeModeInfo));
+ if (!new_drm_modes) {
+ ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ TDM_BACKEND_ERR("alloc failed drm_modes\n");
+ goto failed_get;
+ }
+ new_output_modes = calloc(connector->count_modes,
+ sizeof(hal_tdm_output_mode));
+ if (!new_output_modes) {
+ ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ TDM_BACKEND_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 = HAL_TDM_OUTPUT_CONN_STATUS_CONNECTED;
+ else
+ output_data->status = HAL_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 = display_data->mode_res->min_height;
+ caps->min_h = display_data->mode_res->min_width;
+ caps->max_w = display_data->mode_res->max_height;
+ caps->max_h = display_data->mode_res->max_width;
+ } else {
+ caps->mmWidth = connector->mmWidth;
+ caps->mmHeight = connector->mmHeight;
+ caps->min_w = display_data->mode_res->min_width;
+ caps->min_h = display_data->mode_res->min_height;
+ caps->max_w = display_data->mode_res->max_width;
+ caps->max_h = display_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(display_data->drm_fd, output_data->crtc_id);
+ if (!crtc) {
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ TDM_BACKEND_ERR("get crtc failed: %m\n");
+ goto failed_get;
+ }
+
+ props = drmModeObjectGetProperties(display_data->drm_fd, output_data->crtc_id,
+ DRM_MODE_OBJECT_CRTC);
+ if (!props) {
+ ret = HAL_TDM_ERROR_OPERATION_FAILED;
+ TDM_BACKEND_ERR("get crtc properties failed: %m\n");
+ goto failed_get;
+ }
+
+ caps->props = calloc(1, sizeof(hal_tdm_prop) * props->count_props);
+ if (!caps->props) {
+ ret = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ TDM_BACKEND_ERR("alloc failed\n");
+ goto failed_get;
+ }
+
+ caps->prop_count = 0;
+ for (i = 0; i < props->count_props; i++) {
+ drmModePropertyPtr prop = drmModeGetProperty(display_data->drm_fd,
+ props->props[i]);
+ if (!prop)
+ continue;
+ snprintf(caps->props[caps->prop_count].name, HAL_TDM_NAME_LEN, "%s", prop->name);
+ caps->props[caps->prop_count].id = props->props[i];
+ caps->prop_count++;
+ drmModeFreeProperty(prop);
+ }
+
+ caps->capabilities |= HAL_TDM_OUTPUT_CAPABILITY_HWC;
+
+ drmModeFreeObjectProperties(props);
+ drmModeFreeCrtc(crtc);
+ drmModeFreeConnector(connector);
+
+ return HAL_TDM_ERROR_NONE;
+failed_get:
+ drmModeFreeCrtc(crtc);
+ drmModeFreeObjectProperties(props);
+ drmModeFreeConnector(connector);
+ free(caps->modes);
+ free(caps->props);
+ memset(caps, 0, sizeof(hal_tdm_caps_output));
+ return ret;
+}
+
+hal_tdm_error
+exynos_output_set_property(hal_tdm_output *output, unsigned int id, hal_tdm_value value)
+{
+ tdm_exynos_output *output_data = output;
+ tdm_exynos_display *display_data;
+ int ret;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data->crtc_id > 0, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ display_data = output_data->display_data;
+ ret = drmModeObjectSetProperty(display_data->drm_fd,
+ output_data->crtc_id, DRM_MODE_OBJECT_CRTC,
+ id, value.u32);
+ if (ret < 0) {
+ TDM_BACKEND_ERR("set property failed: %m");
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_output_get_property(hal_tdm_output *output, unsigned int id,
+ hal_tdm_value *value)
+{
+ tdm_exynos_output *output_data = output;
+ tdm_exynos_display *display_data;
+ drmModeObjectPropertiesPtr props;
+ int i;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data->crtc_id > 0, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(value, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ display_data = output_data->display_data;
+ props = drmModeObjectGetProperties(display_data->drm_fd, output_data->crtc_id,
+ DRM_MODE_OBJECT_CRTC);
+ if (props == NULL) {
+ TDM_BACKEND_ERR("get property failed: %m");
+ return HAL_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_output_wait_vblank(hal_tdm_output *output, int interval, int sync,
+ void *user_data)
+{
+ tdm_exynos_output *output_data = output;
+ tdm_exynos_display *display_data;
+ tdm_exynos_event *event_data;
+ uint target_msc;
+ hal_tdm_error ret;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ event_data = calloc(1, sizeof(tdm_exynos_event));
+ if (!event_data) {
+ TDM_BACKEND_ERR("alloc failed");
+ return HAL_TDM_ERROR_OUT_OF_MEMORY;
+ }
+
+ display_data = output_data->display_data;
+
+ ret = _tdm_exynos_output_get_cur_msc(display_data->drm_fd, output_data->pipe,
+ &target_msc);
+ if (ret != HAL_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(display_data->drm_fd, output_data->pipe,
+ &target_msc, event_data);
+ if (ret != HAL_TDM_ERROR_NONE)
+ goto failed_vblank;
+
+ return HAL_TDM_ERROR_NONE;
+failed_vblank:
+ free(event_data);
+ return ret;
+}
+
+hal_tdm_error
+exynos_output_set_vblank_handler(hal_tdm_output *output,
+ hal_tdm_output_vblank_handler func)
+{
+ tdm_exynos_output *output_data = output;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ output_data->vblank_func = func;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_output_commit(hal_tdm_output *output, int sync, void *user_data)
+{
+ tdm_exynos_output *output_data = output;
+ tdm_exynos_display *display_data;
+ tdm_exynos_layer *layer_data = NULL;
+ hal_tdm_error ret;
+ int do_waitvblank = 1;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ display_data = output_data->display_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 != HAL_TDM_ERROR_NONE)
+ return ret;
+ } else {
+ ret = _tdm_exynos_output_commit_layer(layer_data);
+ if (ret != HAL_TDM_ERROR_NONE)
+ return ret;
+ }
+ }
+
+ if (do_waitvblank == 1) {
+ tdm_exynos_event *event_data = calloc(1, sizeof(tdm_exynos_event));
+ uint target_msc;
+
+ if (!event_data) {
+ TDM_BACKEND_ERR("alloc failed");
+ return HAL_TDM_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = _tdm_exynos_output_get_cur_msc(display_data->drm_fd, output_data->pipe,
+ &target_msc);
+ if (ret != HAL_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;
+
+ ret = _tdm_exynos_output_wait_vblank(display_data->drm_fd, output_data->pipe,
+ &target_msc, event_data);
+ if (ret != HAL_TDM_ERROR_NONE) {
+ free(event_data);
+ return ret;
+ }
+ }
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_output_set_commit_handler(hal_tdm_output *output,
+ hal_tdm_output_commit_handler func)
+{
+ tdm_exynos_output *output_data = output;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ output_data->commit_func = func;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_output_set_dpms(hal_tdm_output *output, hal_tdm_output_dpms dpms_value)
+{
+ tdm_exynos_output *output_data = output;
+ tdm_exynos_display *display_data;
+ int ret;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ display_data = output_data->display_data;
+ ret = drmModeObjectSetProperty(display_data->drm_fd,
+ output_data->connector_id, DRM_MODE_OBJECT_CONNECTOR,
+ output_data->dpms_prop_id, dpms_value);
+ if (ret < 0) {
+ TDM_BACKEND_ERR("set dpms failed: %m");
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_output_get_dpms(hal_tdm_output *output, hal_tdm_output_dpms *dpms_value)
+{
+ tdm_exynos_output *output_data = output;
+ tdm_exynos_display *display_data;
+ drmModeObjectPropertiesPtr props;
+ int i;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(dpms_value, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ display_data = output_data->display_data;
+ props = drmModeObjectGetProperties(display_data->drm_fd,
+ output_data->connector_id, DRM_MODE_OBJECT_CONNECTOR);
+ if (props == NULL) {
+ TDM_BACKEND_ERR("get property failed: %m");
+ return HAL_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_output_set_mode(hal_tdm_output *output, const hal_tdm_output_mode *mode)
+{
+ tdm_exynos_output *output_data = output;
+ hal_tdm_error ret = HAL_TDM_ERROR_NONE;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(mode, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ /* create or replace the target_window when the output mode is set */
+ ret = exynos_hwc_initailize_target_window(output_data->hwc_data, mode->hdisplay, mode->vdisplay);
+ if (ret != HAL_TDM_ERROR_NONE) {
+ TDM_BACKEND_ERR("create target hwc window failed (%d)", ret);
+ return ret;
+ }
+
+ output_data->current_mode = mode;
+ output_data->mode_changed = 1;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_output_get_mode(hal_tdm_output *output, const hal_tdm_output_mode **mode)
+{
+ tdm_exynos_output *output_data = output;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(mode, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ *mode = output_data->current_mode;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_capture*
+exynos_output_create_capture(hal_tdm_output *output, hal_tdm_error *error)
+{
+ tdm_exynos_output *output_data = output;
+ tdm_exynos_display *display_data;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, NULL);
+
+ display_data = output_data->display_data;
+
+ if (display_data->use_ippv2)
+ return tdm_exynos_capture_create_output(display_data, output, error);
+ else
+ return tdm_exynos_capture_legacy_create_output(display_data, output, error);
+}
+
+hal_tdm_error
+exynos_output_set_status_handler(hal_tdm_output *output,
+ hal_tdm_output_status_handler func,
+ void *user_data)
+{
+ tdm_exynos_output *output_data = output;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ output_data->status_func = func;
+ output_data->status_user_data = user_data;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_hwc *
+exynos_output_get_hwc(hal_tdm_output *output, hal_tdm_error *error)
+{
+ tdm_exynos_hwc *hwc_data = NULL;
+ tdm_exynos_output *output_data = output;
+
+ if (!output_data) {
+ TDM_BACKEND_ERR("invalid params");
+ if (error)
+ *error = HAL_TDM_ERROR_INVALID_PARAMETER;
+ return NULL;
+ }
+
+ if (output_data->hwc_data) {
+ TDM_BACKEND_INFO("hwc_data already exists");
+ if (error)
+ *error = HAL_TDM_ERROR_NONE;
+ return output_data->hwc_data;
+ }
+
+ hwc_data = calloc(1, sizeof(tdm_exynos_hwc));
+ if (!hwc_data) {
+ TDM_BACKEND_ERR("alloc failed");
+ if (error)
+ *error = HAL_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 = HAL_TDM_ERROR_NONE;
+
+ return hwc_data;
+}
--- /dev/null
+/**************************************************************************
+
+libtdm_exynos
+
+Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_backend_exynos.h"
+
+typedef struct _tdm_exynos_pp_data {
+ tdm_exynos_display *display_data;
+
+ hal_tdm_info_pp info;
+
+ struct list_head pending_buffer_list;
+ struct list_head buffer_list;
+
+ hal_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 hal_tdm_transform_to_drm(hal_tdm_transform t)
+{
+ switch (t) {
+ case HAL_TDM_TRANSFORM_NORMAL:
+ return DRM_MODE_ROTATE_0;
+ case HAL_TDM_TRANSFORM_90:
+ return DRM_MODE_ROTATE_90;
+ case HAL_TDM_TRANSFORM_180:
+ return DRM_MODE_ROTATE_180;
+ case HAL_TDM_TRANSFORM_270:
+ return DRM_MODE_ROTATE_270;
+ case HAL_TDM_TRANSFORM_FLIPPED:
+ return DRM_MODE_REFLECT_Y;
+ case HAL_TDM_TRANSFORM_FLIPPED_90:
+ return DRM_MODE_REFLECT_Y | DRM_MODE_ROTATE_90;
+ case HAL_TDM_TRANSFORM_FLIPPED_180:
+ return DRM_MODE_REFLECT_Y | DRM_MODE_ROTATE_180;
+ case HAL_TDM_TRANSFORM_FLIPPED_270:
+ return DRM_MODE_REFLECT_Y | DRM_MODE_ROTATE_270;
+ }
+ return 0;
+}
+
+static hal_tdm_error
+_tdm_exynos_pp_process(tdm_exynos_pp_data *pp_data, tdm_exynos_pp_buffer *buffer)
+{
+ tdm_exynos_display *display_data = pp_data->display_data;
+ hal_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 = hal_tdm_transform_to_drm(info->transform);
+
+ CLEAR(arg);
+ arg.flags = DRM_EXYNOS_IPP_FLAG_EVENT | DRM_EXYNOS_IPP_FLAG_NONBLOCK;
+ arg.ipp_id = display_data->ipp_module_id;
+ arg.params_size = sizeof(task);
+ arg.params_ptr = (unsigned long)(&task);
+ arg.user_data = (__u64)(uintptr_t)buffer;
+
+ ret = ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_COMMIT, &arg);
+ if (ret) {
+ TDM_BACKEND_ERR("ipp commit failed. %xx pp_data(%p), buffer(%p). %m", DRM_IOCTL_EXYNOS_IPP_COMMIT, pp_data, buffer);
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ return HAL_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_BACKEND_ERR("invalid params");
+ return;
+ }
+
+ if (!pp_list_init)
+ return;
+
+ pp_data = dequeued_buffer->pp_data;
+
+ TDM_BACKEND_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_BACKEND_DBG("dequeued: %p", dequeued_buffer);
+ break;
+ }
+ }
+
+ if (!pp_data->first_event) {
+ TDM_BACKEND_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;
+
+hal_tdm_error
+tdm_exynos_pp_init(tdm_exynos_display *display_data)
+{
+ struct drm_exynos_ioctl_ipp_get_caps caps_arg;
+ struct drm_exynos_ioctl_ipp_get_res res_arg;
+ uint32_t *ipps;
+ int i;
+
+ display_data->ipp_module_id = -1;
+
+ CLEAR(res_arg);
+ if (ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_RESOURCES,
+ &res_arg)) {
+ TDM_BACKEND_ERR("failed to get Exynos IPP resources");
+ return HAL_TDM_ERROR_NO_CAPABILITY;
+ }
+
+ ipps = calloc(res_arg.count_ipps, sizeof(*ipps));
+ if (!ipps) {
+ TDM_BACKEND_ERR("alloc failed");
+ return HAL_TDM_ERROR_OUT_OF_MEMORY;
+ }
+
+ res_arg.ipp_id_ptr = (unsigned long)ipps;
+ if (ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_RESOURCES,
+ &res_arg)) {
+ TDM_BACKEND_ERR("failed to get Exynos IPP resources");
+ free(ipps);
+ return HAL_TDM_ERROR_NO_CAPABILITY;
+ }
+
+ for (i = 0; i < res_arg.count_ipps; i++) {
+ CLEAR(caps_arg);
+ caps_arg.ipp_id = ipps[i];
+ if (ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_CAPS,
+ &caps_arg)) {
+ TDM_BACKEND_ERR("failed to get IPP capabilities");
+ free(ipps);
+ return HAL_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 HAL_TDM_ERROR_NO_CAPABILITY;
+ }
+
+ TDM_BACKEND_INFO("selected Exynos IPP module id %d", ipps[i]);
+ display_data->ipp_module_id = ipps[i];
+ free(ipps);
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+tdm_exynos_pp_get_capability(tdm_exynos_display *display_data, hal_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_BACKEND_ERR("invalid params");
+ return HAL_TDM_ERROR_INVALID_PARAMETER;
+ }
+
+ CLEAR(caps_arg);
+ caps_arg.ipp_id = display_data->ipp_module_id;
+ if (ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_CAPS,
+ &caps_arg)) {
+ TDM_BACKEND_ERR("failed to get IPP capabilities");
+ return HAL_TDM_ERROR_NO_CAPABILITY;
+ }
+
+ formats = calloc(caps_arg.formats_count, sizeof(*formats));
+ if (!formats) {
+ TDM_BACKEND_ERR("alloc failed");
+ return HAL_TDM_ERROR_OUT_OF_MEMORY;
+ }
+
+ caps_arg.formats_ptr = (unsigned long) formats;
+ if (ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_GET_CAPS,
+ &caps_arg)) {
+ TDM_BACKEND_ERR("failed to get IPP capabilities");
+ free(formats);
+ return HAL_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 = HAL_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_BACKEND_ERR("alloc failed");
+ free(formats);
+ return HAL_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_pp *
+tdm_exynos_pp_create(tdm_exynos_display *display_data, hal_tdm_error *error)
+{
+ tdm_exynos_pp_data *pp_data = calloc(1, sizeof(tdm_exynos_pp_data));
+ if (!pp_data) {
+ TDM_BACKEND_ERR("alloc failed");
+ if (error)
+ *error = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ pp_data->display_data = display_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(hal_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);
+}
+
+hal_tdm_error
+exynos_pp_set_info(hal_tdm_pp *pp, hal_tdm_info_pp *info)
+{
+ tdm_exynos_pp_data *pp_data = pp;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(info, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ if (info->sync) {
+ TDM_BACKEND_ERR("not support sync mode currently");
+ return HAL_TDM_ERROR_INVALID_PARAMETER;
+ }
+
+ pp_data->info = *info;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_pp_attach(hal_tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst)
+{
+ tdm_exynos_pp_data *pp_data = pp;
+ tdm_exynos_pp_buffer *buffer;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(src, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(dst, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ buffer = calloc(1, sizeof(tdm_exynos_pp_buffer));
+ if (!buffer) {
+ TDM_BACKEND_ERR("alloc failed");
+ return HAL_TDM_ERROR_NONE;
+ }
+
+ LIST_ADDTAIL(&buffer->link, &pp_data->pending_buffer_list);
+ buffer->src = src;
+ buffer->dst = dst;
+ buffer->pp_data = pp_data;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_pp_commit(hal_tdm_pp *pp)
+{
+ tdm_exynos_pp_data *pp_data = pp;
+ tdm_exynos_pp_buffer *b = NULL, *bb = NULL;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_pp_set_done_handler(hal_tdm_pp *pp, hal_tdm_pp_done_handler func,
+ void *user_data)
+{
+ tdm_exynos_pp_data *pp_data = pp;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ pp_data->done_func = func;
+ pp_data->done_user_data = user_data;
+
+ return HAL_TDM_ERROR_NONE;
+}
--- /dev/null
+/**************************************************************************
+
+libtdm_exynos
+
+Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_backend_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_display *display_data;
+
+ unsigned int prop_id;
+
+ hal_tdm_info_pp info;
+ int info_changed;
+
+ struct list_head pending_buffer_list;
+ struct list_head buffer_list;
+
+ hal_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 hal_tdm_error
+_tdm_exynos_pp_legacy_set(tdm_exynos_pp_legacy_data *pp_data)
+{
+ tdm_exynos_display *display_data = pp_data->display_data;
+ hal_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(hal_tdm_size));
+ memcpy(&property.config[0].pos, &info->src_config.pos, sizeof(hal_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(hal_tdm_size));
+ memcpy(&property.config[1].pos, &info->dst_config.pos, sizeof(hal_tdm_pos));
+ property.cmd = IPP_CMD_M2M;
+ property.prop_id = pp_data->prop_id;
+
+ TDM_BACKEND_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_BACKEND_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(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_SET_PROPERTY, &property);
+ if (ret) {
+ TDM_BACKEND_ERR("failed: %m");
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ TDM_BACKEND_DBG("success. prop_id(%d) ", property.prop_id);
+ pp_data->prop_id = property.prop_id;
+ return HAL_TDM_ERROR_NONE;
+}
+
+static hal_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_display *display_data = pp_data->display_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_BACKEND_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(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
+ if (ret) {
+ TDM_BACKEND_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 HAL_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_BACKEND_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(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, &buf);
+ if (ret) {
+ TDM_BACKEND_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 HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ TDM_BACKEND_DBG("success. prop_id(%d)", buf.prop_id);
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+static hal_tdm_error
+_tdm_exynos_pp_legacy_cmd(tdm_exynos_pp_legacy_data *pp_data, enum drm_exynos_ipp_ctrl cmd)
+{
+ tdm_exynos_display *display_data = pp_data->display_data;
+ struct drm_exynos_ipp_cmd_ctrl ctrl;
+ int ret = 0;
+
+ ctrl.prop_id = pp_data->prop_id;
+ ctrl.ctrl = cmd;
+
+ TDM_BACKEND_DBG("prop_id(%d) ctrl(%d). ", ctrl.prop_id, ctrl.ctrl);
+
+ ret = ioctl(display_data->drm_fd, DRM_IOCTL_EXYNOS_IPP_CMD_CTRL, &ctrl);
+ if (ret) {
+ TDM_BACKEND_ERR("failed. prop_id(%d) ctrl(%d). %m", ctrl.prop_id, ctrl.ctrl);
+ return HAL_TDM_ERROR_OPERATION_FAILED;
+ }
+
+ TDM_BACKEND_DBG("success. prop_id(%d) ", ctrl.prop_id);
+
+ return HAL_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_BACKEND_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_BACKEND_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_BACKEND_DBG("dequeued: %d", dequeued_buffer->index);
+ break;
+ }
+ }
+
+ if (!dequeued_buffer) {
+ TDM_BACKEND_ERR("not found buffer index: %d", buf_idx[0]);
+ return;
+ }
+
+ if (!pp_data->first_event) {
+ TDM_BACKEND_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);
+}
+
+hal_tdm_error
+tdm_exynos_pp_legacy_get_capability(tdm_exynos_display *display_data, hal_tdm_caps_pp *caps)
+{
+ int i;
+
+ if (!caps) {
+ TDM_BACKEND_ERR("invalid params");
+ return HAL_TDM_ERROR_INVALID_PARAMETER;
+ }
+
+ caps->capabilities = HAL_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_BACKEND_ERR("alloc failed");
+ return HAL_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_pp *
+tdm_exynos_pp_legacy_create(tdm_exynos_display *display_data, hal_tdm_error *error)
+{
+ tdm_exynos_pp_legacy_data *pp_data = calloc(1, sizeof(tdm_exynos_pp_legacy_data));
+ if (!pp_data) {
+ TDM_BACKEND_ERR("alloc failed");
+ if (error)
+ *error = HAL_TDM_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ pp_data->display_data = display_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(hal_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);
+}
+
+hal_tdm_error
+exynos_pp_legacy_set_info(hal_tdm_pp *pp, hal_tdm_info_pp *info)
+{
+ tdm_exynos_pp_legacy_data *pp_data = pp;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(info, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ if (info->sync) {
+ TDM_BACKEND_ERR("not support sync mode currently");
+ return HAL_TDM_ERROR_INVALID_PARAMETER;
+ }
+
+ pp_data->info = *info;
+ pp_data->info_changed = 1;
+
+ return HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_pp_legacy_attach(hal_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;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(src, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(dst, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ buffer = calloc(1, sizeof(tdm_exynos_pp_legacy_buffer));
+ if (!buffer) {
+ TDM_BACKEND_ERR("alloc failed");
+ return HAL_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_pp_legacy_commit(hal_tdm_pp *pp)
+{
+ tdm_exynos_pp_legacy_data *pp_data = pp;
+ tdm_exynos_pp_legacy_buffer *b = NULL, *bb = NULL;
+ hal_tdm_error ret;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_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 HAL_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_BACKEND_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 HAL_TDM_ERROR_NONE;
+}
+
+hal_tdm_error
+exynos_pp_legacy_set_done_handler(hal_tdm_pp *pp, hal_tdm_pp_done_handler func,
+ void *user_data)
+{
+ tdm_exynos_pp_legacy_data *pp_data = pp;
+
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(pp_data, HAL_TDM_ERROR_INVALID_PARAMETER);
+ TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER);
+
+ pp_data->done_func = func;
+ pp_data->done_user_data = user_data;
+
+ return HAL_TDM_ERROR_NONE;
+}