From: Changyeon Lee Date: Wed, 22 Jun 2022 09:02:17 +0000 (+0900) Subject: remove legacy libtdm backend X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Ftizen;p=platform%2Fadaptation%2Flibtdm-fbdev.git remove legacy libtdm backend Change-Id: I30d998ecfbacf71836cbe5721a44815d602d4693 --- diff --git a/configure.ac b/configure.ac index ec56a4d..2b5d524 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ AC_PREREQ([2.60]) -AC_INIT([libtdm-fbdev], +AC_INIT([hal-backend-tdm-fbdev], [1.0.0], [https://www.tizen.org], - [libtdm-fbdev]) + [hal-backend-tdm-fbdev]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([Makefile.am]) @@ -23,23 +23,16 @@ LT_INIT([disable-static]) # Enable quiet compiles on automake 1.11. m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -PKG_CHECK_MODULES(TDM_DRM, libtdm libtbm libdrm) - PKG_CHECK_MODULES(LIBHAL_BACKEND_TDM_FBDEV, hal-api-common hal-api-tdm hal-api-tbm libdrm dlog) PKG_CHECK_MODULES(UDEV, libudev, [udev=yes], [udev=no]) if test x"$udev" = xyes; then AC_DEFINE(HAVE_UDEV,1,[Enable udev-based monitor hotplug detection]) - TDM_DRM_CFLAGS="$TDM_DRM_CFLAGS $UDEV_CFLAGS" - TDM_DRM_LIBS="$TDM_DRM_LIBS $UDEV_LIBS" LIBHAL_BACKEND_TDM_FBDEV_CFLAGS="$LIBHAL_BACKEND_TDM_FBDEV_CFLAGS $UDEV_CFLAGS" LIBHAL_BACKEND_TDM_FBDEV_LIBS="$LIBHAL_BACKEND_TDM_FBDEV_LIBS $UDEV_LIBS" fi -AC_SUBST(TDM_DRM_CFLAGS) -AC_SUBST(TDM_DRM_LIBS) - AC_SUBST(LIBHAL_BACKEND_TDM_FBDEV_CFLAGS) AC_SUBST(LIBHAL_BACKEND_TDM_FBDEV_LIBS) @@ -50,13 +43,6 @@ AC_DEFINE_UNQUOTED(LIBDRM_MIROR_VERSION, [`pkg-config --modversion libdrm | cut AC_DEFINE_UNQUOTED(LIBDRM_MICRO_VERSION, [`pkg-config --modversion libdrm | cut -d '.' -f 3`], dnl [libdrm major version]) -# 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]), @@ -65,25 +51,15 @@ AC_ARG_WITH(hal-libdir, AS_HELP_STRING([--with-hal-libdir=PATH], [hal backend li AC_DEFINE_UNQUOTED(HAL_LIBDIR, "${HAL_LIBDIR}", [Directory for hal backend library path]) AC_SUBST(HAL_LIBDIR) - # For enumerating devices in test case AC_OUTPUT([ Makefile - src/libhal-backend-tdm-fbdev/Makefile - src/libtdm-fbdev/Makefile src/Makefile]) echo "" echo "$PACKAGE_STRING will be compiled with:" echo "" -echo "TDM_DRM_CFLAGS : $LIBHAL_BACKEND_TDM_FBDEV_CFLAGS" -echo "TDM_DRM_LIBS : $LIBHAL_BACKEND_TDM_FBDEV_LIBS" -echo "TDM_MODULE_DIR : $HAL_LIBDIR" -echo "" -echo "" -echo "$PACKAGE_STRING will be compiled with:" -echo "" -echo "TDM_DRM_CFLAGS : $TDM_DRM_CFLAGS" -echo "TDM_DRM_LIBS : $TDM_DRM_LIBS" -echo "TDM_MODULE_DIR : $TDM_MODULE_PATH" +echo "LIBHAL_BACKEND_TDM_FBDEV_CFLAGS : $LIBHAL_BACKEND_TDM_FBDEV_CFLAGS" +echo "LIBHAL_BACKEND_TDM_FBDEV_LIBS : $LIBHAL_BACKEND_TDM_FBDEV_LIBS" +echo "HAL_LIBDIR : $HAL_LIBDIR" echo "" diff --git a/packaging/hal-backend-tdm-fbdev.manifest b/packaging/hal-backend-tdm-fbdev.manifest new file mode 100644 index 0000000..75b0fa5 --- /dev/null +++ b/packaging/hal-backend-tdm-fbdev.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/hal-backend-tdm-fbdev.spec b/packaging/hal-backend-tdm-fbdev.spec new file mode 100644 index 0000000..cb837bc --- /dev/null +++ b/packaging/hal-backend-tdm-fbdev.spec @@ -0,0 +1,53 @@ +Name: hal-backend-tdm-fbdev +Version: 2.0.0 +Release: 0 +Summary: hal-backend-tdm module for fbdev +Group: System/Libraries +License: MIT +Source0: %{name}-%{version}.tar.gz +Source1001: %{name}.manifest + +BuildRequires: pkgconfig(libdrm) +BuildRequires: pkgconfig(libudev) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(libtbm) +BuildRequires: pkgconfig(hal-api-common) +BuildRequires: pkgconfig(hal-api-tdm) +BuildRequires: pkgconfig(hal-api-tbm) + +%description +description: hal tdm backend module for fbdev + +%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} \ + 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-fbdev +cp -af COPYING %{buildroot}%{_hal_licensedir}/libhal-backend-tdm-fbdev + +%post +if [ -f %{_hal_libdir}/libhal-backend-tdm.so ]; then + rm -rf %{_hal_libdir}/libhal-backend-tdm.so +fi +ln -s libhal-backend-tdm-fbdev.so %{_hal_libdir}/libhal-backend-tdm.so + +%postun -p /sbin/ldconfig + +%files +%manifest %{name}.manifest +%{_hal_licensedir}/libhal-backend-tdm-fbdev/COPYING +%{_hal_libdir}/libhal-backend-*.so* diff --git a/packaging/libhal-backend-tdm-fbdev.manifest b/packaging/libhal-backend-tdm-fbdev.manifest deleted file mode 100644 index 75b0fa5..0000000 --- a/packaging/libhal-backend-tdm-fbdev.manifest +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/packaging/libtdm-fbdev.manifest b/packaging/libtdm-fbdev.manifest deleted file mode 100644 index 75b0fa5..0000000 --- a/packaging/libtdm-fbdev.manifest +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/packaging/libtdm-fbdev.spec b/packaging/libtdm-fbdev.spec deleted file mode 100644 index 6dcc8ed..0000000 --- a/packaging/libtdm-fbdev.spec +++ /dev/null @@ -1,79 +0,0 @@ -Name: libtdm-fbdev -Version: 2.0.0 -Release: 0 -Summary: Tizen Display Manager DRM Back-End Library -Group: Development/Libraries -License: MIT -Source0: %{name}-%{version}.tar.gz -Source1001: %{name}.manifest -Source1002: libhal-backend-tdm-fbdev.manifest - -BuildRequires: pkgconfig(libdrm) -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) - -%description -Back-End library of Tizen Display Manager FBDEV : libtdm-mgr FBDEV library - -%package -n hal-backend-tdm-fbdev -Summary: hal-backend-tdm module for fbdev -Group: System/Libraries -Requires: hal-api-tdm -Requires: hal-api-common - -%description -n hal-backend-tdm-fbdev -descriptionion: hal tdm backend module for fbdev - -%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} \ - 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-fbdev -cp -af COPYING %{buildroot}%{_hal_licensedir}/libhal-backend-tdm-fbdev - -%post -if [ -f %{_libdir}/tdm/libtdm-default.so ]; then - rm -rf %{_libdir}/tdm/libtdm-default.so -fi -ln -s libtdm-fbdev.so %{_libdir}/tdm/libtdm-default.so - -%postun -p /sbin/ldconfig - -%post -n hal-backend-tdm-fbdev -if [ -f %{_hal_libdir}/libhal-backend-tdm.so ]; then - rm -rf %{_hal_libdir}/libhal-backend-tdm.so -fi -ln -s libhal-backend-tdm-fbdev.so %{_hal_libdir}/libhal-backend-tdm.so - -%postun -n hal-backend-tdm-fbdev -p /sbin/ldconfig - -%files -%defattr(-,root,root,-) -%manifest %{name}.manifest -%license COPYING -%{_libdir}/tdm/libtdm-fbdev.so - -%files -n hal-backend-tdm-fbdev -%manifest libhal-backend-tdm-fbdev.manifest -%{_hal_licensedir}/libhal-backend-tdm-fbdev/COPYING -%{_hal_libdir}/libhal-backend-*.so* diff --git a/src/Makefile.am b/src/Makefile.am index 41bea77..a8c653b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1 +1,15 @@ -SUBDIRS = libtdm-fbdev libhal-backend-tdm-fbdev +AM_CFLAGS = \ + $(LIBHAL_BACKEND_TDM_FBDEV_CFLAGS) \ + -I$(top_srcdir)/src + +libhal_backend_tdm_fbdev_la_LTLIBRARIES = libhal-backend-tdm-fbdev.la +libhal_backend_tdm_fbdev_ladir = @HAL_LIBDIR@ +libthal_backend_dm_fbdev_la_LDFLAGS = -module -avoid-version +libhal_backend_tdm_fbdev_la_LIBADD = $(LIBHAL_BACKEND_TDM_FBDEV_LIBS) -ldl + +libhal_backend_tdm_fbdev_la_SOURCES = \ + tdm_backend_fbdev.c \ + tdm_backend_log.c \ + tdm_fbdev_display.c \ + tdm_fbdev_hwc.c \ + tdm_fbdev_hwc_window.c diff --git a/src/libhal-backend-tdm-fbdev/Makefile.am b/src/libhal-backend-tdm-fbdev/Makefile.am deleted file mode 100644 index 24c253a..0000000 --- a/src/libhal-backend-tdm-fbdev/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -AM_CFLAGS = \ - $(LIBHAL_BACKEND_TDM_FBDEV_CFLAGS) \ - -I$(top_srcdir)/src/libhal-backend-tdm-fbdev - -libhal_backend_tdm_fbdev_la_LTLIBRARIES = libhal-backend-tdm-fbdev.la -libhal_backend_tdm_fbdev_ladir = @HAL_LIBDIR@ -libthal_backend_dm_fbdev_la_LDFLAGS = -module -avoid-version -libhal_backend_tdm_fbdev_la_LIBADD = $(LIBHAL_BACKEND_TDM_FBDEV_LIBS) -ldl - -libhal_backend_tdm_fbdev_la_SOURCES = \ - tdm_backend_fbdev.c \ - tdm_backend_log.c \ - tdm_fbdev_display.c \ - tdm_fbdev_hwc.c \ - tdm_fbdev_hwc_window.c diff --git a/src/libhal-backend-tdm-fbdev/tdm_backend_fbdev.c b/src/libhal-backend-tdm-fbdev/tdm_backend_fbdev.c deleted file mode 100644 index be588a8..0000000 --- a/src/libhal-backend-tdm-fbdev/tdm_backend_fbdev.c +++ /dev/null @@ -1,362 +0,0 @@ -/************************************************************************** - -libtdm_fbdev - -Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: SooChan Lim - -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_fbdev.h" - -#define TDM_FBDEV_NAME "fbdev" - -static int -_tdm_fbdev_open_fbdev(void) -{ - const char *name = "/dev/fb0"; - int fd = -1; - - fd = open(name, O_RDWR); - if (fd < 0) { - TDM_BACKEND_ERR("Cannot open fbdev device.. search by udev"); - goto close; - } - - /* - * TODO: If we failed directly to open framebuffer device - * we would try to open it through udev - */ - -close: - - return fd; -} - -static hal_tdm_error -_tdm_fbdev_init_internal(tdm_fbdev_display *display_data) -{ - struct fb_fix_screeninfo *finfo = calloc(1, sizeof(struct fb_fix_screeninfo)); - struct fb_var_screeninfo *vinfo = calloc(1, sizeof(struct fb_var_screeninfo)); - int ret = -1; - - if (display_data == NULL) { - TDM_BACKEND_ERR("invalid parameter"); - goto close_1; - } - - ret = ioctl(display_data->fbdev_fd, FBIOGET_VSCREENINFO, vinfo); - if (ret < 0) { - TDM_BACKEND_ERR("FBIOGET_VSCREENINFO ioctl failed errno=%d", errno); - goto close_1; - } - - vinfo->reserved[0] = 0; - vinfo->reserved[1] = 0; - vinfo->reserved[2] = 0; - vinfo->xoffset = 0; - vinfo->yoffset = 0; - vinfo->activate = FB_ACTIVATE_NOW; - - /* - * Explicitly request 32 bits per pixel colors with corresponding - * red, blue and green color offsets and length of colors - */ - vinfo->bits_per_pixel = 32; - vinfo->red.offset = 16; - vinfo->red.length = 8; - vinfo->green.offset = 8; - vinfo->green.length = 8; - vinfo->blue.offset = 0; - vinfo->blue.length = 8; - vinfo->transp.offset = 0; - vinfo->transp.length = 0; - - vinfo->yres_virtual = vinfo->yres * MAX_BUF; - ret = ioctl(display_data->fbdev_fd, FBIOPAN_DISPLAY, vinfo); - if (ret < 0) - TDM_BACKEND_ERR("FBIOPAN_DISPLAY ioctl failed, errno=%d", errno); - - ret = ioctl(display_data->fbdev_fd, FBIOGET_FSCREENINFO, finfo); - if (ret < 0) { - TDM_BACKEND_ERR("FBIOGET_FSCREENINFO ioctl failed, errno=%d", errno); - goto close_1; - } - - if (finfo->smem_len <= 0) { - TDM_BACKEND_ERR("Length of frame buffer mem less then 0"); - goto close_1; - } - - display_data->vinfo = vinfo; - display_data->finfo = finfo; - - /* - * Output framebuffer's related information - */ - TDM_BACKEND_INFO("\n" - " VInfo\n" - " fb = %d\n" - " xres = %d px \n" - " yres = %d px \n" - " xres_virtual = %d px \n" - " yres_virtual = %d px \n" - " bpp = %d \n" - " r = %2u:%u\n" - " g = %2u:%u\n" - " b = %2u:%u\n" - " t = %2u:%u\n" - " active = %d \n" - " width = %d mm \n" - " height = %d mm \n", - display_data->fbdev_fd, - vinfo->xres, - vinfo->yres, - vinfo->xres_virtual, - vinfo->yres_virtual, - vinfo->bits_per_pixel, - vinfo->red.offset, vinfo->red.length, - vinfo->green.offset, vinfo->green.length, - vinfo->blue.offset, vinfo->blue.length, - vinfo->transp.offset, vinfo->transp.length, - vinfo->activate, - vinfo->width, - vinfo->height); - - TDM_BACKEND_INFO("\n" - " FInfo\n" - " id = %s\n" - " smem_len = %d\n" - " line_length = %d\n", - finfo->id, - finfo->smem_len, - finfo->line_length); - - return HAL_TDM_ERROR_NONE; -close_1: - ret = HAL_TDM_ERROR_OPERATION_FAILED; - free(vinfo); - free(finfo); - return ret; -} - -int -hal_backend_tdm_fbdev_exit(void *data) -{ - hal_tdm_backend_data *backend_data = (hal_tdm_backend_data *)data; - tdm_fbdev_display *display_data; - - TDM_BACKEND_INFO("deinit"); - - TDM_BACKEND_RETURN_VAL_IF_FAIL(backend_data != NULL, -1); - - display_data = (tdm_fbdev_display *)backend_data->display; - TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data != NULL, -1); - - 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; - } - - if (display_data->fbdev_fd >= 0) - close(display_data->fbdev_fd); - - tdm_fbdev_display_destroy_buffer_list(display_data); - tdm_fbdev_destroy_layer(display_data); - tdm_fbdev_destroy_output(display_data); - - if (display_data->vinfo) - free(display_data->vinfo); - - if (display_data->finfo) - free(display_data->finfo); - - free(display_data); - free(backend_data); - - return HAL_TDM_ERROR_NONE; -} - -static int -hal_backend_tdm_fbdev_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; - tdm_fbdev_display *display_data = NULL; - hal_tdm_error ret; - - /* 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_fbdev_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->buffer_list); - - /* 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 = fbdev_display_get_capability; - display_funcs->display_get_outputs = fbdev_display_get_outputs; - display_funcs->display_get_fd = NULL; - display_funcs->display_handle_events = NULL; - - /* 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 = fbdev_output_get_capability; - output_funcs->output_set_property = fbdev_output_set_property; - output_funcs->output_get_property = fbdev_output_get_property; - output_funcs->output_wait_vblank = fbdev_output_wait_vblank; - output_funcs->output_set_vblank_handler = fbdev_output_set_vblank_handler; - output_funcs->output_set_dpms = fbdev_output_set_dpms; - output_funcs->output_get_dpms = fbdev_output_get_dpms; - output_funcs->output_set_mode = fbdev_output_set_mode; - output_funcs->output_get_mode = fbdev_output_get_mode; - output_funcs->output_get_hwc = fbdev_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 = fbdev_hwc_create_window; - hwc_funcs->hwc_get_video_supported_formats = fbdev_hwc_get_video_supported_formats; - hwc_funcs->hwc_get_capabilities = fbdev_hwc_get_capabilities; - hwc_funcs->hwc_get_available_properties = fbdev_hwc_get_available_properties; - hwc_funcs->hwc_get_client_target_buffer_queue = fbdev_hwc_get_client_target_buffer_queue; - hwc_funcs->hwc_set_client_target_buffer = fbdev_hwc_set_client_target_buffer; - hwc_funcs->hwc_validate = fbdev_hwc_validate; - hwc_funcs->hwc_get_changed_composition_types = fbdev_hwc_get_changed_composition_types; - hwc_funcs->hwc_accept_validation = fbdev_hwc_accept_validation; - hwc_funcs->hwc_commit = fbdev_hwc_commit; - hwc_funcs->hwc_set_commit_handler = fbdev_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 = fbdev_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 = fbdev_hwc_window_set_composition_type; - hwc_window_funcs->hwc_window_set_buffer_damage = fbdev_hwc_window_set_buffer_damage; - hwc_window_funcs->hwc_window_set_info = fbdev_hwc_window_set_info; - hwc_window_funcs->hwc_window_set_buffer = fbdev_hwc_window_set_buffer; - hwc_window_funcs->hwc_window_set_property = fbdev_hwc_window_set_property; - hwc_window_funcs->hwc_window_get_property = fbdev_hwc_window_get_property; - hwc_window_funcs->hwc_window_get_constraints = fbdev_hwc_window_get_constraints; - hwc_window_funcs->hwc_window_set_name = fbdev_hwc_window_set_name; - hwc_window_funcs->hwc_window_set_cursor_image = fbdev_hwc_window_set_cursor_image; - - display_data->fbdev_fd = _tdm_fbdev_open_fbdev(); - if (display_data->fbdev_fd < 0) { - TDM_BACKEND_ERR("fail to open fbdev!\n"); - goto failed; - } - - ret = _tdm_fbdev_init_internal(display_data); - if (ret != HAL_TDM_ERROR_NONE) { - TDM_BACKEND_ERR("init of framebuffer failed"); - goto failed; - } - - ret = tdm_fbdev_create_output(display_data); - if (ret != HAL_TDM_ERROR_NONE) { - TDM_BACKEND_ERR("init of output failed"); - goto failed; - } - - ret = tdm_fbdev_create_layer(display_data); - if (ret != HAL_TDM_ERROR_NONE) { - TDM_BACKEND_ERR("init of layer failed"); - goto failed; - } - - TDM_BACKEND_INFO("init success!"); - - return HAL_TDM_ERROR_NONE; - -failed: - TDM_BACKEND_ERR("init failed!"); - - hal_backend_tdm_fbdev_exit((void *)backend_data); - - return -1; -} - -hal_backend hal_backend_tdm_data = { - "fbdev", - "Samsung", - HAL_ABI_VERSION_TIZEN_6_5, - hal_backend_tdm_fbdev_init, - hal_backend_tdm_fbdev_exit -}; diff --git a/src/libhal-backend-tdm-fbdev/tdm_backend_fbdev.h b/src/libhal-backend-tdm-fbdev/tdm_backend_fbdev.h deleted file mode 100644 index eb41529..0000000 --- a/src/libhal-backend-tdm-fbdev/tdm_backend_fbdev.h +++ /dev/null @@ -1,101 +0,0 @@ -/************************************************************************** - -libtdm_fbdev - -Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: SooChan Lim - -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_FBDEV_H_ -#define _TDM_FBDEV_H_ - -#include "tdm_backend_fbdev_types.h" - -#define MAX_BUF 1 - -/* display funcs */ -hal_tdm_error fbdev_display_get_capability(hal_tdm_display *display, hal_tdm_caps_display *caps); -hal_tdm_output **fbdev_display_get_outputs(hal_tdm_display *display, int *count, hal_tdm_error *error); -hal_tdm_error fbdev_display_get_fd(hal_tdm_display *display, int *fd); -hal_tdm_error fbdev_display_handle_events(hal_tdm_display *display); -hal_tdm_pp *fbdev_display_create_pp(hal_tdm_display *display, hal_tdm_error *error); - -/* output funcs */ -hal_tdm_error fbdev_output_get_capability(hal_tdm_output *output, hal_tdm_caps_output *caps); -hal_tdm_error fbdev_output_set_property(hal_tdm_output *output, unsigned int id, hal_tdm_value value); -hal_tdm_error fbdev_output_get_property(hal_tdm_output *output, unsigned int id, hal_tdm_value *value); -hal_tdm_error fbdev_output_wait_vblank(hal_tdm_output *output, int interval, int sync, void *user_data); -hal_tdm_error fbdev_output_set_vblank_handler(hal_tdm_output *output, hal_tdm_output_vblank_handler func); -hal_tdm_error fbdev_output_commit(hal_tdm_output *output, int sync, void *user_data); -hal_tdm_error fbdev_output_set_commit_handler(hal_tdm_output *output, hal_tdm_output_commit_handler func); -hal_tdm_error fbdev_output_set_dpms(hal_tdm_output *output, hal_tdm_output_dpms dpms_value); -hal_tdm_error fbdev_output_get_dpms(hal_tdm_output *output, hal_tdm_output_dpms *dpms_value); -hal_tdm_error fbdev_output_set_mode(hal_tdm_output *output, const hal_tdm_output_mode *mode); -hal_tdm_error fbdev_output_get_mode(hal_tdm_output *output, const hal_tdm_output_mode **mode); -hal_tdm_hwc *fbdev_output_get_hwc(hal_tdm_output *output, hal_tdm_error *error); - -/* hwc funcs */ -hal_tdm_hwc_window *fbdev_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_error *error); -hal_tdm_error fbdev_hwc_get_video_supported_formats(hal_tdm_output *output, const tbm_format **formats, int *count); -hal_tdm_error fbdev_hwc_get_capabilities(hal_tdm_hwc *hwc, hal_tdm_hwc_capability *capabilities); -hal_tdm_error fbdev_hwc_get_available_properties(hal_tdm_hwc *hwc, const hal_tdm_prop **props, int *count); -tbm_surface_queue_h fbdev_hwc_get_client_target_buffer_queue(hal_tdm_hwc *hwc, hal_tdm_error *error); -hal_tdm_error fbdev_hwc_set_client_target_buffer(hal_tdm_hwc *hwc, tbm_surface_h buffer, hal_tdm_region damage); -hal_tdm_error fbdev_hwc_validate(hal_tdm_hwc *hwc, hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types); -hal_tdm_error fbdev_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 fbdev_hwc_accept_validation(hal_tdm_hwc *hwc); -hal_tdm_error fbdev_hwc_commit(hal_tdm_hwc *hwc, int sync, void *user_data); -hal_tdm_error fbdev_hwc_set_commit_handler(hal_tdm_hwc *hwc, hal_tdm_hwc_commit_handler func); - -/* hwc_window funcs */ -void fbdev_hwc_window_destroy(hal_tdm_hwc_window *hwc_window); -hal_tdm_error fbdev_hwc_window_set_composition_type(hal_tdm_hwc_window *hwc_window, hal_tdm_hwc_window_composition composition_type); -hal_tdm_error fbdev_hwc_window_set_buffer_damage(hal_tdm_hwc_window *hwc_window, hal_tdm_region damage); -hal_tdm_error fbdev_hwc_window_set_info(hal_tdm_hwc_window *hwc_window, hal_tdm_hwc_window_info *info); -hal_tdm_error fbdev_hwc_window_set_buffer(hal_tdm_hwc_window *hwc_window, tbm_surface_h surface); -hal_tdm_error fbdev_hwc_window_set_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value value); -hal_tdm_error fbdev_hwc_window_get_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value *value); -hal_tdm_error fbdev_hwc_window_get_constraints(hal_tdm_hwc_window *hwc_window, int *constraints); -hal_tdm_error fbdev_hwc_window_set_name(hal_tdm_hwc_window *hwc_window, const char *name); -hal_tdm_error fbdev_hwc_window_set_cursor_image(hal_tdm_hwc_window *hwc_window, int width, int height, int stride, void *ptr); - - -void tdm_fbdev_display_destroy_buffer_list(tdm_fbdev_display *display_data); - -hal_tdm_error tdm_fbdev_create_output(tdm_fbdev_display *display_data); -void tdm_fbdev_destroy_output(tdm_fbdev_display *display_data); - -hal_tdm_error tdm_fbdev_create_layer(tdm_fbdev_display *display_data); -void tdm_fbdev_destroy_layer(tdm_fbdev_display *display_data); -hal_tdm_error fbdev_layer_set_buffer(tdm_fbdev_layer *layer_data, tbm_surface_h buffer); -hal_tdm_error fbdev_layer_unset_buffer(tdm_fbdev_layer *layer_data); -hal_tdm_error fbdev_layer_set_info(tdm_fbdev_layer *layer_data, tdm_fbdev_layer_info *info); - -tdm_fbdev_layer *fbdev_output_data_get_layer_data(tdm_fbdev_output *output_data, int layer_zops); - -hal_tdm_error fbdev_hwc_initailize_target_window(tdm_fbdev_hwc *hwc_data); -hal_tdm_error fbdev_hwc_target_window_set_info(tdm_fbdev_hwc *hwc_data, int width, int height); - -#endif /* _TDM_FBDEV_H_ */ diff --git a/src/libhal-backend-tdm-fbdev/tdm_backend_fbdev_types.h b/src/libhal-backend-tdm-fbdev/tdm_backend_fbdev_types.h deleted file mode 100644 index 832d2da..0000000 --- a/src/libhal-backend-tdm-fbdev/tdm_backend_fbdev_types.h +++ /dev/null @@ -1,245 +0,0 @@ -/************************************************************************** - -libtdm_drm - -Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: SooChan Lim - -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_FBDEV_TYPES_H_ -#define _TDM_FBDEV_TYPES_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tdm_backend_list.h" -#include "tdm_fbdev_format.h" -#include "tdm_backend_log.h" - -typedef struct _tdm_fbdev_display tdm_fbdev_display; -typedef struct _tdm_fbdev_output tdm_fbdev_output; -typedef struct _tdm_fbdev_layer tdm_fbdev_layer; -typedef struct _tdm_fbdev_hwc tdm_fbdev_hwc; -typedef struct _tdm_fbdev_hwc_window tdm_fbdev_hwc_window; -typedef struct _tdm_fbdev_display_buffer tdm_fbdev_display_buffer; - -typedef enum { - TDM_FBDEV_LAYER_CAPABILITY_CURSOR = (1 << 0), /**< cursor */ - TDM_FBDEV_LAYER_CAPABILITY_PRIMARY = (1 << 1), /**< primary */ - TDM_FBDEV_LAYER_CAPABILITY_OVERLAY = (1 << 2), /**< overlay */ - TDM_FBDEV_LAYER_CAPABILITY_GRAPHIC = (1 << 4), /**< graphic */ - TDM_FBDEV_LAYER_CAPABILITY_VIDEO = (1 << 5), /**< video */ - TDM_FBDEV_LAYER_CAPABILITY_SCALE = (1 << 8), /**< if a layer_data has scale capability */ - TDM_FBDEV_LAYER_CAPABILITY_TRANSFORM = (1 << 9), /**< if a layer_data has transform capability */ - TDM_FBDEV_LAYER_CAPABILITY_SCANOUT = (1 << 10), /**< if a layer_data allows a scanout buffer only */ - TDM_FBDEV_LAYER_CAPABILITY_RESEVED_MEMORY = (1 << 11), /**< if a layer_data allows a reserved buffer only */ - TDM_FBDEV_LAYER_CAPABILITY_NO_CROP = (1 << 12), /**< if a layer_data has no cropping capability */ -} tdm_fbdev_layer_capability; - -typedef struct _tdm_fbdev_display { - tdm_fbdev_output *output_data; - - int fbdev_fd; - - hal_tdm_display *dpy; - - int hwc_mode; - - struct fb_fix_screeninfo *finfo; - struct fb_var_screeninfo *vinfo; - - struct list_head buffer_list; -} tdm_fbdev_display; - -struct _tdm_fbdev_output { - tdm_fbdev_display *display_data; - tdm_fbdev_layer *layer_data; - - uint32_t width; - uint32_t height; - uint32_t pitch; - uint32_t bpp; - size_t size; - uint32_t max_width; - uint32_t max_height; - - /* - * Poinetr to Framebuffers's mapped memory - */ - void *mem; - - int count_modes; - hal_tdm_output_mode *output_modes; - int mode_changed; - - /* - * Frambuffer device back end currently support only one mode - */ - const hal_tdm_output_mode *current_mode; - - hal_tdm_output_type connector_type; - hal_tdm_output_conn_status status; - unsigned int connector_type_id; - - hal_tdm_output_dpms dpms_value; - - /* - * Event handlers - */ - hal_tdm_output_vblank_handler vblank_func; - hal_tdm_output_commit_handler commit_func; - - void *user_data; - - /* - * Fake flags are used to simulate event-operated back end. Since tdm - * library assumes its back ends to be event-operated and Framebuffer - * device is not event-operated we have to make fake events - */ - int is_vblank; - int is_commit; - - int sequence; - - /* hwc */ - int hwc_enable; - tdm_fbdev_hwc *hwc_data; - - /* dpms */ - hal_tdm_output_dpms current_dpms; -}; - -typedef struct _tdm_fbdev_caps_layer { - tdm_fbdev_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_fbdev_caps_layer; - -typedef struct _tdm_fbdev_layer_info { - hal_tdm_info_config src_config; - hal_tdm_pos dst_pos; - hal_tdm_transform transform; -} tdm_fbdev_layer_info; - -struct _tdm_fbdev_layer { - tdm_fbdev_display *display_data; - tdm_fbdev_output *output_data; - - tdm_fbdev_display_buffer *display_buffer; - int display_buffer_changed; - - tdm_fbdev_layer_capability capabilities; - tdm_fbdev_layer_info info; - int info_changed; -}; - -struct _tdm_fbdev_display_buffer { - struct list_head link; - - int width; - int height; - - tbm_surface_h buffer; -}; - -struct _tdm_fbdev_hwc { - tdm_fbdev_hwc_window *target_hwc_window; - - int need_validate; - int need_target_window; - int need_set_crtc; - - int target_window_zpos; - - tdm_fbdev_output *output_data; - struct list_head hwc_window_list; - - tbm_surface_h cursor_tsurface; - - hal_tdm_hwc_commit_handler commit_func; -}; - -struct _tdm_fbdev_hwc_window { - struct list_head link; - - tdm_fbdev_hwc *hwc_data; - - hal_tdm_hwc_window_info info; - tbm_surface_h surface; - hal_tdm_hwc_window_composition client_type; - hal_tdm_hwc_window_composition validated_type; - int lzpos; - - char name[HAL_TDM_NAME_LEN]; - struct { - int width; - int height; - int stride; - void *ptr; - } cursor_img; - int cursor_img_surface; - int cursor_img_refresh; -}; - -#endif /* _TDM_FBDEV_TYPES_H_ */ diff --git a/src/libhal-backend-tdm-fbdev/tdm_backend_list.h b/src/libhal-backend-tdm-fbdev/tdm_backend_list.h deleted file mode 100644 index 3873817..0000000 --- a/src/libhal-backend-tdm-fbdev/tdm_backend_list.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * - * 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 - -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_*/ diff --git a/src/libhal-backend-tdm-fbdev/tdm_backend_log.c b/src/libhal-backend-tdm-fbdev/tdm_backend_log.c deleted file mode 100644 index 808ceb1..0000000 --- a/src/libhal-backend-tdm-fbdev/tdm_backend_log.c +++ /dev/null @@ -1,70 +0,0 @@ -/************************************************************************** - -libtdm_vc4 - -Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: SooChan Lim - -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" - -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 diff --git a/src/libhal-backend-tdm-fbdev/tdm_backend_log.h b/src/libhal-backend-tdm-fbdev/tdm_backend_log.h deleted file mode 100644 index a62ec86..0000000 --- a/src/libhal-backend-tdm-fbdev/tdm_backend_log.h +++ /dev/null @@ -1,109 +0,0 @@ -/************************************************************************** - -libtdm_vc4 - -Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: SooChan Lim - -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 -#include -#include -#include - -#undef LOG_TAG -#define LOG_TAG "TDM_BACKEND" - -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 diff --git a/src/libhal-backend-tdm-fbdev/tdm_fbdev_display.c b/src/libhal-backend-tdm-fbdev/tdm_fbdev_display.c deleted file mode 100644 index 58393cb..0000000 --- a/src/libhal-backend-tdm-fbdev/tdm_fbdev_display.c +++ /dev/null @@ -1,894 +0,0 @@ -/************************************************************************** - -libtdm_fbdev - -Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: SooChan Lim - -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 -#include "tdm_backend_fbdev.h" - -#include -#include - -/* - * Framebuffer device supported formats - */ -static tbm_format supported_formats[] = { - /* - * TODO: add support of 16 bit formats - */ - TBM_FORMAT_ARGB8888, - TBM_FORMAT_ABGR8888, - TBM_FORMAT_RGBA8888, - TBM_FORMAT_BGRA8888, -}; - -static tdm_fbdev_display_buffer * -_tdm_fbdev_display_find_buffer(tdm_fbdev_display *display_data, tbm_surface_h buffer) -{ - tdm_fbdev_display_buffer *display_buffer = NULL; - - LIST_FOR_EACH_ENTRY(display_buffer, &display_data->buffer_list, link) - { - if (display_buffer->buffer == buffer) - return display_buffer; - } - - return NULL; -} - -static void -_tdm_fbdev_display_cb_destroy_buffer(tbm_surface_h buffer, void *user_data) -{ - tdm_fbdev_display *display_data; - tdm_fbdev_display_buffer *display_buffer; - - if (!user_data) { - TDM_BACKEND_ERR("no user_data"); - return; - } - if (!buffer) { - TDM_BACKEND_ERR("no buffer"); - return; - } - - display_data = (tdm_fbdev_display *)user_data; - - display_buffer = _tdm_fbdev_display_find_buffer(display_data, buffer); - if (!display_buffer) { - TDM_BACKEND_ERR("no display_buffer"); - return; - } - - LIST_DEL(&display_buffer->link); - - free(display_buffer); -} - - -static inline uint32_t -_get_refresh(struct fb_var_screeninfo *timing) -{ - uint32_t pixclock, hfreq, htotal, vtotal; - - pixclock = PICOS2KHZ(timing->pixclock) * 1000; - - htotal = timing->xres + timing->right_margin + timing->hsync_len + timing->left_margin; - vtotal = timing->yres + timing->lower_margin + timing->vsync_len + timing->upper_margin; - - if (timing->vmode & FB_VMODE_INTERLACED) - vtotal /= 2; - if (timing->vmode & FB_VMODE_DOUBLE) - vtotal *= 2; - - hfreq = pixclock / htotal; - return hfreq / vtotal; -} - -/* - * Convert fb_var_screeninfo to hal_tdm_output_mode - */ -static inline void -_tdm_fbdev_display_to_tdm_mode(struct fb_var_screeninfo *timing, hal_tdm_output_mode *mode) -{ - - if (!timing->pixclock) - return; - - mode->clock = timing->pixclock / 1000; - mode->vrefresh = _get_refresh(timing); - mode->hdisplay = timing->xres; - mode->hsync_start = mode->hdisplay + timing->right_margin; - mode->hsync_end = mode->hsync_start + timing->hsync_len; - mode->htotal = mode->hsync_end + timing->left_margin; - - mode->vdisplay = timing->yres; - mode->vsync_start = mode->vdisplay + timing->lower_margin; - mode->vsync_end = mode->vsync_start + timing->vsync_len; - mode->vtotal = mode->vsync_end + timing->upper_margin; - - int interlaced = !!(timing->vmode & FB_VMODE_INTERLACED); - snprintf(mode->name, HAL_TDM_NAME_LEN, "%dx%d%s", mode->hdisplay, mode->vdisplay, interlaced ? "i" : ""); -} - -void -tdm_fbdev_display_destroy_buffer_list(tdm_fbdev_display *display_data) -{ - tdm_fbdev_display_buffer *b = NULL, *bb = NULL; - - LIST_FOR_EACH_ENTRY_SAFE(b, bb, &display_data->buffer_list, link) { - tbm_surface_internal_remove_destroy_handler(b->buffer, _tdm_fbdev_display_cb_destroy_buffer, display_data); - _tdm_fbdev_display_cb_destroy_buffer(b->buffer, display_data); - } -} - -hal_tdm_error -tdm_fbdev_create_output(tdm_fbdev_display *display_data) -{ - tdm_fbdev_output *output = NULL; - size_t size; - int i = 0; - - output = calloc(1, sizeof(tdm_fbdev_output)); - if (output == NULL) { - TDM_BACKEND_ERR("alloc output failed"); - return HAL_TDM_ERROR_OUT_OF_MEMORY; - } - - /* - * TODO: Size of framebuffer must be aligned to system page size before - * it is mapped - */ - size = display_data->vinfo->xres * display_data->vinfo->yres * display_data->vinfo->bits_per_pixel / 8 * MAX_BUF; - - TDM_BACKEND_INFO("\n" "MMaped size: %zu\n", size); - - output->mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, display_data->fbdev_fd, 0); - if (output->mem == MAP_FAILED) { - TDM_BACKEND_ERR("MMap framebuffer failed, errno=%d", errno); - return HAL_TDM_ERROR_OPERATION_FAILED; - } - - memset(output->mem, 0, size); - - output->width = display_data->vinfo->xres; - output->height = display_data->vinfo->yres; - output->pitch = display_data->vinfo->width; - output->bpp = display_data->vinfo->bits_per_pixel; - output->size = size; - output->max_width = display_data->vinfo->xres_virtual; - output->max_height = display_data->vinfo->yres_virtual; - - output->status = HAL_TDM_OUTPUT_CONN_STATUS_CONNECTED; - output->connector_type = HAL_TDM_OUTPUT_TYPE_LVDS; - - output->is_vblank = DOWN; - output->is_commit = DOWN; - output->sequence = 1; - - /* - * TODO: connector_type_id field relates to libdrm connector which framebuffer - * does not know. It have to be checked whether softaware above us use this - * field for its purposes. - */ - output->connector_type_id = 1; - - output->count_modes = 1; - output->output_modes = calloc(output->count_modes, sizeof(hal_tdm_output_mode)); - if (!output->output_modes) { - TDM_BACKEND_ERR("failed: alloc memory"); - return HAL_TDM_ERROR_OUT_OF_MEMORY; - } - - for (i = 0; i < output->count_modes; i++) { - _tdm_fbdev_display_to_tdm_mode(display_data->vinfo, &output->output_modes[i]); - - sprintf(output->output_modes[i].name, "%dx%d", display_data->vinfo->xres, display_data->vinfo->yres); - } - - /* - * We currently support only one mode - */ - if (output->count_modes == 1) { - output->current_mode = &output->output_modes[0]; - output->status = HAL_TDM_OUTPUT_CONN_STATUS_MODE_SETTED; - } - - output->display_data = display_data; - display_data->output_data = output; - - return HAL_TDM_ERROR_NONE; -} - -void -tdm_fbdev_destroy_output(tdm_fbdev_display *display_data) -{ - tdm_fbdev_output *fbdev_output = display_data->output_data; - - if (fbdev_output == NULL) - goto close; - - if (fbdev_output->mem == NULL) - goto close_2; - - munmap(fbdev_output->mem, fbdev_output->size); - - if (fbdev_output->output_modes == NULL) - goto close_2; - - free(fbdev_output->output_modes); - -close_2: - free(fbdev_output); -close: - return; -} - -hal_tdm_error -tdm_fbdev_create_layer(tdm_fbdev_display *display_data) -{ - tdm_fbdev_layer *layer; - tdm_fbdev_output *fbdev_output = display_data->output_data; - - /* - * Framebuffer does not support layer, therefore create only - * one layer by libtdm's demand; - */ - layer = calloc(1, sizeof(tdm_fbdev_layer)); - if (layer == NULL) { - TDM_BACKEND_ERR("alloc output failed"); - return HAL_TDM_ERROR_OUT_OF_MEMORY; - } - - layer->capabilities = TDM_FBDEV_LAYER_CAPABILITY_PRIMARY | TDM_FBDEV_LAYER_CAPABILITY_GRAPHIC; - - layer->display_data = display_data; - layer->output_data = fbdev_output; - fbdev_output->layer_data = layer; - - return HAL_TDM_ERROR_NONE; -} - -void -tdm_fbdev_destroy_layer(tdm_fbdev_display *display_data) -{ - tdm_fbdev_output *fbdev_output = display_data->output_data; - tdm_fbdev_layer *layer; - - if (fbdev_output == NULL) - return; - - layer = fbdev_output->layer_data; - if (layer != NULL) - free(layer); -} - -hal_tdm_error -fbdev_display_get_capability(hal_tdm_display *display, hal_tdm_caps_display *caps) -{ - TDM_BACKEND_RETURN_VAL_IF_FAIL(caps, HAL_TDM_ERROR_INVALID_PARAMETER); - - /* - * Framebuffer does not support layer, therefore create only - * one layer by libtdm's demand; - */ - caps->max_layer_count = 1; - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_output ** -fbdev_display_get_outputs(hal_tdm_display *display, int *count, hal_tdm_error *error) -{ - tdm_fbdev_display *display_data = (tdm_fbdev_display *)display; - tdm_fbdev_output *fbdev_output = display_data->output_data; - hal_tdm_output **outputs; - hal_tdm_error ret; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data, NULL); - TDM_BACKEND_RETURN_VAL_IF_FAIL(count, NULL); - - if (fbdev_output == NULL) { - ret = HAL_TDM_ERROR_NONE; - goto failed_get; - } - - /* - * Since it is Framebuffer device there is only one output - */ - *count = 1; - - /* will be freed in frontend */ - outputs = calloc(*count, sizeof(tdm_fbdev_output*)); - if (!outputs) { - TDM_BACKEND_ERR("failed: alloc memory"); - *count = 0; - ret = HAL_TDM_ERROR_OUT_OF_MEMORY; - goto failed_get; - } - - outputs[0] = fbdev_output; - - if (error) - *error = HAL_TDM_ERROR_NONE; - - return outputs; - -failed_get: - - if (error) - *error = ret; - return NULL; -} - -hal_tdm_error -fbdev_display_handle_events(hal_tdm_display *display) -{ - tdm_fbdev_display *display_data = (tdm_fbdev_display *)display; - void *user_data; - tdm_fbdev_output *fbdev_output; - unsigned int sequence = 0; - unsigned int tv_sec = 0; - unsigned int tv_usec = 0; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data, HAL_TDM_ERROR_INVALID_PARAMETER); - - fbdev_output = display_data->output_data; - user_data = fbdev_output->user_data; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(user_data, HAL_TDM_ERROR_INVALID_PARAMETER); - - /* - (hal_tdm_output *output, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, - void *user_data); - */ - - /* - * Framebuffer does not produce events - * Fake flags are used to simulate event-operated back end. Since tdm - * library assumes its back ends to be event-operated and Framebuffer - * device is not event-operated we have to make fake events - */ - if (fbdev_output->is_vblank && fbdev_output->vblank_func) { - fbdev_output->is_vblank = DOWN; - - fbdev_output->vblank_func((hal_tdm_output *)display_data, sequence, tv_sec, tv_usec, user_data); - } - - if (fbdev_output->is_commit && fbdev_output->commit_func) { - fbdev_output->is_commit = DOWN; - - fbdev_output->commit_func((hal_tdm_output *)display_data, sequence, tv_sec, tv_usec, user_data); - } - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_output_get_capability(hal_tdm_output *output, hal_tdm_caps_output *caps) -{ - tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; - tdm_fbdev_display *display_data = NULL; - hal_tdm_error ret; - int i = 0; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, 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 = fbdev_output->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->status = fbdev_output->status; - caps->type = fbdev_output->connector_type; - caps->type_id = fbdev_output->connector_type_id; - - caps->mode_count = fbdev_output->count_modes; - caps->modes = calloc(caps->mode_count, sizeof(hal_tdm_output_mode)); - if (!caps->modes) { - ret = HAL_TDM_ERROR_OUT_OF_MEMORY; - TDM_BACKEND_ERR("alloc failed\n"); - goto failed_get; - } - - for (i = 0; i < caps->mode_count; i++) - caps->modes[i] = fbdev_output->output_modes[i]; - - caps->mmWidth = display_data->vinfo->width; - caps->mmHeight = display_data->vinfo->height; - caps->subpixel = -1; - - caps->min_w = fbdev_output->width; - caps->min_h = fbdev_output->height; - caps->max_w = fbdev_output->max_width; - caps->max_h = fbdev_output->max_height; - caps->preferred_align = -1; - - /* - * Framebuffer does not have output properties - */ - caps->prop_count = 0; - caps->props = NULL; - - caps->capabilities |= HAL_TDM_OUTPUT_CAPABILITY_HWC; - - return HAL_TDM_ERROR_NONE; - -failed_get: - memset(caps, 0, sizeof(hal_tdm_caps_output)); - return ret; -} - -hal_tdm_error -fbdev_output_set_property(hal_tdm_output *output, unsigned int id, hal_tdm_value value) -{ - /* - * Framebuffer does not have output properties - */ - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_output_get_property(hal_tdm_output *output, unsigned int id, hal_tdm_value *value) -{ - /* - * Framebuffer does not have output properties - */ - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_output_wait_vblank(hal_tdm_output *output, int interval, int sync, void *user_data) -{ - tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; - tdm_fbdev_display *display_data; - - int crtc = 0; - int ret; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); - - /* - * Frame buffer device does not support asynchronous events, that is - * why clients must get responsibility on handling asynchronous - * events. - */ - if (!sync) { - TDM_BACKEND_WRN("Framebuffer back end does not support asynchronous vblank"); - return HAL_TDM_ERROR_NONE; - } - - display_data = fbdev_output->display_data; - - ret = ioctl(display_data->fbdev_fd, FBIO_WAITFORVSYNC, &crtc); - if (ret < 0) { - TDM_BACKEND_ERR("FBIO_WAITFORVSYNC ioctl failed, errno=%d", errno); - return HAL_TDM_ERROR_OPERATION_FAILED; - } - - /* - * Up fake flag to simulate vsync event - */ - fbdev_output->is_vblank = UP; - fbdev_output->user_data = user_data; - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_output_set_vblank_handler(hal_tdm_output *output, hal_tdm_output_vblank_handler func) -{ - tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); - TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER); - - fbdev_output->vblank_func = func; - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_output_commit(hal_tdm_output *output, int sync, void *user_data) -{ - tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; - tdm_fbdev_layer *fbdev_layer; - tdm_fbdev_display_buffer *display_buffer; - tbm_bo bo; - tbm_bo_handle bo_handle; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); - - fbdev_layer = fbdev_output->layer_data; - - if (!fbdev_layer->display_buffer_changed) - return HAL_TDM_ERROR_NONE; - - fbdev_output->mode_changed = 0; - fbdev_layer->display_buffer_changed = 0; - fbdev_layer->info_changed = 0; - - display_buffer = fbdev_layer->display_buffer; - - bo = tbm_surface_internal_get_bo(display_buffer->buffer, 0); - if (!bo) { - TDM_BACKEND_ERR("get bo fail"); - return HAL_TDM_ERROR_OPERATION_FAILED; - } - - bo_handle = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_READ); - if (!bo_handle.ptr) { - TDM_BACKEND_ERR("map bo fail"); - return HAL_TDM_ERROR_OPERATION_FAILED; - } - - /* - * Display buffer's content to screen - */ - memcpy(fbdev_output->mem, bo_handle.ptr, tbm_bo_size(bo) * sizeof(char)); - - tbm_bo_unmap(bo); - - if (fbdev_output->commit_func) { - TDM_BACKEND_ERR("trace"); - fbdev_output->commit_func((hal_tdm_output *)output, fbdev_output->sequence++, 0, 0, user_data); - } - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_output_set_commit_handler(hal_tdm_output *output, hal_tdm_output_commit_handler func) -{ - tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); - TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER); - - fbdev_output->commit_func = func; - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_output_set_dpms(hal_tdm_output *output, hal_tdm_output_dpms dpms_value) -{ - tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; - tdm_fbdev_display *display_data; - int fbmode = 0; - int ret; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); - - /* - * Bypass context switching overhead - */ - if (fbdev_output->dpms_value == dpms_value) - return HAL_TDM_ERROR_NONE; - - display_data = fbdev_output->display_data; - - switch (dpms_value) { - case HAL_TDM_OUTPUT_DPMS_ON: - fbmode = FB_BLANK_UNBLANK; - break; - - case HAL_TDM_OUTPUT_DPMS_OFF: - fbmode = FB_BLANK_POWERDOWN; - break; - - case HAL_TDM_OUTPUT_DPMS_STANDBY: - fbmode = FB_BLANK_VSYNC_SUSPEND; - break; - - case HAL_TDM_OUTPUT_DPMS_SUSPEND: - fbmode = FB_BLANK_HSYNC_SUSPEND; - break; - - default: - TDM_BACKEND_ERR("NEVER GET HERE"); - break; - } - - ret = ioctl(display_data->fbdev_fd, FBIOBLANK, &fbmode); - if (ret < 0) { - TDM_BACKEND_ERR("FBIOBLANK ioctl failed, errno=%d", errno); - return HAL_TDM_ERROR_OPERATION_FAILED; - } - - /* - * TODO: framebuffer have to be reinitialized again, Maybe - */ - - fbdev_output->dpms_value = dpms_value; - fbmode = 0; - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_output_get_dpms(hal_tdm_output *output, hal_tdm_output_dpms *dpms_value) -{ - tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); - TDM_BACKEND_RETURN_VAL_IF_FAIL(dpms_value, HAL_TDM_ERROR_INVALID_PARAMETER); - - *dpms_value = fbdev_output->dpms_value; - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_output_set_mode(hal_tdm_output *output, const hal_tdm_output_mode *mode) -{ - tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); - TDM_BACKEND_RETURN_VAL_IF_FAIL(mode, HAL_TDM_ERROR_INVALID_PARAMETER); - - /* - * We currently support only one mode - */ - if (fbdev_output->count_modes == 1) - return HAL_TDM_ERROR_NONE; - - /* - * TODO: Implement mode switching - */ - fbdev_output->mode_changed = 0; - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_output_get_mode(hal_tdm_output *output, const hal_tdm_output_mode **mode) -{ - tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); - TDM_BACKEND_RETURN_VAL_IF_FAIL(mode, HAL_TDM_ERROR_INVALID_PARAMETER); - - *mode = fbdev_output->current_mode; - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_hwc * -fbdev_output_get_hwc(hal_tdm_output *output, hal_tdm_error *error) -{ - tdm_fbdev_hwc *hwc_data = NULL; - tdm_fbdev_output *output_data = output; - hal_tdm_error ret = HAL_TDM_ERROR_NONE; - - 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_fbdev_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; - - ret = fbdev_hwc_initailize_target_window(output_data->hwc_data); - if (ret != HAL_TDM_ERROR_NONE) { - TDM_BACKEND_ERR("create target hwc window failed (%d)", ret); - free(hwc_data); - if (error) - *error = ret; - return NULL; - } - - if (error) - *error = HAL_TDM_ERROR_NONE; - - return hwc_data; -} - -tdm_fbdev_layer * -fbdev_output_data_get_layer_data(tdm_fbdev_output *output_data, int layer_zpos) -{ - TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, NULL); - - if (layer_zpos == 0) - return output_data->layer_data; - - return NULL; -} - -hal_tdm_error -fbdev_layer_get_capability(tdm_fbdev_layer *layer_data, tdm_fbdev_caps_layer *caps) -{ - hal_tdm_error ret; - int i; - - 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_fbdev_caps_layer)); - - caps->capabilities = layer_data->capabilities; - - /* - * Make our single GRAPHIC layer the lowest one aka "Prime" - */ - caps->zpos = 0; - - caps->format_count = sizeof(supported_formats) / sizeof(supported_formats[0]); - caps->formats = calloc(caps->format_count, sizeof(tbm_format)); - if (!caps->formats) { - ret = HAL_TDM_ERROR_OUT_OF_MEMORY; - TDM_BACKEND_ERR("alloc failed\n"); - goto failed_get; - } - - for (i = 0; i < caps->format_count; i++) - caps->formats[i] = supported_formats[i]; - - /* - * Framebuffer does not have layer properties - */ - caps->prop_count = 0; - caps->props = NULL; - - return HAL_TDM_ERROR_NONE; - -failed_get: - - memset(caps, 0, sizeof(tdm_fbdev_caps_layer)); - return ret; -} - -hal_tdm_error -fbdev_layer_set_property(tdm_fbdev_layer *layer_data, unsigned int id, hal_tdm_value value) -{ - /* - * Framebuffer does not have layer properties - */ - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_layer_get_property(tdm_fbdev_layer *layer_data, unsigned int id, hal_tdm_value *value) -{ - /* - * Framebuffer does not have layer properties - */ - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_layer_set_info(tdm_fbdev_layer *layer_data, tdm_fbdev_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; - - /* - * We do not use info in this backend, therefore just ignore - * info's changing - */ - layer_data->info_changed = 0; - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_layer_get_info(tdm_fbdev_layer *layer_data, tdm_fbdev_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 -fbdev_layer_set_buffer(tdm_fbdev_layer *layer_data, tbm_surface_h buffer) -{ - tdm_fbdev_display_buffer *display_buffer; - tdm_fbdev_display *display_data; - hal_tdm_error err = HAL_TDM_ERROR_NONE; - - 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); - - if (tbm_surface_internal_get_num_bos(buffer) > 1) { - TDM_BACKEND_ERR("Framebuffer backend does not support surfaces with more than one bos"); - return HAL_TDM_ERROR_INVALID_PARAMETER; - } - - display_data = layer_data->display_data; - - display_buffer = _tdm_fbdev_display_find_buffer(display_data, buffer); - if (!display_buffer) { - display_buffer = calloc(1, sizeof(tdm_fbdev_display_buffer)); - if (display_buffer == NULL) { - TDM_BACKEND_ERR("alloc failed"); - return HAL_TDM_ERROR_OUT_OF_MEMORY; - } - - display_buffer->buffer = buffer; - display_buffer->width = tbm_surface_get_width(buffer); - display_buffer->height = tbm_surface_get_height(buffer); - - err = tbm_surface_internal_add_destroy_handler(buffer, _tdm_fbdev_display_cb_destroy_buffer, display_data); - if (err != HAL_TDM_ERROR_NONE) { - TDM_BACKEND_ERR("add destroy handler fail"); - free(display_buffer); - return HAL_TDM_ERROR_OPERATION_FAILED; - } - - LIST_ADDTAIL(&display_buffer->link, &display_data->buffer_list); - } - - layer_data->display_buffer = display_buffer; - layer_data->display_buffer_changed = 1; - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_layer_unset_buffer(tdm_fbdev_layer *layer_data) -{ - TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER); - - layer_data->display_buffer = NULL; - layer_data->display_buffer_changed = 1; - - return HAL_TDM_ERROR_NONE; -} diff --git a/src/libhal-backend-tdm-fbdev/tdm_fbdev_format.h b/src/libhal-backend-tdm-fbdev/tdm_fbdev_format.h deleted file mode 100644 index 4b2d849..0000000 --- a/src/libhal-backend-tdm-fbdev/tdm_fbdev_format.h +++ /dev/null @@ -1,69 +0,0 @@ -/************************************************************************** - -libtdm_fbdev - -Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: SooChan Lim - -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_FBDEV_FORMAT_H_ -#define _TDM_FBDEV_FORMAT_H_ - -#include - -#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 ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) - -#define CURSOR_MIN_W 192 -#define CURSOR_MIN_H 192 -#define CURSOR_MAX_W 192 -#define CURSOR_MAX_H 192 - -enum { - DOWN = 0, - UP, -}; - -#endif /* _TDM_FBDEV_FORMAT_H_ */ diff --git a/src/libhal-backend-tdm-fbdev/tdm_fbdev_hwc.c b/src/libhal-backend-tdm-fbdev/tdm_fbdev_hwc.c deleted file mode 100644 index 2f26722..0000000 --- a/src/libhal-backend-tdm-fbdev/tdm_fbdev_hwc.c +++ /dev/null @@ -1,803 +0,0 @@ -/************************************************************************** - -libtdm_fbdev - -Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: SooChan Lim - -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_fbdev.h" - -#define MIN_WIDTH 32 - -#define NUM_LAYERS 1 -#define NUM_BUFFERS 3 - -#define NUM_UI_LAYERS 1 - -#define ZPOS_MAX 1 -#define ZPOS_CURSOR 2 -#define ZPOS_1 1 -#define ZPOS_0 0 -#define ZPOS_VIDEO1 0 -#define ZPOS_NONE -999 - -tbm_format hwc_window_video_formats[] = { - TBM_FORMAT_NV12, - TBM_FORMAT_YUV420 -}; - -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 -_fbdev_hwc_cursor_buffer_unset(tdm_fbdev_hwc_window *hwc_window_data) -{ - hwc_window_data->surface = NULL; - hwc_window_data->cursor_img_surface = 0; - - hwc_window_data->info.src_config.pos.w = hwc_window_data->cursor_img.width; - hwc_window_data->info.src_config.pos.h = hwc_window_data->cursor_img.height; - hwc_window_data->info.dst_pos.w = hwc_window_data->cursor_img.width; - hwc_window_data->info.dst_pos.h = hwc_window_data->cursor_img.height; - - return 1; -} - -static void -_fbdev_hwc_cursor_adjust_pos(tdm_fbdev_hwc_window *hwc_window_data) -{ - int x, y; - - /* dst pos of cursor is possible set by negative value - * this is temporary code. - */ - - x = hwc_window_data->info.dst_pos.x; - y = hwc_window_data->info.dst_pos.y; - - if (x < 0) hwc_window_data->info.dst_pos.x = 0; - if (y < 0) hwc_window_data->info.dst_pos.y = 0; -} - -static int -_fbdev_hwc_cursor_buffer_set(tdm_fbdev_hwc *hwc_data, tdm_fbdev_hwc_window *hwc_window_data) -{ - tbm_surface_h cursor_tsurface = NULL; - tbm_surface_info_s tsurface_info; - tbm_surface_error_e ret = TBM_SURFACE_ERROR_NONE; - int img_w, img_h, new_w, new_h; - tbm_format new_format; - unsigned int flags = TBM_BO_SCANOUT; - void *src_ptr = NULL, *dst_ptr = NULL; - int src_stride; - int i; - - _fbdev_hwc_cursor_adjust_pos(hwc_window_data); - - if (!hwc_window_data->cursor_img_refresh && hwc_window_data->surface) - return 1; - - img_w = hwc_window_data->cursor_img.width; - img_h = hwc_window_data->cursor_img.height; - new_format = hwc_window_data->info.src_config.format; - - /* cursor restriction to set the cursor layer */ - new_w = (CURSOR_MIN_W > img_w) ? CURSOR_MIN_W : img_w; - new_h = (CURSOR_MIN_H > img_h) ? CURSOR_MIN_H : img_h; - - if (hwc_data->cursor_tsurface) { - tbm_surface_internal_unref(hwc_data->cursor_tsurface); - hwc_data->cursor_tsurface = NULL; - } - - cursor_tsurface = tbm_surface_internal_create_with_flags(new_w, new_h, new_format, flags); - TDM_BACKEND_RETURN_VAL_IF_FAIL(cursor_tsurface, 0); - - hwc_data->cursor_tsurface = cursor_tsurface; - ret = tbm_surface_map(hwc_data->cursor_tsurface, TBM_SURF_OPTION_WRITE, &tsurface_info); - if (ret != TBM_SURFACE_ERROR_NONE) { - TDM_BACKEND_ERR("Failed to map tsurface\n"); - tbm_surface_internal_unref(hwc_data->cursor_tsurface); - hwc_data->cursor_tsurface = NULL; - return 0; - } - - src_ptr = hwc_window_data->cursor_img.ptr; - dst_ptr = tsurface_info.planes[0].ptr; - src_stride = hwc_window_data->cursor_img.stride; - - memset(dst_ptr, 0, tsurface_info.planes[0].stride * tsurface_info.height); - - for (i = 0 ; i < img_h ; i++) { - memcpy(dst_ptr, src_ptr, src_stride); - dst_ptr += tsurface_info.planes[0].stride; - src_ptr += src_stride; - } - - tbm_surface_unmap(hwc_data->cursor_tsurface); - - hwc_window_data->surface = hwc_data->cursor_tsurface; - hwc_window_data->cursor_img_surface = 1; - - /* fix the dst_pos info of the cursor window */ - hwc_window_data->info.src_config.pos.w = new_w; - hwc_window_data->info.src_config.pos.h = new_h; - hwc_window_data->info.dst_pos.w = new_w; - hwc_window_data->info.dst_pos.h = new_h; - - hwc_window_data->cursor_img_refresh = 0; - - return 1; -} - -static void -_print_validate_result(tdm_fbdev_hwc *hwc_data, hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds) -{ - tdm_fbdev_hwc_window *hwc_window_data = NULL; - int i; - - for (i = 0; i < num_wnds; i++) { - hwc_window_data = composited_wnds[i]; - switch (hwc_window_data->validated_type) { - case HAL_TDM_HWC_WIN_COMPOSITION_CLIENT: - TDM_BACKEND_INFO(" window(%p) %s -> %s : lzpos(%d) -- {%s} on TARGET WINDOW", hwc_window_data, - _comp_to_str(hwc_window_data->client_type), - _comp_to_str(hwc_window_data->validated_type), - hwc_data->target_hwc_window->lzpos, - hwc_window_data->name ? hwc_window_data->name : "NONE"); - break; - case HAL_TDM_HWC_WIN_COMPOSITION_DEVICE: - case HAL_TDM_HWC_WIN_COMPOSITION_VIDEO: - case HAL_TDM_HWC_WIN_COMPOSITION_CURSOR: - case HAL_TDM_HWC_WIN_COMPOSITION_NONE: - TDM_BACKEND_INFO(" window(%p) %s -> %s : lzpos(%d) -- {%s}", hwc_window_data, - _comp_to_str(hwc_window_data->client_type), - _comp_to_str(hwc_window_data->validated_type), - hwc_window_data->lzpos, - hwc_window_data->name ? hwc_window_data->name : "NONE"); - break; - default: - break; - } - } -} - -static int -_fbdev_hwc_window_can_set_on_hw_layer(tdm_fbdev_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.pos.w < MIN_WIDTH || hwc_window_data->info.src_config.pos.w % 2) - return 0; - - return 1; -} - -static tbm_surface_queue_h -_fbdev_hwc_window_get_tbm_buffer_queue(hal_tdm_hwc_window *hwc_window, hal_tdm_error *error) -{ - tdm_fbdev_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(NUM_BUFFERS, 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; -} - -static hal_tdm_error -_fbdev_hwc_layer_attach_window(tdm_fbdev_layer *layer_data, tdm_fbdev_hwc_window *hwc_window_data) -{ - hal_tdm_error ret = HAL_TDM_ERROR_NONE; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_OPERATION_FAILED); - - if (hwc_window_data == NULL || hwc_window_data->surface == NULL) { - if (layer_data->display_buffer) - ret = fbdev_layer_unset_buffer(layer_data); - TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret); - } else { - ret = fbdev_layer_set_info(layer_data, (tdm_fbdev_layer_info *)&(hwc_window_data->info)); - TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret); - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data->surface != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - ret = fbdev_layer_set_buffer(layer_data, hwc_window_data->surface); - TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret); - } - - return ret; -} - -static hal_tdm_error -_fbdev_hwc_prepare_commit(tdm_fbdev_hwc *hwc_data) -{ - tdm_fbdev_hwc_window *hwc_window_data = NULL; - tdm_fbdev_layer *layer_data = NULL; - int use_layers_zpos[NUM_LAYERS] = {0,}; - int lzpos = 0; - - /* set target hwc window to the layer */ - if (hwc_data->need_target_window) { - layer_data = fbdev_output_data_get_layer_data(hwc_data->output_data, hwc_data->target_hwc_window->lzpos); - _fbdev_hwc_layer_attach_window(layer_data, hwc_data->target_hwc_window); - use_layers_zpos[hwc_data->target_hwc_window->lzpos] = 1; - } - - /* set the hwc_windows to the layers */ - LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) { - if (hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_NONE || - hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_CLIENT) { - - if (hwc_window_data->cursor_img_surface) - _fbdev_hwc_cursor_buffer_unset(hwc_window_data); - - continue; - } - - if (hwc_window_data == hwc_data->target_hwc_window) - continue; - - /* set the cursor buffer HERE if it needs */ - if (hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_CURSOR) - _fbdev_hwc_cursor_buffer_set(hwc_data, hwc_window_data); - - layer_data = fbdev_output_data_get_layer_data(hwc_data->output_data, hwc_window_data->lzpos); - _fbdev_hwc_layer_attach_window(layer_data, hwc_window_data); - use_layers_zpos[hwc_window_data->lzpos] = 1; - } - - /* unset the unused layers */ - for (lzpos = 0; lzpos < NUM_LAYERS; lzpos++) { - if (use_layers_zpos[lzpos]) - continue; - - layer_data = fbdev_output_data_get_layer_data(hwc_data->output_data, lzpos); - if (!layer_data) - continue; - - _fbdev_hwc_layer_attach_window(layer_data, NULL); - } - - /* for debug */ - for (lzpos = NUM_LAYERS -1 ; lzpos >= 0; lzpos--) { - if (use_layers_zpos[lzpos]) - TDM_BACKEND_INFO(" lzpos(%d) : %s", lzpos, use_layers_zpos[lzpos] ? "SET" : "UNSET"); - } - - return HAL_TDM_ERROR_NONE; -} - -/* assign the validated_type to the composited_wnds - * assign the layer_zpos to the composited_wnds - */ -static void -_fbdev_hwc_apply_policy(tdm_fbdev_hwc *hwc_data , hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds) -{ - tdm_fbdev_hwc_window *hwc_window_data = NULL; - tdm_fbdev_hwc_window **composited_list = NULL; - int client_count = 0; - int device_count = 0; - int video_count = 0; - int cursor_count = 0; - int ui_lzpos_top = ZPOS_0; - int ui_lzpos_bottom = ZPOS_0; - int num_ui_layers = NUM_UI_LAYERS; - int set_clients_below = 0; - int i = 0; - - composited_list = (tdm_fbdev_hwc_window **)composited_wnds; - - /* initialize the need_target_window */ - hwc_data->need_target_window = 0; - - /* initialize the validated_types */ - LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) { - if (hwc_window_data->validated_type != HAL_TDM_HWC_WIN_COMPOSITION_NONE) - hwc_window_data->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_NONE; - } - - /* use the target_window to commit when there is no window. */ - if (num_wnds == 0) { - hwc_data->need_target_window = 1; - hwc_data->target_hwc_window->lzpos = ui_lzpos_bottom; - return; - } - - /* 1. first check validate_type without target_window */ - for (i = 0; i < num_wnds; i++) { - switch (composited_list[i]->client_type) { - case HAL_TDM_HWC_WIN_COMPOSITION_VIDEO: - composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_VIDEO; - video_count++; - continue; - case HAL_TDM_HWC_WIN_COMPOSITION_CURSOR: - if (set_clients_below) break; - if (cursor_count > 0) break; - - composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_CURSOR; - cursor_count++; - continue; - case HAL_TDM_HWC_WIN_COMPOSITION_DEVICE: - if (set_clients_below) break; - if (num_ui_layers <= 0) break; - if (!_fbdev_hwc_window_can_set_on_hw_layer(composited_list[i])) break; - - composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_DEVICE; - device_count++; - num_ui_layers--; - continue; - default: - break; - } - - composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_CLIENT; - client_count++; - set_clients_below = 1; - } - - /* 2. check need target window and set ui_lzpos top and bottom */ - num_ui_layers = NUM_UI_LAYERS; - - if (video_count > 0) { - ui_lzpos_bottom++; - num_ui_layers--; - } - - if (client_count > 0) { - ui_lzpos_bottom++; - num_ui_layers--; - hwc_data->need_target_window = 1; - hwc_data->target_hwc_window->lzpos = ui_lzpos_bottom - 1; - } - - if (num_ui_layers > device_count) - ui_lzpos_top = ui_lzpos_bottom + device_count - 1; - - /* 3. set lzpos and modify validate_type with target_window */ - for (i = 0; i < num_wnds; i++) { - switch (composited_list[i]->validated_type) { - case HAL_TDM_HWC_WIN_COMPOSITION_VIDEO: - composited_list[i]->lzpos = ZPOS_VIDEO1; - continue; - case HAL_TDM_HWC_WIN_COMPOSITION_CURSOR: - composited_list[i]->lzpos = ZPOS_CURSOR; - continue; - case HAL_TDM_HWC_WIN_COMPOSITION_DEVICE: - if (num_ui_layers <= 0) break; - composited_list[i]->lzpos = ui_lzpos_top; - ui_lzpos_top--; - num_ui_layers--; - continue; - default: - break; - } - - composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_CLIENT; - composited_list[i]->lzpos = ZPOS_NONE; - } -} - -static int -_fbdev_hwc_get_changed_number(tdm_fbdev_hwc *hwc_data) -{ - int num = 0; - tdm_fbdev_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; -} - -hal_tdm_hwc_window * -_fbdev_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_hwc_window_info *info, hal_tdm_error *error) -{ - tdm_fbdev_hwc *hwc_data = hwc; - tdm_fbdev_hwc_window *hwc_window_data = NULL; - - 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_fbdev_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->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_hwc_window * -fbdev_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_error *error) -{ - tdm_fbdev_hwc *hwc_data = hwc; - tdm_fbdev_hwc_window *hwc_window_data = NULL; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, NULL); - - hwc_window_data = _fbdev_hwc_create_window(hwc_data, NULL, error); - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data, NULL); - - LIST_ADDTAIL(&hwc_window_data->link, &hwc_data->hwc_window_list); - - TDM_BACKEND_INFO("hwc_window(%p) create", hwc_window_data); - if (error) - *error = HAL_TDM_ERROR_NONE; - - return hwc_window_data; -} - -hal_tdm_error -fbdev_hwc_get_video_supported_formats(hal_tdm_hwc *hwc, const tbm_format **formats, int *count) -{ - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc != 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: fix these formats. - *formats = hwc_window_video_formats; - *count = sizeof(hwc_window_video_formats) / sizeof(tbm_format); - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_hwc_get_capabilities(hal_tdm_hwc *hwc, hal_tdm_hwc_capability *capabilities) -{ - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - TDM_BACKEND_RETURN_VAL_IF_FAIL(capabilities != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - - *capabilities |= HAL_TDM_HWC_CAPABILITY_VIDEO_SCALE; - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_hwc_get_available_properties(hal_tdm_hwc *hwc, const hal_tdm_prop **props, int *count) -{ - tdm_fbdev_hwc *hwc_data = hwc; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - TDM_BACKEND_RETURN_VAL_IF_FAIL(props != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - TDM_BACKEND_RETURN_VAL_IF_FAIL(count != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - - *props = NULL; - *count = 0; - - return HAL_TDM_ERROR_NONE; -} - -tbm_surface_queue_h -fbdev_hwc_get_client_target_buffer_queue(hal_tdm_hwc *hwc, hal_tdm_error *error) -{ - tdm_fbdev_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 = _fbdev_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 -fbdev_hwc_set_client_target_buffer(hal_tdm_hwc *hwc, tbm_surface_h buffer, hal_tdm_region damage) -{ - tdm_fbdev_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 = fbdev_hwc_window_set_buffer(hwc_data->target_hwc_window, buffer); - TDM_BACKEND_RETURN_VAL_IF_FAIL(err == HAL_TDM_ERROR_NONE, err); - - err = fbdev_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 -fbdev_hwc_validate(hal_tdm_hwc *hwc, hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types) -{ - tdm_fbdev_hwc *hwc_data = hwc; - tdm_fbdev_output *output_data; - - 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); - - output_data = hwc_data->output_data; - TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - - TDM_BACKEND_INFO(" ==============Validate================================="); - - _fbdev_hwc_apply_policy(hwc_data, composited_wnds, num_wnds); - - *num_types = _fbdev_hwc_get_changed_number(hwc_data); - - _print_validate_result(hwc_data, composited_wnds, num_wnds); - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_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_fbdev_hwc *hwc_data = hwc; - tdm_fbdev_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 = _fbdev_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 -fbdev_hwc_accept_validation(hal_tdm_hwc *hwc) -{ - tdm_fbdev_hwc *hwc_data = hwc; - hal_tdm_error ret = HAL_TDM_ERROR_NONE; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data->output_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - - TDM_BACKEND_INFO(" ==============Accept Changes Done================================="); - - if (hwc_data->output_data->current_dpms != HAL_TDM_OUTPUT_DPMS_ON) { - TDM_BACKEND_ERR("dpms is not on. do not set buffer"); - return HAL_TDM_ERROR_BAD_REQUEST; - } - - ret = _fbdev_hwc_prepare_commit(hwc_data); - TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret); - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_hwc_commit(hal_tdm_hwc *hwc, int sync, void *user_data) -{ - tdm_fbdev_hwc *hwc_data = hwc; - tdm_fbdev_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; - TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER); - - TDM_BACKEND_INFO(" ==============COMMIT================================="); - - if (hwc_data->output_data->current_dpms != HAL_TDM_OUTPUT_DPMS_ON) { - TDM_BACKEND_ERR("dpms is not on. do not commit"); - return HAL_TDM_ERROR_BAD_REQUEST; - } - - ret = fbdev_output_commit(output_data, sync, user_data); - TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret); - - if (hwc_data->commit_func) - hwc_data->commit_func(hwc, output_data->sequence++, 0, 0, user_data); - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_hwc_set_commit_handler(hal_tdm_hwc *hwc, hal_tdm_hwc_commit_handler func) -{ - tdm_fbdev_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; -} - -hal_tdm_error -fbdev_hwc_target_window_set_info(tdm_fbdev_hwc *hwc_data, int width, int height) -{ - hal_tdm_hwc_window_info info = {0}; - tdm_fbdev_hwc_window *target_hwc_window; - hal_tdm_error ret = HAL_TDM_ERROR_NONE; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, HAL_TDM_ERROR_INVALID_PARAMETER); - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window, HAL_TDM_ERROR_INVALID_PARAMETER); - - target_hwc_window = hwc_data->target_hwc_window; - - info.dst_pos.x = 0; - info.dst_pos.y = 0; - info.dst_pos.w = width; - info.dst_pos.h = height; - - info.src_config.pos.x = 0; - info.src_config.pos.y = 0; - info.src_config.pos.w = width; - info.src_config.pos.h = height; - - info.src_config.size.h = width; - info.src_config.size.v = height; - info.src_config.format = TBM_FORMAT_ARGB8888; - - ret = fbdev_hwc_window_set_info(target_hwc_window, &info); - if (ret != HAL_TDM_ERROR_NONE) { - TDM_BACKEND_ERR("set info target hwc window failed (%d)", ret); - return HAL_TDM_ERROR_OPERATION_FAILED; - } - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_hwc_initailize_target_window(tdm_fbdev_hwc *hwc_data) -{ - hal_tdm_hwc_window_info info = {0}; - hal_tdm_error ret = HAL_TDM_ERROR_NONE; - tdm_fbdev_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.w = 2; - info.dst_pos.h = 1; - - info.src_config.pos.x = 0; - info.src_config.pos.y = 0; - info.src_config.pos.w = 2; - info.src_config.pos.h = 1; - - info.src_config.size.h = 2; - info.src_config.size.v = 1; - info.src_config.format = TBM_FORMAT_ARGB8888; - - target_hwc_window = _fbdev_hwc_create_window(hwc_data, &info, &ret); - if (ret != HAL_TDM_ERROR_NONE) { - TDM_BACKEND_ERR("create target hwc window failed (%d)", ret); - return HAL_TDM_ERROR_OPERATION_FAILED; - } - - if (hwc_data->target_hwc_window) - fbdev_hwc_window_destroy(hwc_data->target_hwc_window); - - hwc_data->target_hwc_window = target_hwc_window; - hwc_data->need_set_crtc = 1; - - return HAL_TDM_ERROR_NONE; -} diff --git a/src/libhal-backend-tdm-fbdev/tdm_fbdev_hwc_window.c b/src/libhal-backend-tdm-fbdev/tdm_fbdev_hwc_window.c deleted file mode 100644 index 55e2a71..0000000 --- a/src/libhal-backend-tdm-fbdev/tdm_fbdev_hwc_window.c +++ /dev/null @@ -1,184 +0,0 @@ -/************************************************************************** - -libtdm_fbdev - -Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: SooChan Lim - -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_fbdev.h" - -void -fbdev_hwc_window_destroy(hal_tdm_hwc_window *hwc_window) -{ - tdm_fbdev_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 -fbdev_hwc_window_set_composition_type(hal_tdm_hwc_window *hwc_window, - hal_tdm_hwc_window_composition comp_type) -{ - tdm_fbdev_hwc_window *hwc_window_data = hwc_window; - tdm_fbdev_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; - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_hwc_window_set_buffer_damage(hal_tdm_hwc_window *hwc_window, hal_tdm_region damage) -{ - tdm_fbdev_hwc_window *hwc_window_data = hwc_window; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - - //TODO:: - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_hwc_window_set_info(hal_tdm_hwc_window *hwc_window, hal_tdm_hwc_window_info *info) -{ - tdm_fbdev_hwc_window *hwc_window_data = hwc_window; - tdm_fbdev_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); - TDM_BACKEND_RETURN_VAL_IF_FAIL(info != 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; - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_hwc_window_set_buffer(hal_tdm_hwc_window *hwc_window, tbm_surface_h surface) -{ - tdm_fbdev_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 -fbdev_hwc_window_set_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value value) -{ - tdm_fbdev_hwc_window *hwc_window_data = hwc_window; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - - //TODO: - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_hwc_window_get_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value *value) -{ - tdm_fbdev_hwc_window *hwc_window_data = hwc_window; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - - //TODO: - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_hwc_window_get_constraints(hal_tdm_hwc_window *hwc_window, int *constraints) -{ - tdm_fbdev_hwc_window *hwc_window_data = hwc_window; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - TDM_BACKEND_RETURN_VAL_IF_FAIL(constraints != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - - // no constraints - *constraints = 0; - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_hwc_window_set_name(hal_tdm_hwc_window *hwc_window, const char *name) -{ - tdm_fbdev_hwc_window *hwc_window_data = hwc_window; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - - if (!name) - return HAL_TDM_ERROR_NONE; - - snprintf(hwc_window_data->name, HAL_TDM_NAME_LEN, "%s", name); - - return HAL_TDM_ERROR_NONE; -} - -hal_tdm_error -fbdev_hwc_window_set_cursor_image(hal_tdm_hwc_window *hwc_window, int width, int height, int stride, void *ptr) -{ - tdm_fbdev_hwc_window *hwc_window_data = hwc_window; - - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); - TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data->client_type == HAL_TDM_HWC_WIN_COMPOSITION_CURSOR, HAL_TDM_ERROR_INVALID_PARAMETER); - - hwc_window_data->cursor_img.width = width; - hwc_window_data->cursor_img.height = height; - hwc_window_data->cursor_img.stride = stride; - hwc_window_data->cursor_img.ptr = ptr; - - hwc_window_data->cursor_img_refresh = 1; - - return HAL_TDM_ERROR_NONE; -} diff --git a/src/libtdm-fbdev/Makefile.am b/src/libtdm-fbdev/Makefile.am deleted file mode 100644 index c0f804f..0000000 --- a/src/libtdm-fbdev/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -AM_CFLAGS = \ - $(TDM_DRM_CFLAGS) \ - -I$(top_srcdir)/src - -libtdm_fbdev_la_LTLIBRARIES = libtdm-fbdev.la -libtdm_fbdev_ladir = $(TDM_MODULE_PATH) -libtdm_fbdev_la_LDFLAGS = -module -avoid-version -libtdm_fbdev_la_LIBADD = $(TDM_DRM_LIBS) -ldl - -libtdm_fbdev_la_SOURCES = \ - tdm_fbdev_display.c \ - tdm_fbdev_hwc.c \ - tdm_fbdev_hwc_window.c \ - tdm_fbdev.c diff --git a/src/libtdm-fbdev/tdm_fbdev.c b/src/libtdm-fbdev/tdm_fbdev.c deleted file mode 100644 index c3b9b2d..0000000 --- a/src/libtdm-fbdev/tdm_fbdev.c +++ /dev/null @@ -1,335 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "tdm_fbdev.h" -#include - -#define TDM_FBDEV_NAME "fbdev" - -#define TDM_HWC 1 - -static tdm_fbdev_data *fbdev_data; - -static int -_tdm_fbdev_open_fbdev(void) -{ - const char *name = "/dev/fb0"; - int fd = -1; - - fd = open(name, O_RDWR); - if (fd < 0) { - TDM_ERR("Cannot open fbdev device.. search by udev"); - goto close; - } - - /* - * TODO: If we failed directly to open framebuffer device - * we would try to open it through udev - */ - -close: - - return fd; -} - -static tdm_error -_tdm_fbdev_init_internal(void) -{ - struct fb_fix_screeninfo *finfo = calloc(1, sizeof(struct fb_fix_screeninfo)); - struct fb_var_screeninfo *vinfo = calloc(1, sizeof(struct fb_var_screeninfo)); - int ret = -1; - - ret = ioctl(fbdev_data->fbdev_fd, FBIOGET_VSCREENINFO, vinfo); - if (ret < 0) { - TDM_ERR("FBIOGET_VSCREENINFO ioctl failed errno=%d", errno); - goto close_1; - } - - vinfo->reserved[0] = 0; - vinfo->reserved[1] = 0; - vinfo->reserved[2] = 0; - vinfo->xoffset = 0; - vinfo->yoffset = 0; - vinfo->activate = FB_ACTIVATE_NOW; - - /* - * Explicitly request 32 bits per pixel colors with corresponding - * red, blue and green color offsets and length of colors - */ - vinfo->bits_per_pixel = 32; - vinfo->red.offset = 16; - vinfo->red.length = 8; - vinfo->green.offset = 8; - vinfo->green.length = 8; - vinfo->blue.offset = 0; - vinfo->blue.length = 8; - vinfo->transp.offset = 0; - vinfo->transp.length = 0; - - vinfo->yres_virtual = vinfo->yres * MAX_BUF; - ret = ioctl(fbdev_data->fbdev_fd, FBIOPAN_DISPLAY, vinfo); - if (ret < 0) - TDM_ERR("FBIOPAN_DISPLAY ioctl failed, errno=%d", errno); - - ret = ioctl(fbdev_data->fbdev_fd, FBIOGET_FSCREENINFO, finfo); - if (ret < 0) { - TDM_ERR("FBIOGET_FSCREENINFO ioctl failed, errno=%d", errno); - goto close_1; - } - - if (finfo->smem_len <= 0) { - TDM_ERR("Length of frame buffer mem less then 0"); - goto close_1; - } - - fbdev_data->vinfo = vinfo; - fbdev_data->finfo = finfo; - - /* - * Output framebuffer's related information - */ - TDM_INFO("\n" - " VInfo\n" - " fb = %d\n" - " xres = %d px \n" - " yres = %d px \n" - " xres_virtual = %d px \n" - " yres_virtual = %d px \n" - " bpp = %d \n" - " r = %2u:%u\n" - " g = %2u:%u\n" - " b = %2u:%u\n" - " t = %2u:%u\n" - " active = %d \n" - " width = %d mm \n" - " height = %d mm \n", - fbdev_data->fbdev_fd, - vinfo->xres, - vinfo->yres, - vinfo->xres_virtual, - vinfo->yres_virtual, - vinfo->bits_per_pixel, - vinfo->red.offset, vinfo->red.length, - vinfo->green.offset, vinfo->green.length, - vinfo->blue.offset, vinfo->blue.length, - vinfo->transp.offset, vinfo->transp.length, - vinfo->activate, - vinfo->width, - vinfo->height); - - TDM_INFO("\n" - " FInfo\n" - " id = %s\n" - " smem_len = %d\n" - " line_length = %d\n", - finfo->id, - finfo->smem_len, - finfo->line_length); - - return TDM_ERROR_NONE; -close_1: - ret = TDM_ERROR_OPERATION_FAILED; - return ret; -} - -void -tdm_fbdev_deinit(tdm_backend_data *bdata) -{ - if (fbdev_data != bdata) - return; - - TDM_INFO("deinit"); - - close(fbdev_data->fbdev_fd); - - tdm_fbdev_destroy_layer(fbdev_data); - tdm_fbdev_destroy_output(fbdev_data); - - if (fbdev_data->vinfo) - free(fbdev_data->vinfo); - - if (fbdev_data->finfo) - free(fbdev_data->finfo); - - free(fbdev_data); - fbdev_data = NULL; -} - -tdm_backend_data* -tdm_fbdev_init(tdm_display *dpy, tdm_error *error) -{ - tdm_func_display fbdev_func_display; - tdm_func_output fbdev_func_output; - tdm_func_layer fbdev_func_layer; - tdm_func_hwc fbdev_func_hwc; - tdm_func_hwc_window fbdev_func_hwc_window; - tdm_error ret; - - if (!dpy) { - TDM_ERR("display is null"); - if (error) - *error = TDM_ERROR_BAD_REQUEST; - return NULL; - } - - if (fbdev_data) { - TDM_ERR("failed: init twice"); - if (error) - *error = TDM_ERROR_BAD_REQUEST; - return NULL; - } - - fbdev_data = calloc(1, sizeof(struct _tdm_fbdev_data)); - if (!fbdev_data) { - TDM_ERR("alloc failed"); - if (error) - *error = TDM_ERROR_OUT_OF_MEMORY; - return NULL; - } - -#if TDM_HWC - /* enable the tdm_hwc */ - fbdev_data->hwc_mode = 1; -#endif - - LIST_INITHEAD(&fbdev_data->buffer_list); - - memset(&fbdev_func_display, 0, sizeof(fbdev_func_display)); - fbdev_func_display.display_get_capability = fbdev_display_get_capability; - fbdev_func_display.display_get_outputs = fbdev_display_get_outputs; - fbdev_func_display.display_get_fd = NULL; - fbdev_func_display.display_handle_events = NULL; - - memset(&fbdev_func_output, 0, sizeof(fbdev_func_output)); - fbdev_func_output.output_get_capability = fbdev_output_get_capability; - fbdev_func_output.output_get_layers = fbdev_output_get_layers; - fbdev_func_output.output_set_property = fbdev_output_set_property; - fbdev_func_output.output_get_property = fbdev_output_get_property; - fbdev_func_output.output_wait_vblank = fbdev_output_wait_vblank; - fbdev_func_output.output_set_vblank_handler = fbdev_output_set_vblank_handler; - fbdev_func_output.output_commit = fbdev_output_commit; - fbdev_func_output.output_set_commit_handler = fbdev_output_set_commit_handler; - fbdev_func_output.output_set_dpms = fbdev_output_set_dpms; - fbdev_func_output.output_get_dpms = fbdev_output_get_dpms; - fbdev_func_output.output_set_mode = fbdev_output_set_mode; - fbdev_func_output.output_get_mode = fbdev_output_get_mode; - - if (fbdev_data->hwc_mode) { - fbdev_func_output.output_get_hwc = fbdev_output_get_hwc; - - memset(&fbdev_func_hwc, 0, sizeof(fbdev_func_hwc)); - fbdev_func_hwc.hwc_create_window = fbdev_hwc_create_window; - fbdev_func_hwc.hwc_get_video_supported_formats = fbdev_hwc_get_video_supported_formats; - fbdev_func_hwc.hwc_get_video_available_properties = NULL; - fbdev_func_hwc.hwc_get_capabilities = fbdev_hwc_get_capabilities; - fbdev_func_hwc.hwc_get_available_properties = fbdev_hwc_get_available_properties; - fbdev_func_hwc.hwc_get_client_target_buffer_queue = fbdev_hwc_get_client_target_buffer_queue; - fbdev_func_hwc.hwc_set_client_target_buffer = fbdev_hwc_set_client_target_buffer; - fbdev_func_hwc.hwc_validate = fbdev_hwc_validate; - fbdev_func_hwc.hwc_get_changed_composition_types = fbdev_hwc_get_changed_composition_types; - fbdev_func_hwc.hwc_accept_validation = fbdev_hwc_accept_validation; - fbdev_func_hwc.hwc_commit = fbdev_hwc_commit; - fbdev_func_hwc.hwc_set_commit_handler = fbdev_hwc_set_commit_handler; - - memset(&fbdev_func_hwc_window, 0, sizeof(fbdev_func_hwc_window)); - fbdev_func_hwc_window.hwc_window_destroy = fbdev_hwc_window_destroy; - fbdev_func_hwc_window.hwc_window_acquire_buffer_queue = NULL; // no need - fbdev_func_hwc_window.hwc_window_release_buffer_queue = NULL; // no need - fbdev_func_hwc_window.hwc_window_set_composition_type = fbdev_hwc_window_set_composition_type; - fbdev_func_hwc_window.hwc_window_set_buffer_damage = fbdev_hwc_window_set_buffer_damage; - fbdev_func_hwc_window.hwc_window_set_info = fbdev_hwc_window_set_info; - fbdev_func_hwc_window.hwc_window_set_buffer = fbdev_hwc_window_set_buffer; - fbdev_func_hwc_window.hwc_window_set_property = fbdev_hwc_window_set_property; - fbdev_func_hwc_window.hwc_window_get_property = fbdev_hwc_window_get_property; - fbdev_func_hwc_window.hwc_window_get_constraints = fbdev_hwc_window_get_constraints; - fbdev_func_hwc_window.hwc_window_set_name = fbdev_hwc_window_set_name; - fbdev_func_hwc_window.hwc_window_set_cursor_image = fbdev_hwc_window_set_cursor_image; - } - - memset(&fbdev_func_layer, 0, sizeof(fbdev_func_layer)); - fbdev_func_layer.layer_get_capability = fbdev_layer_get_capability; - fbdev_func_layer.layer_set_property = fbdev_layer_set_property; - fbdev_func_layer.layer_get_property = fbdev_layer_get_property; - fbdev_func_layer.layer_set_info = fbdev_layer_set_info; - fbdev_func_layer.layer_get_info = fbdev_layer_get_info; - fbdev_func_layer.layer_set_buffer = fbdev_layer_set_buffer; - fbdev_func_layer.layer_unset_buffer = fbdev_layer_unset_buffer; - - ret = tdm_backend_register_func_display(dpy, &fbdev_func_display); - if (ret != TDM_ERROR_NONE) - goto failed; - - ret = tdm_backend_register_func_output(dpy, &fbdev_func_output); - if (ret != TDM_ERROR_NONE) - goto failed; - - ret = tdm_backend_register_func_layer(dpy, &fbdev_func_layer); - if (ret != TDM_ERROR_NONE) - goto failed; - - if (fbdev_data->hwc_mode) { - ret = tdm_backend_register_func_hwc(dpy, &fbdev_func_hwc); - if (ret != TDM_ERROR_NONE) - goto failed; - - ret = tdm_backend_register_func_hwc_window(dpy, &fbdev_func_hwc_window); - if (ret != TDM_ERROR_NONE) - goto failed; - } - - fbdev_data->dpy = dpy; - - fbdev_data->fbdev_fd = _tdm_fbdev_open_fbdev(); - if (fbdev_data->fbdev_fd < 0) { - ret = TDM_ERROR_OPERATION_FAILED; - goto failed; - } - - ret = _tdm_fbdev_init_internal(); - if (ret != TDM_ERROR_NONE) { - TDM_INFO("init of framebuffer failed"); - goto failed; - } - - ret = tdm_fbdev_creat_output(fbdev_data); - if (ret != TDM_ERROR_NONE) { - TDM_INFO("init of output failed"); - goto failed_2; - } - - ret = tdm_fbdev_creat_layer(fbdev_data); - if (ret != TDM_ERROR_NONE) { - TDM_INFO("init of output failed"); - goto failed_3; - } - - TDM_INFO("init success!"); - - if (error) - *error = TDM_ERROR_NONE; - - return (tdm_backend_data*) fbdev_data; - -failed_3: - tdm_fbdev_destroy_layer(fbdev_data); -failed_2: - tdm_fbdev_destroy_output(fbdev_data); - -failed: - if (error) - *error = ret; - - tdm_fbdev_deinit(fbdev_data); - - TDM_ERR("init failed!"); - return NULL; -} - -tdm_backend_module tdm_backend_module_data = { - "fbdev", - "Samsung", - TDM_BACKEND_SET_ABI_VERSION(1, 1), - tdm_fbdev_init, - tdm_fbdev_deinit -}; diff --git a/src/libtdm-fbdev/tdm_fbdev.h b/src/libtdm-fbdev/tdm_fbdev.h deleted file mode 100644 index b76b896..0000000 --- a/src/libtdm-fbdev/tdm_fbdev.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef _TDM_fbdev_H_ -#define _TDM_fbdev_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include "tdm_fbdev_types.h" -#include "tdm_fbdev_hwc.h" -#include "tdm_fbdev_hwc_window.h" - -#define MAX_BUF 1 - -/* fbdev backend functions (display) */ -tdm_error fbdev_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps); -tdm_output** fbdev_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error); -tdm_error fbdev_display_get_fd(tdm_backend_data *bdata, int *fd); -tdm_error fbdev_display_handle_events(tdm_backend_data *bdata); -tdm_pp* fbdev_display_create_pp(tdm_backend_data *bdata, tdm_error *error); -tdm_error fbdev_output_get_capability(tdm_output *output, tdm_caps_output *caps); -tdm_layer** fbdev_output_get_layers(tdm_output *output, int *count, tdm_error *error); -tdm_error fbdev_output_set_property(tdm_output *output, unsigned int id, tdm_value value); -tdm_error fbdev_output_get_property(tdm_output *output, unsigned int id, tdm_value *value); -tdm_error fbdev_output_wait_vblank(tdm_output *output, int interval, int sync, void *user_data); -tdm_error fbdev_output_set_vblank_handler(tdm_output *output, tdm_output_vblank_handler func); -tdm_error fbdev_output_commit(tdm_output *output, int sync, void *user_data); -tdm_error fbdev_output_set_commit_handler(tdm_output *output, tdm_output_commit_handler func); -tdm_error fbdev_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value); -tdm_error fbdev_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value); -tdm_error fbdev_output_set_mode(tdm_output *output, const tdm_output_mode *mode); -tdm_error fbdev_output_get_mode(tdm_output *output, const tdm_output_mode **mode); -tdm_hwc *fbdev_output_get_hwc(tdm_output *output, tdm_error *error); - -tdm_hwc_window *fbdev_hwc_create_window(tdm_hwc *hwc, tdm_error *error); -tdm_error fbdev_hwc_get_video_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count); -tdm_error fbdev_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *capabilities); -tdm_error fbdev_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count); -tbm_surface_queue_h fbdev_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error); -tdm_error fbdev_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage); -tdm_error fbdev_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types); -tdm_error fbdev_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 fbdev_hwc_accept_validation(tdm_hwc *hwc); -tdm_error fbdev_hwc_commit(tdm_hwc *hwc, int sync, void *user_data); -tdm_error fbdev_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func); - -void fbdev_hwc_window_destroy(tdm_hwc_window *hwc_window); -tdm_error fbdev_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, tdm_hwc_window_composition composition_type); -tdm_error fbdev_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage); -tdm_error fbdev_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info); -tdm_error fbdev_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface); -tdm_error fbdev_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value); -tdm_error fbdev_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value); -tdm_error fbdev_hwc_window_get_constraints(tdm_hwc_window *hwc_window, int *constraints); -tdm_error fbdev_hwc_window_set_name(tdm_hwc_window *hwc_window, const char *name); -tdm_error fbdev_hwc_window_set_cursor_image(tdm_hwc_window *hwc_window, int width, int height, int stride, void *ptr); - -tdm_error fbdev_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps); -tdm_error fbdev_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value); -tdm_error fbdev_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value); -tdm_error fbdev_layer_set_info(tdm_layer *layer, tdm_info_layer *info); -tdm_error fbdev_layer_get_info(tdm_layer *layer, tdm_info_layer *info); -tdm_error fbdev_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer); -tdm_error fbdev_layer_unset_buffer(tdm_layer *layer); - - -tdm_error tdm_fbdev_creat_output(tdm_fbdev_data *fbdev_data); -void tdm_fbdev_destroy_output(tdm_fbdev_data *fbdev_data); - -tdm_error tdm_fbdev_creat_layer(tdm_fbdev_data *fbdev_data); -void tdm_fbdev_destroy_layer(tdm_fbdev_data *fbdev_data); - -tdm_fbdev_layer_data *fbdev_output_data_get_layer_data(tdm_fbdev_output_data *output_data, int layer_zops); - -#endif /* _TDM_fbdev_H_ */ diff --git a/src/libtdm-fbdev/tdm_fbdev_display.c b/src/libtdm-fbdev/tdm_fbdev_display.c deleted file mode 100644 index b9842d8..0000000 --- a/src/libtdm-fbdev/tdm_fbdev_display.c +++ /dev/null @@ -1,927 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "tdm_fbdev.h" - -#include -#include - -/* - * Framebuffer device supported formats - */ -static tbm_format supported_formats[] = { - /* - * TODO: add support of 16 bit formats - */ - TBM_FORMAT_ARGB8888, - TBM_FORMAT_ABGR8888, - TBM_FORMAT_RGBA8888, - TBM_FORMAT_BGRA8888, -}; - -static tdm_fbdev_display_buffer* -_tdm_fbdev_display_find_buffer(tdm_fbdev_data *fbdev_data, tbm_surface_h buffer) -{ - tdm_fbdev_display_buffer *display_buffer = NULL; - - LIST_FOR_EACH_ENTRY(display_buffer, &fbdev_data->buffer_list, link) - { - if (display_buffer->buffer == buffer) - return display_buffer; - } - - return NULL; -} - -static void -_tdm_fbdev_display_cb_destroy_buffer(tbm_surface_h buffer, void *user_data) -{ - tdm_fbdev_data *fbdev_data; - tdm_fbdev_display_buffer *display_buffer; - - if (!user_data) { - TDM_ERR("no user_data"); - return; - } - if (!buffer) { - TDM_ERR("no buffer"); - return; - } - - fbdev_data = (tdm_fbdev_data *) user_data; - - display_buffer = _tdm_fbdev_display_find_buffer(fbdev_data, buffer); - if (!display_buffer) { - TDM_ERR("no display_buffer"); - return; - } - - LIST_DEL(&display_buffer->link); - - free(display_buffer); -} - - -static inline uint32_t -_get_refresh(struct fb_var_screeninfo *timing) -{ - uint32_t pixclock, hfreq, htotal, vtotal; - - pixclock = PICOS2KHZ(timing->pixclock) * 1000; - - htotal = timing->xres + timing->right_margin + timing->hsync_len + timing->left_margin; - vtotal = timing->yres + timing->lower_margin + timing->vsync_len + timing->upper_margin; - - if (timing->vmode & FB_VMODE_INTERLACED) - vtotal /= 2; - if (timing->vmode & FB_VMODE_DOUBLE) - vtotal *= 2; - - hfreq = pixclock / htotal; - return hfreq / vtotal; -} - -/* - * Convert fb_var_screeninfo to tdm_output_mode - */ -static inline void -_tdm_fbdev_display_to_tdm_mode(struct fb_var_screeninfo *timing, tdm_output_mode *mode) -{ - - if (!timing->pixclock) - return; - - mode->clock = timing->pixclock / 1000; - mode->vrefresh = _get_refresh(timing); - mode->hdisplay = timing->xres; - mode->hsync_start = mode->hdisplay + timing->right_margin; - mode->hsync_end = mode->hsync_start + timing->hsync_len; - mode->htotal = mode->hsync_end + timing->left_margin; - - mode->vdisplay = timing->yres; - mode->vsync_start = mode->vdisplay + timing->lower_margin; - mode->vsync_end = mode->vsync_start + timing->vsync_len; - mode->vtotal = mode->vsync_end + timing->upper_margin; - - int interlaced = !!(timing->vmode & FB_VMODE_INTERLACED); - snprintf(mode->name, TDM_NAME_LEN, "%dx%d%s", mode->hdisplay, mode->vdisplay, interlaced ? "i" : ""); -} - -tdm_error -tdm_fbdev_creat_output(tdm_fbdev_data *fbdev_data) -{ - tdm_fbdev_output_data *output = NULL; - size_t size; - int i = 0; - - output = calloc(1, sizeof(tdm_fbdev_output_data)); - if (output == NULL) { - TDM_ERR("alloc output failed"); - return TDM_ERROR_OUT_OF_MEMORY; - } - - /* - * TODO: Size of framebuffer must be aligned to system page size before - * it is mapped - */ - size = fbdev_data->vinfo->xres * fbdev_data->vinfo->yres * fbdev_data->vinfo->bits_per_pixel / 8 * MAX_BUF; - - TDM_INFO("\n" "MMaped size: %zu\n", size); - - output->mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fbdev_data->fbdev_fd, 0); - if (output->mem == MAP_FAILED) { - TDM_ERR("MMap framebuffer failed, errno=%d", errno); - return TDM_ERROR_OPERATION_FAILED; - } - - memset(output->mem, 0, size); - - output->width = fbdev_data->vinfo->xres; - output->height = fbdev_data->vinfo->yres; - output->pitch = fbdev_data->vinfo->width; - output->bpp = fbdev_data->vinfo->bits_per_pixel; - output->size = size; - output->max_width = fbdev_data->vinfo->xres_virtual; - output->max_height = fbdev_data->vinfo->yres_virtual; - - output->status = TDM_OUTPUT_CONN_STATUS_CONNECTED; - output->connector_type = TDM_OUTPUT_TYPE_LVDS; - - output->is_vblank = DOWN; - output->is_commit = DOWN; - output->sequence = 1; - - /* - * TODO: connector_type_id field relates to libdrm connector which framebuffer - * does not know. It have to be checked whether softaware above us use this - * field for its purposes. - */ - output->connector_type_id = 1; - - output->count_modes = 1; - output->output_modes = calloc(output->count_modes, sizeof(tdm_output_mode)); - if (!output->output_modes) { - TDM_ERR("failed: alloc memory"); - return TDM_ERROR_OUT_OF_MEMORY; - } - - for (i = 0; i < output->count_modes; i++) { - _tdm_fbdev_display_to_tdm_mode(fbdev_data->vinfo, &output->output_modes[i]); - - sprintf(output->output_modes[i].name, "%dx%d", fbdev_data->vinfo->xres, fbdev_data->vinfo->yres); - } - - /* - * We currently support only one mode - */ - if (output->count_modes == 1) { - output->current_mode = &output->output_modes[0]; - output->status = TDM_OUTPUT_CONN_STATUS_MODE_SETTED; - } - - output->fbdev_data = fbdev_data; - fbdev_data->fbdev_output = output; - - if (fbdev_data->hwc_mode) - output->hwc_enable = 1; - - return TDM_ERROR_NONE; -} - -void -tdm_fbdev_destroy_output(tdm_fbdev_data *fbdev_data) -{ - tdm_fbdev_output_data *fbdev_output = fbdev_data->fbdev_output; - tdm_fbdev_hwc_data *hwc_data = NULL; - - if (fbdev_output == NULL) - goto close; - - hwc_data = fbdev_output->hwc_data; - if (hwc_data && hwc_data->target_hwc_window) - fbdev_hwc_window_destroy(hwc_data->target_hwc_window); - - if (fbdev_output->mem == NULL) - goto close_2; - - munmap(fbdev_output->mem, fbdev_output->size); - - if (fbdev_output->output_modes == NULL) - goto close_2; - - free(fbdev_output->output_modes); - -close_2: - free(fbdev_output); -close: - return; -} - -tdm_error -tdm_fbdev_creat_layer(tdm_fbdev_data *fbdev_data) -{ - tdm_fbdev_layer_data *layer; - tdm_fbdev_output_data *fbdev_output = fbdev_data->fbdev_output; - - /* - * Framebuffer does not support layer, therefore create only - * one layer by libtdm's demand; - */ - layer = calloc(1, sizeof(tdm_fbdev_layer_data)); - if (layer == NULL) { - TDM_ERR("alloc output failed"); - return TDM_ERROR_OUT_OF_MEMORY; - } - - layer->capabilities = TDM_LAYER_CAPABILITY_PRIMARY | TDM_LAYER_CAPABILITY_GRAPHIC; - - layer->fbdev_data = fbdev_data; - layer->fbdev_output = fbdev_output; - fbdev_output->fbdev_layer = layer; - - return TDM_ERROR_NONE; -} - -void -tdm_fbdev_destroy_layer(tdm_fbdev_data *fbdev_data) -{ - tdm_fbdev_output_data *fbdev_output = fbdev_data->fbdev_output; - tdm_fbdev_layer_data *layer = fbdev_output->fbdev_layer; - - if (layer != NULL) - free(layer); -} - -tdm_error -fbdev_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps) -{ - RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER); - - /* - * Framebuffer does not support layer, therefore create only - * one layer by libtdm's demand; - */ - caps->max_layer_count = 1; - - return TDM_ERROR_NONE; -} - -tdm_output** -fbdev_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error) -{ - tdm_fbdev_data *fbdev_data = bdata; - tdm_fbdev_output_data *fbdev_output = fbdev_data->fbdev_output; - tdm_output **outputs; - tdm_error ret; - - RETURN_VAL_IF_FAIL(fbdev_data, NULL); - RETURN_VAL_IF_FAIL(count, NULL); - - if (fbdev_output == NULL) { - ret = TDM_ERROR_NONE; - goto failed_get; - } - - /* - * Since it is Framebuffer device there is only one output - */ - *count = 1; - - /* will be freed in frontend */ - outputs = calloc(*count, sizeof(tdm_fbdev_output_data*)); - if (!outputs) { - TDM_ERR("failed: alloc memory"); - *count = 0; - ret = TDM_ERROR_OUT_OF_MEMORY; - goto failed_get; - } - - outputs[0] = fbdev_output; - - if (error) - *error = TDM_ERROR_NONE; - - return outputs; - -failed_get: - - if (error) - *error = ret; - return NULL; -} - -tdm_error -fbdev_display_handle_events(tdm_backend_data *bdata) -{ - tdm_fbdev_data *fbdev_data = (tdm_fbdev_data *) bdata; - void *user_data; - tdm_fbdev_output_data *fbdev_output; - tdm_fbdev_hwc_data *hwc_data; - unsigned int sequence = 0; - unsigned int tv_sec = 0; - unsigned int tv_usec = 0; - - RETURN_VAL_IF_FAIL(fbdev_data, TDM_ERROR_INVALID_PARAMETER); - - fbdev_output = fbdev_data->fbdev_output; - user_data = fbdev_output->user_data; - - RETURN_VAL_IF_FAIL(user_data, TDM_ERROR_INVALID_PARAMETER); - - /* - (tdm_output *output, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, - void *user_data); - */ - - /* - * Framebuffer does not produce events - * Fake flags are used to simulate event-operated back end. Since tdm - * library assumes its back ends to be event-operated and Framebuffer - * device is not event-operated we have to make fake events - */ - if (fbdev_output->is_vblank && fbdev_output->vblank_func) { - fbdev_output->is_vblank = DOWN; - - fbdev_output->vblank_func((tdm_output *) fbdev_data, sequence, tv_sec, tv_usec, user_data); - } - - if (fbdev_output->is_commit) { - if (fbdev_output->hwc_enable) { - hwc_data = fbdev_output->hwc_data; - - if (hwc_data && hwc_data->commit_func) { - fbdev_output->is_commit = DOWN; - hwc_data->commit_func(hwc_data, sequence, tv_sec, tv_usec, user_data); - } - } else { - if (fbdev_output->commit_func) { - fbdev_output->is_commit = DOWN; - fbdev_output->commit_func((tdm_output *) fbdev_data, sequence, tv_sec, tv_usec, user_data); - } - } - } - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_output_get_capability(tdm_output *output, tdm_caps_output *caps) -{ - tdm_fbdev_output_data *fbdev_output = (tdm_fbdev_output_data *) output; - tdm_fbdev_data *fbdev_data = NULL; - tdm_error ret; - int i = 0; - - RETURN_VAL_IF_FAIL(fbdev_output, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER); - - memset(caps, 0, sizeof(tdm_caps_output)); - - fbdev_data = fbdev_output->fbdev_data; - - snprintf(caps->maker, TDM_NAME_LEN, "unknown"); - snprintf(caps->model, TDM_NAME_LEN, "unknown"); - snprintf(caps->name, TDM_NAME_LEN, "unknown"); - - caps->status = fbdev_output->status; - caps->type = fbdev_output->connector_type; - caps->type_id = fbdev_output->connector_type_id; - - caps->mode_count = fbdev_output->count_modes; - caps->modes = calloc(caps->mode_count, sizeof(tdm_output_mode)); - if (!caps->modes) { - ret = TDM_ERROR_OUT_OF_MEMORY; - TDM_ERR("alloc failed\n"); - goto failed_get; - } - - for (i = 0; i < caps->mode_count; i++) - caps->modes[i] = fbdev_output->output_modes[i]; - - caps->mmWidth = fbdev_data->vinfo->width; - caps->mmHeight = fbdev_data->vinfo->height; - caps->subpixel = -1; - - caps->min_w = fbdev_output->width; - caps->min_h = fbdev_output->height; - caps->max_w = fbdev_output->max_width; - caps->max_h = fbdev_output->max_height; - caps->preferred_align = -1; - - /* - * Framebuffer does not have output properties - */ - caps->prop_count = 0; - caps->props = NULL; - - if (fbdev_output->hwc_enable) - caps->capabilities |= TDM_OUTPUT_CAPABILITY_HWC; - - return TDM_ERROR_NONE; - -failed_get: - memset(caps, 0, sizeof(tdm_caps_output)); - return ret; -} - -tdm_layer** -fbdev_output_get_layers(tdm_output *output, int *count, tdm_error *error) -{ - tdm_fbdev_output_data *fbdev_output = (tdm_fbdev_output_data *) output; - tdm_layer **layers; - tdm_error ret; - - RETURN_VAL_IF_FAIL(fbdev_output, NULL); - RETURN_VAL_IF_FAIL(count, NULL); - - if (fbdev_output->hwc_enable) { - *count = 0; - ret = TDM_ERROR_NONE; - goto failed_get; - } - - /* - * Framebuffer does not support layer, therefore create only - * one layer by libtdm's demand; - */ - *count = 1; - - layers = calloc(*count, sizeof(tdm_layer)); - if (layers == NULL) { - TDM_ERR("failed: alloc memory"); - *count = 0; - ret = TDM_ERROR_OUT_OF_MEMORY; - goto failed_get; - } - - layers[0] = fbdev_output->fbdev_layer; - - if (error) - *error = TDM_ERROR_NONE; - - return layers; - -failed_get: - - if (error) - *error = ret; - - return NULL; -} - -tdm_error -fbdev_output_set_property(tdm_output *output, unsigned int id, tdm_value value) -{ - /* - * Framebuffer does not have output properties - */ - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_output_get_property(tdm_output *output, unsigned int id, tdm_value *value) -{ - /* - * Framebuffer does not have output properties - */ - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_output_wait_vblank(tdm_output *output, int interval, int sync, void *user_data) -{ - tdm_fbdev_output_data *fbdev_output = (tdm_fbdev_output_data *) output; - tdm_fbdev_data *fbdev_data; - - int crtc = 0; - int ret; - - RETURN_VAL_IF_FAIL(fbdev_output, TDM_ERROR_INVALID_PARAMETER); - - /* - * Frame buffer device does not support asynchronous events, that is - * why clients must get responsibility on handling asynchronous - * events. - */ - if (!sync) { - TDM_WRN("Framebuffer back end does not support asynchronous vblank"); - return TDM_ERROR_NONE; - } - - fbdev_data = fbdev_output->fbdev_data; - - ret = ioctl(fbdev_data->fbdev_fd, FBIO_WAITFORVSYNC, &crtc); - if (ret < 0) { - TDM_ERR("FBIO_WAITFORVSYNC ioctl failed, errno=%d", errno); - return TDM_ERROR_OPERATION_FAILED; - } - - /* - * Up fake flag to simulate vsync event - */ - fbdev_output->is_vblank = UP; - fbdev_output->user_data = user_data; - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_output_set_vblank_handler(tdm_output *output, tdm_output_vblank_handler func) -{ - tdm_fbdev_output_data *fbdev_output = (tdm_fbdev_output_data *) output; - - RETURN_VAL_IF_FAIL(fbdev_output, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER); - - fbdev_output->vblank_func = func; - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_output_commit(tdm_output *output, int sync, void *user_data) -{ - tdm_fbdev_output_data *fbdev_output = (tdm_fbdev_output_data *) output; - tdm_fbdev_layer_data *fbdev_layer; - tdm_fbdev_display_buffer *display_buffer; - tbm_bo bo; - tbm_bo_handle bo_handle; - - RETURN_VAL_IF_FAIL(fbdev_output, TDM_ERROR_INVALID_PARAMETER); - - fbdev_layer = fbdev_output->fbdev_layer; - - if (!fbdev_layer->display_buffer_changed) - return TDM_ERROR_NONE; - - fbdev_output->mode_changed = 0; - fbdev_layer->display_buffer_changed = 0; - fbdev_layer->info_changed = 0; - - display_buffer = fbdev_layer->display_buffer; - - bo = tbm_surface_internal_get_bo(display_buffer->buffer, 0); - if (!bo) { - TDM_ERR("get bo fail"); - return TDM_ERROR_OPERATION_FAILED; - } - - bo_handle = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_READ); - if (!bo_handle.ptr) { - TDM_ERR("map bo fail"); - return TDM_ERROR_OPERATION_FAILED; - } - - /* - * Display buffer's content to screen - */ - memcpy(fbdev_output->mem, bo_handle.ptr, tbm_bo_size(bo) * sizeof(char)); - - tbm_bo_unmap(bo); - - if (fbdev_output->commit_func) { - TDM_ERR("trace"); - fbdev_output->commit_func((tdm_output *) output, fbdev_output->sequence++, 0, 0, user_data); - } - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_output_set_commit_handler(tdm_output *output, tdm_output_commit_handler func) -{ - tdm_fbdev_output_data *fbdev_output = (tdm_fbdev_output_data *) output; - - RETURN_VAL_IF_FAIL(fbdev_output, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER); - - fbdev_output->commit_func = func; - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) -{ - tdm_fbdev_output_data *fbdev_output = (tdm_fbdev_output_data *) output; - tdm_fbdev_data *fbdev_data; - int fbmode = 0; - int ret; - - RETURN_VAL_IF_FAIL(fbdev_output, TDM_ERROR_INVALID_PARAMETER); - - /* - * Bypass context switching overhead - */ - if (fbdev_output->dpms_value == dpms_value) - return TDM_ERROR_NONE; - - fbdev_data = fbdev_output->fbdev_data; - - switch (dpms_value) { - case TDM_OUTPUT_DPMS_ON: - fbmode = FB_BLANK_UNBLANK; - break; - - case TDM_OUTPUT_DPMS_OFF: - fbmode = FB_BLANK_POWERDOWN; - break; - - case TDM_OUTPUT_DPMS_STANDBY: - fbmode = FB_BLANK_VSYNC_SUSPEND; - break; - - case TDM_OUTPUT_DPMS_SUSPEND: - fbmode = FB_BLANK_HSYNC_SUSPEND; - break; - - default: - NEVER_GET_HERE(); - break; - } - - ret = ioctl(fbdev_data->fbdev_fd, FBIOBLANK, &fbmode); - if (ret < 0) { - TDM_ERR("FBIOBLANK ioctl failed, errno=%d", errno); - return TDM_ERROR_OPERATION_FAILED; - } - - /* - * TODO: framebuffer have to be reinitialized again, Maybe - */ - - fbdev_output->dpms_value = dpms_value; - fbmode = 0; - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value) -{ - tdm_fbdev_output_data *fbdev_output = (tdm_fbdev_output_data *) output; - - RETURN_VAL_IF_FAIL(fbdev_output, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(dpms_value, TDM_ERROR_INVALID_PARAMETER); - - *dpms_value = fbdev_output->dpms_value; - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_output_set_mode(tdm_output *output, const tdm_output_mode *mode) -{ - tdm_fbdev_output_data *fbdev_output = (tdm_fbdev_output_data *) output; - - RETURN_VAL_IF_FAIL(fbdev_output, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER); - - /* - * We currently support only one mode - */ - if (fbdev_output->count_modes == 1) - return TDM_ERROR_NONE; - - /* - * TODO: Implement mode switching - */ - fbdev_output->mode_changed = 0; - - /* create or replace the target_window when the output mode is set */ - if (fbdev_output->hwc_enable) { - fbdev_hwc_target_window_set_info(fbdev_output->hwc_data, fbdev_output->current_mode->hdisplay, fbdev_output->current_mode->vdisplay); - } - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_output_get_mode(tdm_output *output, const tdm_output_mode **mode) -{ - tdm_fbdev_output_data *fbdev_output = (tdm_fbdev_output_data *) output; - - RETURN_VAL_IF_FAIL(fbdev_output, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER); - - *mode = fbdev_output->current_mode; - - return TDM_ERROR_NONE; -} - -tdm_hwc * -fbdev_output_get_hwc(tdm_output *output, tdm_error *error) -{ - tdm_fbdev_hwc_data *hwc_data = NULL; - tdm_fbdev_output_data *output_data = output; - tdm_error ret = TDM_ERROR_NONE; - - 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_fbdev_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; - - ret = fbdev_hwc_initailize_target_window(output_data->hwc_data); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("create target hwc window failed (%d)", ret); - free(hwc_data); - if (error) - *error = ret; - return NULL; - } - - if (error) - *error = TDM_ERROR_NONE; - - return hwc_data; -} - -tdm_fbdev_layer_data * -fbdev_output_data_get_layer_data(tdm_fbdev_output_data *output_data, int layer_zpos) -{ - RETURN_VAL_IF_FAIL(output_data, NULL); - - if (layer_zpos == 0) - return output_data->fbdev_layer; - - return NULL; -} - -tdm_error -fbdev_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps) -{ - tdm_fbdev_layer_data *fbdev_layer = (tdm_fbdev_layer_data *) layer; - tdm_error ret; - int i; - - RETURN_VAL_IF_FAIL(fbdev_layer, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER); - - memset(caps, 0, sizeof(tdm_caps_layer)); - - caps->capabilities = fbdev_layer->capabilities; - - /* - * Make our single GRAPHIC layer the lowest one aka "Prime" - */ - caps->zpos = 0; - - caps->format_count = sizeof(supported_formats) / sizeof(supported_formats[0]); - caps->formats = calloc(caps->format_count, sizeof(tbm_format)); - if (!caps->formats) { - ret = TDM_ERROR_OUT_OF_MEMORY; - TDM_ERR("alloc failed\n"); - goto failed_get; - } - - for (i = 0; i < caps->format_count; i++) - caps->formats[i] = supported_formats[i]; - - /* - * Framebuffer does not have layer properties - */ - caps->prop_count = 0; - caps->props = NULL; - - return TDM_ERROR_NONE; - -failed_get: - - memset(caps, 0, sizeof(tdm_caps_layer)); - return ret; -} - -tdm_error -fbdev_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value) -{ - /* - * Framebuffer does not have layer properties - */ - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value) -{ - /* - * Framebuffer does not have layer properties - */ - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_layer_set_info(tdm_layer *layer, tdm_info_layer *info) -{ - tdm_fbdev_layer_data *fbdev_layer = (tdm_fbdev_layer_data *) layer; - - RETURN_VAL_IF_FAIL(fbdev_layer, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER); - - fbdev_layer->info = *info; - - /* - * We do not use info in this backend, therefore just ignore - * info's changing - */ - fbdev_layer->info_changed = 0; - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_layer_get_info(tdm_layer *layer, tdm_info_layer *info) -{ - tdm_fbdev_layer_data *fbdev_layer = (tdm_fbdev_layer_data *) layer; - - RETURN_VAL_IF_FAIL(fbdev_layer, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER); - - *info = fbdev_layer->info; - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) -{ - tdm_fbdev_layer_data *fbdev_layer = (tdm_fbdev_layer_data *) layer; - tdm_fbdev_display_buffer *display_buffer; - tdm_fbdev_data *fbdev_data; - tdm_error err = TDM_ERROR_NONE; - - RETURN_VAL_IF_FAIL(fbdev_layer, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(buffer, TDM_ERROR_INVALID_PARAMETER); - - if (tbm_surface_internal_get_num_bos(buffer) > 1) { - TDM_ERR("Framebuffer backend does not support surfaces with more than one bos"); - return TDM_ERROR_INVALID_PARAMETER; - } - - fbdev_data = fbdev_layer->fbdev_data; - - display_buffer = _tdm_fbdev_display_find_buffer(fbdev_data, buffer); - if (!display_buffer) { - display_buffer = calloc(1, sizeof(tdm_fbdev_display_buffer)); - if (display_buffer == NULL) { - TDM_ERR("alloc failed"); - return TDM_ERROR_OUT_OF_MEMORY; - } - - display_buffer->buffer = buffer; - display_buffer->width = tbm_surface_get_width(buffer); - display_buffer->height = tbm_surface_get_height(buffer); - - err = tdm_buffer_add_destroy_handler(buffer, _tdm_fbdev_display_cb_destroy_buffer, fbdev_data); - if (err != TDM_ERROR_NONE) { - TDM_ERR("add destroy handler fail"); - free(display_buffer); - return TDM_ERROR_OPERATION_FAILED; - } - - LIST_ADDTAIL(&display_buffer->link, &fbdev_data->buffer_list); - } - - fbdev_layer->display_buffer = display_buffer; - fbdev_layer->display_buffer_changed = 1; - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_layer_unset_buffer(tdm_layer *layer) -{ - tdm_fbdev_layer_data *fbdev_layer = (tdm_fbdev_layer_data *) layer; - - RETURN_VAL_IF_FAIL(fbdev_layer, TDM_ERROR_INVALID_PARAMETER); - - fbdev_layer->display_buffer = NULL; - fbdev_layer->display_buffer_changed = 1; - - return TDM_ERROR_NONE; -} diff --git a/src/libtdm-fbdev/tdm_fbdev_hwc.c b/src/libtdm-fbdev/tdm_fbdev_hwc.c deleted file mode 100644 index ed366c1..0000000 --- a/src/libtdm-fbdev/tdm_fbdev_hwc.c +++ /dev/null @@ -1,804 +0,0 @@ -/************************************************************************** - -libtdm_fbdev - -Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: SooChan Lim - -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 -#include "tdm_fbdev.h" - -#define MIN_WIDTH 32 - -#define NUM_LAYERS 4 -#define NUM_BUFFERS 3 - -#define NUM_UI_LAYERS 1 - -#define ZPOS_MAX 1 -#define ZPOS_CURSOR 2 -#define ZPOS_1 1 -#define ZPOS_0 0 -#define ZPOS_VIDEO1 0 -#define ZPOS_NONE -999 - -tbm_format hwc_window_video_formats[] = { - TBM_FORMAT_NV12, - TBM_FORMAT_YUV420 -}; - -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 -_fbdev_hwc_cursor_buffer_unset(tdm_fbdev_hwc_window_data *hwc_window_data) -{ - hwc_window_data->surface = NULL; - hwc_window_data->cursor_img_surface = 0; - - hwc_window_data->info.src_config.pos.w = hwc_window_data->cursor_img.width; - hwc_window_data->info.src_config.pos.h = hwc_window_data->cursor_img.height; - hwc_window_data->info.dst_pos.w = hwc_window_data->cursor_img.width; - hwc_window_data->info.dst_pos.h = hwc_window_data->cursor_img.height; - - return 1; -} - -static void -_fbdev_hwc_cursor_adjust_pos(tdm_fbdev_hwc_window_data *hwc_window_data) -{ - int x, y; - - /* dst pos of cursor is possible set by negative value - * this is temporary code. - */ - - x = hwc_window_data->info.dst_pos.x; - y = hwc_window_data->info.dst_pos.y; - - if (x < 0) hwc_window_data->info.dst_pos.x = 0; - if (y < 0) hwc_window_data->info.dst_pos.y = 0; -} - -static int -_fbdev_hwc_cursor_buffer_set(tdm_fbdev_hwc_data *hwc_data, tdm_fbdev_hwc_window_data *hwc_window_data) -{ - tbm_surface_h cursor_tsurface = NULL; - tbm_surface_info_s tsurface_info; - tbm_surface_error_e ret = TBM_SURFACE_ERROR_NONE; - int img_w, img_h, new_w, new_h; - tbm_format new_format; - unsigned int flags = TBM_BO_SCANOUT; - void *src_ptr = NULL, *dst_ptr = NULL; - int src_stride; - int i; - - _fbdev_hwc_cursor_adjust_pos(hwc_window_data); - - if (!hwc_window_data->cursor_img_refresh && hwc_window_data->surface) - return 1; - - img_w = hwc_window_data->cursor_img.width; - img_h = hwc_window_data->cursor_img.height; - new_format = hwc_window_data->info.src_config.format; - - /* cursor restriction to set the cursor layer */ - new_w = (CURSOR_MIN_W > img_w) ? CURSOR_MIN_W : img_w; - new_h = (CURSOR_MIN_H > img_h) ? CURSOR_MIN_H : img_h; - - if (hwc_data->cursor_tsurface) { - tbm_surface_internal_unref(hwc_data->cursor_tsurface); - hwc_data->cursor_tsurface = NULL; - } - - cursor_tsurface = tbm_surface_internal_create_with_flags(new_w, new_h, new_format, flags); - RETURN_VAL_IF_FAIL(cursor_tsurface, 0); - - hwc_data->cursor_tsurface = cursor_tsurface; - ret = tbm_surface_map(hwc_data->cursor_tsurface, TBM_SURF_OPTION_WRITE, &tsurface_info); - if (ret != TBM_SURFACE_ERROR_NONE) { - TDM_ERR("Failed to map tsurface\n"); - tbm_surface_internal_unref(hwc_data->cursor_tsurface); - hwc_data->cursor_tsurface = NULL; - return 0; - } - - src_ptr = hwc_window_data->cursor_img.ptr; - dst_ptr = tsurface_info.planes[0].ptr; - src_stride = hwc_window_data->cursor_img.stride; - - memset(dst_ptr, 0, tsurface_info.planes[0].stride * tsurface_info.height); - - for (i = 0 ; i < img_h ; i++) { - memcpy(dst_ptr, src_ptr, src_stride); - dst_ptr += tsurface_info.planes[0].stride; - src_ptr += src_stride; - } - - tbm_surface_unmap(hwc_data->cursor_tsurface); - - hwc_window_data->surface = hwc_data->cursor_tsurface; - hwc_window_data->cursor_img_surface = 1; - - /* fix the dst_pos info of the cursor window */ - hwc_window_data->info.src_config.pos.w = new_w; - hwc_window_data->info.src_config.pos.h = new_h; - hwc_window_data->info.dst_pos.w = new_w; - hwc_window_data->info.dst_pos.h = new_h; - - hwc_window_data->cursor_img_refresh = 0; - - return 1; -} - -static void -_print_validate_result(tdm_fbdev_hwc_data *hwc_data, tdm_hwc_window **composited_wnds, uint32_t num_wnds) -{ - tdm_fbdev_hwc_window_data *hwc_window_data = NULL; - int i; - - for (i = 0; i < num_wnds; i++) { - hwc_window_data = composited_wnds[i]; - switch (hwc_window_data->validated_type) { - case TDM_HWC_WIN_COMPOSITION_CLIENT: - TDM_INFO(" window(%p) %s -> %s : lzpos(%d) -- {%s} on TARGET WINDOW", hwc_window_data, - _comp_to_str(hwc_window_data->client_type), - _comp_to_str(hwc_window_data->validated_type), - hwc_data->target_hwc_window->lzpos, - hwc_window_data->name ? hwc_window_data->name : "NONE"); - break; - case TDM_HWC_WIN_COMPOSITION_DEVICE: - case TDM_HWC_WIN_COMPOSITION_VIDEO: - case TDM_HWC_WIN_COMPOSITION_CURSOR: - case TDM_HWC_WIN_COMPOSITION_NONE: - TDM_INFO(" window(%p) %s -> %s : lzpos(%d) -- {%s}", hwc_window_data, - _comp_to_str(hwc_window_data->client_type), - _comp_to_str(hwc_window_data->validated_type), - hwc_window_data->lzpos, - hwc_window_data->name ? hwc_window_data->name : "NONE"); - break; - default: - break; - } - } -} - -static int -_fbdev_hwc_window_can_set_on_hw_layer(tdm_fbdev_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.pos.w < MIN_WIDTH || hwc_window_data->info.src_config.pos.w % 2) - return 0; - - return 1; -} - -static tbm_surface_queue_h -_fbdev_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error) -{ - tdm_fbdev_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(NUM_BUFFERS, 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; -} - -static tdm_error -_fbdev_hwc_layer_attach_window(tdm_fbdev_layer_data *layer_data, tdm_fbdev_hwc_window_data *hwc_window_data) -{ - tdm_error ret = TDM_ERROR_NONE; - - RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_OPERATION_FAILED); - - if (hwc_window_data == NULL || hwc_window_data->surface == NULL) { - if (layer_data->display_buffer) - ret = fbdev_layer_unset_buffer(layer_data); - RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); - } else { - ret = fbdev_layer_set_info((tdm_layer *)layer_data, (tdm_info_layer *)&(hwc_window_data->info)); - RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); - RETURN_VAL_IF_FAIL(hwc_window_data->surface != NULL, TDM_ERROR_INVALID_PARAMETER); - ret = fbdev_layer_set_buffer(layer_data, hwc_window_data->surface); - RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); - } - - return ret; -} - -static tdm_error -_fbdev_hwc_prepare_commit(tdm_fbdev_hwc_data *hwc_data) -{ - tdm_fbdev_hwc_window_data *hwc_window_data = NULL; - tdm_fbdev_layer_data *layer_data = NULL; - int use_layers_zpos[NUM_LAYERS] = {0,}; - int lzpos = 0; - - /* set target hwc window to the layer */ - if (hwc_data->need_target_window) { - layer_data = fbdev_output_data_get_layer_data(hwc_data->output_data, hwc_data->target_hwc_window->lzpos); - _fbdev_hwc_layer_attach_window(layer_data, hwc_data->target_hwc_window); - use_layers_zpos[hwc_data->target_hwc_window->lzpos] = 1; - } - - /* set the hwc_windows to the layers */ - LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) { - if (hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_NONE || - hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_CLIENT) { - - if (hwc_window_data->cursor_img_surface) - _fbdev_hwc_cursor_buffer_unset(hwc_window_data); - - continue; - } - - if (hwc_window_data == hwc_data->target_hwc_window) - continue; - - /* set the cursor buffer HERE if it needs */ - if (hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_CURSOR) - _fbdev_hwc_cursor_buffer_set(hwc_data, hwc_window_data); - - layer_data = fbdev_output_data_get_layer_data(hwc_data->output_data, hwc_window_data->lzpos); - _fbdev_hwc_layer_attach_window(layer_data, hwc_window_data); - use_layers_zpos[hwc_window_data->lzpos] = 1; - } - - /* unset the unused layers */ - for (lzpos = 0; lzpos < NUM_LAYERS; lzpos++) { - if (use_layers_zpos[lzpos]) - continue; - - layer_data = fbdev_output_data_get_layer_data(hwc_data->output_data, lzpos); - if (!layer_data) - continue; - - _fbdev_hwc_layer_attach_window(layer_data, NULL); - } - - /* for debug */ - for (lzpos = NUM_LAYERS -1 ; lzpos >= 0; lzpos--) { - if (use_layers_zpos[lzpos]) - TDM_INFO(" lzpos(%d) : %s", lzpos, use_layers_zpos[lzpos] ? "SET" : "UNSET"); - } - - return TDM_ERROR_NONE; -} - -/* assign the validated_type to the composited_wnds - * assign the layer_zpos to the composited_wnds - */ -static void -_fbdev_hwc_apply_policy(tdm_fbdev_hwc_data *hwc_data , tdm_hwc_window **composited_wnds, uint32_t num_wnds) -{ - tdm_fbdev_hwc_window_data *hwc_window_data = NULL; - tdm_fbdev_hwc_window_data **composited_list = NULL; - int client_count = 0; - int device_count = 0; - int video_count = 0; - int cursor_count = 0; - int ui_lzpos_top = ZPOS_0; - int ui_lzpos_bottom = ZPOS_0; - int num_ui_layers = NUM_UI_LAYERS; - int set_clients_below = 0; - int i = 0; - - composited_list = (tdm_fbdev_hwc_window_data **)composited_wnds; - - /* initialize the need_target_window */ - hwc_data->need_target_window = 0; - - /* initialize the validated_types */ - LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) { - if (hwc_window_data->validated_type != TDM_HWC_WIN_COMPOSITION_NONE) - hwc_window_data->validated_type = TDM_HWC_WIN_COMPOSITION_NONE; - } - - /* use the target_window to commit when there is no window. */ - if (num_wnds == 0) { - hwc_data->need_target_window = 1; - hwc_data->target_hwc_window->lzpos = ui_lzpos_bottom; - return; - } - - /* 1. first check validate_type without target_window */ - for (i = 0; i < num_wnds; i++) { - switch (composited_list[i]->client_type) { - case TDM_HWC_WIN_COMPOSITION_VIDEO: - composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_VIDEO; - video_count++; - continue; - case TDM_HWC_WIN_COMPOSITION_CURSOR: - if (set_clients_below) break; - if (cursor_count > 0) break; - - composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CURSOR; - cursor_count++; - continue; - case TDM_HWC_WIN_COMPOSITION_DEVICE: - if (set_clients_below) break; - if (num_ui_layers <= 0) break; - if (!_fbdev_hwc_window_can_set_on_hw_layer(composited_list[i])) break; - - composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_DEVICE; - device_count++; - num_ui_layers--; - continue; - default: - break; - } - - composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CLIENT; - client_count++; - set_clients_below = 1; - } - - /* 2. check need target window and set ui_lzpos top and bottom */ - num_ui_layers = NUM_UI_LAYERS; - - if (video_count > 0) { - ui_lzpos_bottom++; - num_ui_layers--; - } - - if (client_count > 0) { - ui_lzpos_bottom++; - num_ui_layers--; - hwc_data->need_target_window = 1; - hwc_data->target_hwc_window->lzpos = ui_lzpos_bottom - 1; - } - - if (num_ui_layers > device_count) - ui_lzpos_top = ui_lzpos_bottom + device_count - 1; - - /* 3. set lzpos and modify validate_type with target_window */ - for (i = 0; i < num_wnds; i++) { - switch (composited_list[i]->validated_type) { - case TDM_HWC_WIN_COMPOSITION_VIDEO: - composited_list[i]->lzpos = ZPOS_VIDEO1; - continue; - case TDM_HWC_WIN_COMPOSITION_CURSOR: - composited_list[i]->lzpos = ZPOS_CURSOR; - continue; - case TDM_HWC_WIN_COMPOSITION_DEVICE: - if (num_ui_layers <= 0) break; - composited_list[i]->lzpos = ui_lzpos_top; - ui_lzpos_top--; - num_ui_layers--; - continue; - default: - break; - } - - composited_list[i]->validated_type = TDM_HWC_WIN_COMPOSITION_CLIENT; - composited_list[i]->lzpos = ZPOS_NONE; - } -} - -static int -_fbdev_hwc_get_changed_number(tdm_fbdev_hwc_data *hwc_data) -{ - int num = 0; - tdm_fbdev_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; -} - -tdm_hwc_window * -_fbdev_hwc_create_window(tdm_hwc *hwc, tdm_hwc_window_info *info, tdm_error *error) -{ - tdm_fbdev_hwc_data *hwc_data = hwc; - tdm_fbdev_hwc_window_data *hwc_window_data = NULL; - - 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_fbdev_hwc_window_data)); - if (!hwc_window_data) { - TDM_ERR("alloc failed"); - if (error) - *error = TDM_ERROR_OUT_OF_MEMORY; - return NULL; - } - - 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_hwc_window * -fbdev_hwc_create_window(tdm_hwc *hwc, tdm_error *error) -{ - tdm_fbdev_hwc_data *hwc_data = hwc; - tdm_fbdev_hwc_window_data *hwc_window_data = NULL; - - RETURN_VAL_IF_FAIL(hwc_data, NULL); - - hwc_window_data = _fbdev_hwc_create_window(hwc_data, NULL, error); - RETURN_VAL_IF_FAIL(hwc_window_data, NULL); - - LIST_ADDTAIL(&hwc_window_data->link, &hwc_data->hwc_window_list); - - TDM_INFO("hwc_window(%p) create", hwc_window_data); - if (error) - *error = TDM_ERROR_NONE; - - return hwc_window_data; -} - -tdm_error -fbdev_hwc_get_video_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count) -{ - RETURN_VAL_IF_FAIL(hwc != 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: fix these formats. - *formats = hwc_window_video_formats; - *count = sizeof(hwc_window_video_formats) / sizeof(tbm_format); - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *capabilities) -{ - RETURN_VAL_IF_FAIL(hwc != NULL, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER); - - *capabilities |= TDM_HWC_CAPABILITY_VIDEO_SCALE; - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count) -{ - tdm_fbdev_hwc_data *hwc_data = hwc; - - RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); - - *props = NULL; - *count = 0; - - return TDM_ERROR_NONE; -} - -tbm_surface_queue_h -fbdev_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error) -{ - tdm_fbdev_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 = _fbdev_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 -fbdev_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage) -{ - tdm_fbdev_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 = fbdev_hwc_window_set_buffer(hwc_data->target_hwc_window, buffer); - RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err); - - err = fbdev_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 -fbdev_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types) -{ - tdm_fbdev_hwc_data *hwc_data = hwc; - tdm_fbdev_output_data *output_data; - - RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER); - - output_data = hwc_data->output_data; - RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER); - - TDM_INFO(" ==============Validate================================="); - - _fbdev_hwc_apply_policy(hwc_data, composited_wnds, num_wnds); - - *num_types = _fbdev_hwc_get_changed_number(hwc_data); - - _print_validate_result(hwc_data, composited_wnds, num_wnds); - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements, - tdm_hwc_window **hwc_wnds, tdm_hwc_window_composition *composition_types) -{ - tdm_fbdev_hwc_data *hwc_data = hwc; - tdm_fbdev_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 = _fbdev_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 -fbdev_hwc_accept_validation(tdm_hwc *hwc) -{ - tdm_fbdev_hwc_data *hwc_data = hwc; - tdm_error ret = TDM_ERROR_NONE; - - RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(hwc_data->output_data != NULL, TDM_ERROR_INVALID_PARAMETER); - - TDM_INFO(" ==============Accept Changes Done================================="); - - if (hwc_data->output_data->current_dpms != TDM_OUTPUT_DPMS_ON) { - TDM_ERR("dpms is not on. do not set buffer"); - return TDM_ERROR_BAD_REQUEST; - } - - ret = _fbdev_hwc_prepare_commit(hwc_data); - RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_hwc_commit(tdm_hwc *hwc, int sync, void *user_data) -{ - tdm_fbdev_hwc_data *hwc_data = hwc; - tdm_fbdev_output_data *output_data = NULL; - tdm_error ret; - - RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER); - - output_data = hwc_data->output_data; - RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); - - TDM_INFO(" ==============COMMIT================================="); - - if (hwc_data->output_data->current_dpms != TDM_OUTPUT_DPMS_ON) { - TDM_ERR("dpms is not on. do not commit"); - return TDM_ERROR_BAD_REQUEST; - } - - ret = fbdev_output_commit(output_data, sync, user_data); - RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); - - if (hwc_data->commit_func) - hwc_data->commit_func(hwc, output_data->sequence++, 0, 0, user_data); - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func) -{ - tdm_fbdev_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; -} - -tdm_error -fbdev_hwc_target_window_set_info(tdm_fbdev_hwc_data *hwc_data, int width, int height) -{ - tdm_hwc_window_info info = {0}; - tdm_fbdev_hwc_window_data *target_hwc_window; - tdm_error ret = TDM_ERROR_NONE; - - RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window, TDM_ERROR_INVALID_PARAMETER); - - target_hwc_window = hwc_data->target_hwc_window; - - info.dst_pos.x = 0; - info.dst_pos.y = 0; - info.dst_pos.w = width; - info.dst_pos.h = height; - - info.src_config.pos.x = 0; - info.src_config.pos.y = 0; - info.src_config.pos.w = width; - info.src_config.pos.h = height; - - info.src_config.size.h = width; - info.src_config.size.v = height; - info.src_config.format = TBM_FORMAT_ARGB8888; - - ret = fbdev_hwc_window_set_info(target_hwc_window, &info); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("set info target hwc window failed (%d)", ret); - return TDM_ERROR_OPERATION_FAILED; - } - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_hwc_initailize_target_window(tdm_fbdev_hwc_data *hwc_data) -{ - tdm_hwc_window_info info = {0}; - tdm_error ret = TDM_ERROR_NONE; - tdm_fbdev_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.w = 2; - info.dst_pos.h = 1; - - info.src_config.pos.x = 0; - info.src_config.pos.y = 0; - info.src_config.pos.w = 2; - info.src_config.pos.h = 1; - - info.src_config.size.h = 2; - info.src_config.size.v = 1; - info.src_config.format = TBM_FORMAT_ARGB8888; - - target_hwc_window = _fbdev_hwc_create_window(hwc_data, &info, &ret); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("create target hwc window failed (%d)", ret); - return TDM_ERROR_OPERATION_FAILED; - } - - if (hwc_data->target_hwc_window) - fbdev_hwc_window_destroy(hwc_data->target_hwc_window); - - hwc_data->target_hwc_window = target_hwc_window; - hwc_data->need_set_crtc = 1; - - return TDM_ERROR_NONE; -} diff --git a/src/libtdm-fbdev/tdm_fbdev_hwc.h b/src/libtdm-fbdev/tdm_fbdev_hwc.h deleted file mode 100644 index 4a435f7..0000000 --- a/src/libtdm-fbdev/tdm_fbdev_hwc.h +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************** - -libtdm_fbdev - -Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: SooChan Lim - -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_FBDEV_HWC_H_ -#define _TDM_FBDEV_HWC_H_ - -#include "tdm_fbdev.h" - -tdm_error fbdev_hwc_initailize_target_window(tdm_fbdev_hwc_data *hwc_data); -tdm_error fbdev_hwc_target_window_set_info(tdm_fbdev_hwc_data *hwc_data, int width, int height); - -#endif /* _TDM_FBDEV_HWC_H_ */ diff --git a/src/libtdm-fbdev/tdm_fbdev_hwc_window.c b/src/libtdm-fbdev/tdm_fbdev_hwc_window.c deleted file mode 100644 index 49c520f..0000000 --- a/src/libtdm-fbdev/tdm_fbdev_hwc_window.c +++ /dev/null @@ -1,184 +0,0 @@ -/************************************************************************** - -libtdm_fbdev - -Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: SooChan Lim - -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_fbdev.h" - -void -fbdev_hwc_window_destroy(tdm_hwc_window *hwc_window) -{ - tdm_fbdev_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 -fbdev_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, - tdm_hwc_window_composition comp_type) -{ - tdm_fbdev_hwc_window_data *hwc_window_data = hwc_window; - tdm_fbdev_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; - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage) -{ - tdm_fbdev_hwc_window_data *hwc_window_data = hwc_window; - - RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER); - - //TODO:: - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info) -{ - tdm_fbdev_hwc_window_data *hwc_window_data = hwc_window; - tdm_fbdev_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); - RETURN_VAL_IF_FAIL(info != 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; - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface) -{ - tdm_fbdev_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 -fbdev_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value) -{ - tdm_fbdev_hwc_window_data *hwc_window_data = hwc_window; - - RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER); - - //TODO: - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value) -{ - tdm_fbdev_hwc_window_data *hwc_window_data = hwc_window; - - RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER); - - //TODO: - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_hwc_window_get_constraints(tdm_hwc_window *hwc_window, int *constraints) -{ - tdm_fbdev_hwc_window_data *hwc_window_data = hwc_window; - - RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(constraints != NULL, TDM_ERROR_INVALID_PARAMETER); - - // no constraints - *constraints = 0; - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_hwc_window_set_name(tdm_hwc_window *hwc_window, const char *name) -{ - tdm_fbdev_hwc_window_data *hwc_window_data = hwc_window; - - RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER); - - if (!name) - return TDM_ERROR_NONE; - - snprintf(hwc_window_data->name, TDM_NAME_LEN, "%s", name); - - return TDM_ERROR_NONE; -} - -tdm_error -fbdev_hwc_window_set_cursor_image(tdm_hwc_window *hwc_window, int width, int height, int stride, void *ptr) -{ - tdm_fbdev_hwc_window_data *hwc_window_data = hwc_window; - - RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER); - RETURN_VAL_IF_FAIL(hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_CURSOR, TDM_ERROR_INVALID_PARAMETER); - - hwc_window_data->cursor_img.width = width; - hwc_window_data->cursor_img.height = height; - hwc_window_data->cursor_img.stride = stride; - hwc_window_data->cursor_img.ptr = ptr; - - hwc_window_data->cursor_img_refresh = 1; - - return TDM_ERROR_NONE; -} diff --git a/src/libtdm-fbdev/tdm_fbdev_hwc_window.h b/src/libtdm-fbdev/tdm_fbdev_hwc_window.h deleted file mode 100644 index e365b20..0000000 --- a/src/libtdm-fbdev/tdm_fbdev_hwc_window.h +++ /dev/null @@ -1,36 +0,0 @@ -/************************************************************************** - -libtdm_fbdev - -Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: SooChan Lim - -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_FBDEV_HWC_WINDOW_H_ -#define _TDM_FBDEV_HWC_WINDOW_H_ - -#include "tdm_fbdev.h" - -#endif /* _TDM_FBDEV_HWC_WINDOW_H_ */ \ No newline at end of file diff --git a/src/libtdm-fbdev/tdm_fbdev_types.h b/src/libtdm-fbdev/tdm_fbdev_types.h deleted file mode 100644 index 4db4cdc..0000000 --- a/src/libtdm-fbdev/tdm_fbdev_types.h +++ /dev/null @@ -1,254 +0,0 @@ -/************************************************************************** - -libtdm_drm - -Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: SooChan Lim - -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_FBDEV_TYPES_H_ -#define _TDM_FBDEV_TYPES_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Framebuffer moudel's internal macros, functions, 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 ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) - -#define CURSOR_MIN_W 192 -#define CURSOR_MIN_H 192 -#define CURSOR_MAX_W 192 -#define CURSOR_MAX_H 192 - -#define RETURN_VAL_IF_FAIL(cond, val) {\ - if (!(cond)) {\ - TDM_ERR("'%s' failed", #cond);\ - return val;\ - } \ -} - -#define RETURN_IF_FAIL(cond) {\ - if (!(cond)) {\ - TDM_ERR("'%s' failed", #cond);\ - return;\ - } \ -} - -#define GOTO_IF_FAIL(cond, val) {\ - if (!(cond)) {\ - TDM_ERR("'%s' failed", #cond);\ - goto val;\ - } \ -} - -typedef struct _tdm_fbdev_output_data tdm_fbdev_output_data; -typedef struct _tdm_fbdev_layer_data tdm_fbdev_layer_data; -typedef struct _tdm_fbdev_hwc_data tdm_fbdev_hwc_data; -typedef struct _tdm_fbdev_hwc_window_data tdm_fbdev_hwc_window_data; -typedef struct _tdm_fbdev_display_buffer tdm_fbdev_display_buffer; - -typedef struct _tdm_fbdev_data { - tdm_fbdev_output_data *fbdev_output; - - int fbdev_fd; - - tdm_display *dpy; - - int hwc_mode; - - struct fb_fix_screeninfo *finfo; - struct fb_var_screeninfo *vinfo; - - struct list_head buffer_list; -} tdm_fbdev_data; - -struct _tdm_fbdev_output_data { - tdm_fbdev_data *fbdev_data; - tdm_fbdev_layer_data *fbdev_layer; - - uint32_t width; - uint32_t height; - uint32_t pitch; - uint32_t bpp; - size_t size; - uint32_t max_width; - uint32_t max_height; - - /* - * Poinetr to Framebuffers's mapped memory - */ - void *mem; - - int count_modes; - tdm_output_mode *output_modes; - int mode_changed; - - /* - * Frambuffer device back end currently support only one mode - */ - const tdm_output_mode *current_mode; - - tdm_output_type connector_type; - tdm_output_conn_status status; - unsigned int connector_type_id; - - tdm_output_dpms dpms_value; - - /* - * Event handlers - */ - tdm_output_vblank_handler vblank_func; - tdm_output_commit_handler commit_func; - - void *user_data; - - /* - * Fake flags are used to simulate event-operated back end. Since tdm - * library assumes its back ends to be event-operated and Framebuffer - * device is not event-operated we have to make fake events - */ - int is_vblank; - int is_commit; - - int sequence; - - /* hwc */ - int hwc_enable; - tdm_fbdev_hwc_data *hwc_data; - - /* dpms */ - tdm_output_dpms current_dpms; -}; - -struct _tdm_fbdev_layer_data { - tdm_fbdev_data *fbdev_data; - tdm_fbdev_output_data *fbdev_output; - - tdm_fbdev_display_buffer *display_buffer; - int display_buffer_changed; - - tdm_layer_capability capabilities; - tdm_info_layer info; - int info_changed; -}; - -enum { - DOWN = 0, - UP, -}; - -struct _tdm_fbdev_display_buffer { - struct list_head link; - - int width; - int height; - - tbm_surface_h buffer; -}; - - -struct _tdm_fbdev_hwc_data { - tdm_fbdev_hwc_window_data *target_hwc_window; - - int need_validate; - int need_target_window; - int need_set_crtc; - - int target_window_zpos; - - tdm_fbdev_output_data *output_data; - struct list_head hwc_window_list; - - tbm_surface_h cursor_tsurface; - - tdm_hwc_commit_handler commit_func; -}; - -struct _tdm_fbdev_hwc_window_data { - struct list_head link; - - tdm_fbdev_hwc_data *hwc_data; - - tdm_hwc_window_info info; - tbm_surface_h surface; - tdm_hwc_window_composition client_type; - tdm_hwc_window_composition validated_type; - int lzpos; - - char name[TDM_NAME_LEN]; - struct { - int width; - int height; - int stride; - void *ptr; - } cursor_img; - int cursor_img_surface; - int cursor_img_refresh; -}; - -#endif /* _TDM_FBDEV_TYPES_H_ */ diff --git a/src/tdm_backend_fbdev.c b/src/tdm_backend_fbdev.c new file mode 100644 index 0000000..be588a8 --- /dev/null +++ b/src/tdm_backend_fbdev.c @@ -0,0 +1,362 @@ +/************************************************************************** + +libtdm_fbdev + +Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim + +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_fbdev.h" + +#define TDM_FBDEV_NAME "fbdev" + +static int +_tdm_fbdev_open_fbdev(void) +{ + const char *name = "/dev/fb0"; + int fd = -1; + + fd = open(name, O_RDWR); + if (fd < 0) { + TDM_BACKEND_ERR("Cannot open fbdev device.. search by udev"); + goto close; + } + + /* + * TODO: If we failed directly to open framebuffer device + * we would try to open it through udev + */ + +close: + + return fd; +} + +static hal_tdm_error +_tdm_fbdev_init_internal(tdm_fbdev_display *display_data) +{ + struct fb_fix_screeninfo *finfo = calloc(1, sizeof(struct fb_fix_screeninfo)); + struct fb_var_screeninfo *vinfo = calloc(1, sizeof(struct fb_var_screeninfo)); + int ret = -1; + + if (display_data == NULL) { + TDM_BACKEND_ERR("invalid parameter"); + goto close_1; + } + + ret = ioctl(display_data->fbdev_fd, FBIOGET_VSCREENINFO, vinfo); + if (ret < 0) { + TDM_BACKEND_ERR("FBIOGET_VSCREENINFO ioctl failed errno=%d", errno); + goto close_1; + } + + vinfo->reserved[0] = 0; + vinfo->reserved[1] = 0; + vinfo->reserved[2] = 0; + vinfo->xoffset = 0; + vinfo->yoffset = 0; + vinfo->activate = FB_ACTIVATE_NOW; + + /* + * Explicitly request 32 bits per pixel colors with corresponding + * red, blue and green color offsets and length of colors + */ + vinfo->bits_per_pixel = 32; + vinfo->red.offset = 16; + vinfo->red.length = 8; + vinfo->green.offset = 8; + vinfo->green.length = 8; + vinfo->blue.offset = 0; + vinfo->blue.length = 8; + vinfo->transp.offset = 0; + vinfo->transp.length = 0; + + vinfo->yres_virtual = vinfo->yres * MAX_BUF; + ret = ioctl(display_data->fbdev_fd, FBIOPAN_DISPLAY, vinfo); + if (ret < 0) + TDM_BACKEND_ERR("FBIOPAN_DISPLAY ioctl failed, errno=%d", errno); + + ret = ioctl(display_data->fbdev_fd, FBIOGET_FSCREENINFO, finfo); + if (ret < 0) { + TDM_BACKEND_ERR("FBIOGET_FSCREENINFO ioctl failed, errno=%d", errno); + goto close_1; + } + + if (finfo->smem_len <= 0) { + TDM_BACKEND_ERR("Length of frame buffer mem less then 0"); + goto close_1; + } + + display_data->vinfo = vinfo; + display_data->finfo = finfo; + + /* + * Output framebuffer's related information + */ + TDM_BACKEND_INFO("\n" + " VInfo\n" + " fb = %d\n" + " xres = %d px \n" + " yres = %d px \n" + " xres_virtual = %d px \n" + " yres_virtual = %d px \n" + " bpp = %d \n" + " r = %2u:%u\n" + " g = %2u:%u\n" + " b = %2u:%u\n" + " t = %2u:%u\n" + " active = %d \n" + " width = %d mm \n" + " height = %d mm \n", + display_data->fbdev_fd, + vinfo->xres, + vinfo->yres, + vinfo->xres_virtual, + vinfo->yres_virtual, + vinfo->bits_per_pixel, + vinfo->red.offset, vinfo->red.length, + vinfo->green.offset, vinfo->green.length, + vinfo->blue.offset, vinfo->blue.length, + vinfo->transp.offset, vinfo->transp.length, + vinfo->activate, + vinfo->width, + vinfo->height); + + TDM_BACKEND_INFO("\n" + " FInfo\n" + " id = %s\n" + " smem_len = %d\n" + " line_length = %d\n", + finfo->id, + finfo->smem_len, + finfo->line_length); + + return HAL_TDM_ERROR_NONE; +close_1: + ret = HAL_TDM_ERROR_OPERATION_FAILED; + free(vinfo); + free(finfo); + return ret; +} + +int +hal_backend_tdm_fbdev_exit(void *data) +{ + hal_tdm_backend_data *backend_data = (hal_tdm_backend_data *)data; + tdm_fbdev_display *display_data; + + TDM_BACKEND_INFO("deinit"); + + TDM_BACKEND_RETURN_VAL_IF_FAIL(backend_data != NULL, -1); + + display_data = (tdm_fbdev_display *)backend_data->display; + TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data != NULL, -1); + + 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; + } + + if (display_data->fbdev_fd >= 0) + close(display_data->fbdev_fd); + + tdm_fbdev_display_destroy_buffer_list(display_data); + tdm_fbdev_destroy_layer(display_data); + tdm_fbdev_destroy_output(display_data); + + if (display_data->vinfo) + free(display_data->vinfo); + + if (display_data->finfo) + free(display_data->finfo); + + free(display_data); + free(backend_data); + + return HAL_TDM_ERROR_NONE; +} + +static int +hal_backend_tdm_fbdev_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; + tdm_fbdev_display *display_data = NULL; + hal_tdm_error ret; + + /* 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_fbdev_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->buffer_list); + + /* 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 = fbdev_display_get_capability; + display_funcs->display_get_outputs = fbdev_display_get_outputs; + display_funcs->display_get_fd = NULL; + display_funcs->display_handle_events = NULL; + + /* 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 = fbdev_output_get_capability; + output_funcs->output_set_property = fbdev_output_set_property; + output_funcs->output_get_property = fbdev_output_get_property; + output_funcs->output_wait_vblank = fbdev_output_wait_vblank; + output_funcs->output_set_vblank_handler = fbdev_output_set_vblank_handler; + output_funcs->output_set_dpms = fbdev_output_set_dpms; + output_funcs->output_get_dpms = fbdev_output_get_dpms; + output_funcs->output_set_mode = fbdev_output_set_mode; + output_funcs->output_get_mode = fbdev_output_get_mode; + output_funcs->output_get_hwc = fbdev_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 = fbdev_hwc_create_window; + hwc_funcs->hwc_get_video_supported_formats = fbdev_hwc_get_video_supported_formats; + hwc_funcs->hwc_get_capabilities = fbdev_hwc_get_capabilities; + hwc_funcs->hwc_get_available_properties = fbdev_hwc_get_available_properties; + hwc_funcs->hwc_get_client_target_buffer_queue = fbdev_hwc_get_client_target_buffer_queue; + hwc_funcs->hwc_set_client_target_buffer = fbdev_hwc_set_client_target_buffer; + hwc_funcs->hwc_validate = fbdev_hwc_validate; + hwc_funcs->hwc_get_changed_composition_types = fbdev_hwc_get_changed_composition_types; + hwc_funcs->hwc_accept_validation = fbdev_hwc_accept_validation; + hwc_funcs->hwc_commit = fbdev_hwc_commit; + hwc_funcs->hwc_set_commit_handler = fbdev_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 = fbdev_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 = fbdev_hwc_window_set_composition_type; + hwc_window_funcs->hwc_window_set_buffer_damage = fbdev_hwc_window_set_buffer_damage; + hwc_window_funcs->hwc_window_set_info = fbdev_hwc_window_set_info; + hwc_window_funcs->hwc_window_set_buffer = fbdev_hwc_window_set_buffer; + hwc_window_funcs->hwc_window_set_property = fbdev_hwc_window_set_property; + hwc_window_funcs->hwc_window_get_property = fbdev_hwc_window_get_property; + hwc_window_funcs->hwc_window_get_constraints = fbdev_hwc_window_get_constraints; + hwc_window_funcs->hwc_window_set_name = fbdev_hwc_window_set_name; + hwc_window_funcs->hwc_window_set_cursor_image = fbdev_hwc_window_set_cursor_image; + + display_data->fbdev_fd = _tdm_fbdev_open_fbdev(); + if (display_data->fbdev_fd < 0) { + TDM_BACKEND_ERR("fail to open fbdev!\n"); + goto failed; + } + + ret = _tdm_fbdev_init_internal(display_data); + if (ret != HAL_TDM_ERROR_NONE) { + TDM_BACKEND_ERR("init of framebuffer failed"); + goto failed; + } + + ret = tdm_fbdev_create_output(display_data); + if (ret != HAL_TDM_ERROR_NONE) { + TDM_BACKEND_ERR("init of output failed"); + goto failed; + } + + ret = tdm_fbdev_create_layer(display_data); + if (ret != HAL_TDM_ERROR_NONE) { + TDM_BACKEND_ERR("init of layer failed"); + goto failed; + } + + TDM_BACKEND_INFO("init success!"); + + return HAL_TDM_ERROR_NONE; + +failed: + TDM_BACKEND_ERR("init failed!"); + + hal_backend_tdm_fbdev_exit((void *)backend_data); + + return -1; +} + +hal_backend hal_backend_tdm_data = { + "fbdev", + "Samsung", + HAL_ABI_VERSION_TIZEN_6_5, + hal_backend_tdm_fbdev_init, + hal_backend_tdm_fbdev_exit +}; diff --git a/src/tdm_backend_fbdev.h b/src/tdm_backend_fbdev.h new file mode 100644 index 0000000..eb41529 --- /dev/null +++ b/src/tdm_backend_fbdev.h @@ -0,0 +1,101 @@ +/************************************************************************** + +libtdm_fbdev + +Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim + +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_FBDEV_H_ +#define _TDM_FBDEV_H_ + +#include "tdm_backend_fbdev_types.h" + +#define MAX_BUF 1 + +/* display funcs */ +hal_tdm_error fbdev_display_get_capability(hal_tdm_display *display, hal_tdm_caps_display *caps); +hal_tdm_output **fbdev_display_get_outputs(hal_tdm_display *display, int *count, hal_tdm_error *error); +hal_tdm_error fbdev_display_get_fd(hal_tdm_display *display, int *fd); +hal_tdm_error fbdev_display_handle_events(hal_tdm_display *display); +hal_tdm_pp *fbdev_display_create_pp(hal_tdm_display *display, hal_tdm_error *error); + +/* output funcs */ +hal_tdm_error fbdev_output_get_capability(hal_tdm_output *output, hal_tdm_caps_output *caps); +hal_tdm_error fbdev_output_set_property(hal_tdm_output *output, unsigned int id, hal_tdm_value value); +hal_tdm_error fbdev_output_get_property(hal_tdm_output *output, unsigned int id, hal_tdm_value *value); +hal_tdm_error fbdev_output_wait_vblank(hal_tdm_output *output, int interval, int sync, void *user_data); +hal_tdm_error fbdev_output_set_vblank_handler(hal_tdm_output *output, hal_tdm_output_vblank_handler func); +hal_tdm_error fbdev_output_commit(hal_tdm_output *output, int sync, void *user_data); +hal_tdm_error fbdev_output_set_commit_handler(hal_tdm_output *output, hal_tdm_output_commit_handler func); +hal_tdm_error fbdev_output_set_dpms(hal_tdm_output *output, hal_tdm_output_dpms dpms_value); +hal_tdm_error fbdev_output_get_dpms(hal_tdm_output *output, hal_tdm_output_dpms *dpms_value); +hal_tdm_error fbdev_output_set_mode(hal_tdm_output *output, const hal_tdm_output_mode *mode); +hal_tdm_error fbdev_output_get_mode(hal_tdm_output *output, const hal_tdm_output_mode **mode); +hal_tdm_hwc *fbdev_output_get_hwc(hal_tdm_output *output, hal_tdm_error *error); + +/* hwc funcs */ +hal_tdm_hwc_window *fbdev_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_error *error); +hal_tdm_error fbdev_hwc_get_video_supported_formats(hal_tdm_output *output, const tbm_format **formats, int *count); +hal_tdm_error fbdev_hwc_get_capabilities(hal_tdm_hwc *hwc, hal_tdm_hwc_capability *capabilities); +hal_tdm_error fbdev_hwc_get_available_properties(hal_tdm_hwc *hwc, const hal_tdm_prop **props, int *count); +tbm_surface_queue_h fbdev_hwc_get_client_target_buffer_queue(hal_tdm_hwc *hwc, hal_tdm_error *error); +hal_tdm_error fbdev_hwc_set_client_target_buffer(hal_tdm_hwc *hwc, tbm_surface_h buffer, hal_tdm_region damage); +hal_tdm_error fbdev_hwc_validate(hal_tdm_hwc *hwc, hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types); +hal_tdm_error fbdev_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 fbdev_hwc_accept_validation(hal_tdm_hwc *hwc); +hal_tdm_error fbdev_hwc_commit(hal_tdm_hwc *hwc, int sync, void *user_data); +hal_tdm_error fbdev_hwc_set_commit_handler(hal_tdm_hwc *hwc, hal_tdm_hwc_commit_handler func); + +/* hwc_window funcs */ +void fbdev_hwc_window_destroy(hal_tdm_hwc_window *hwc_window); +hal_tdm_error fbdev_hwc_window_set_composition_type(hal_tdm_hwc_window *hwc_window, hal_tdm_hwc_window_composition composition_type); +hal_tdm_error fbdev_hwc_window_set_buffer_damage(hal_tdm_hwc_window *hwc_window, hal_tdm_region damage); +hal_tdm_error fbdev_hwc_window_set_info(hal_tdm_hwc_window *hwc_window, hal_tdm_hwc_window_info *info); +hal_tdm_error fbdev_hwc_window_set_buffer(hal_tdm_hwc_window *hwc_window, tbm_surface_h surface); +hal_tdm_error fbdev_hwc_window_set_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value value); +hal_tdm_error fbdev_hwc_window_get_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value *value); +hal_tdm_error fbdev_hwc_window_get_constraints(hal_tdm_hwc_window *hwc_window, int *constraints); +hal_tdm_error fbdev_hwc_window_set_name(hal_tdm_hwc_window *hwc_window, const char *name); +hal_tdm_error fbdev_hwc_window_set_cursor_image(hal_tdm_hwc_window *hwc_window, int width, int height, int stride, void *ptr); + + +void tdm_fbdev_display_destroy_buffer_list(tdm_fbdev_display *display_data); + +hal_tdm_error tdm_fbdev_create_output(tdm_fbdev_display *display_data); +void tdm_fbdev_destroy_output(tdm_fbdev_display *display_data); + +hal_tdm_error tdm_fbdev_create_layer(tdm_fbdev_display *display_data); +void tdm_fbdev_destroy_layer(tdm_fbdev_display *display_data); +hal_tdm_error fbdev_layer_set_buffer(tdm_fbdev_layer *layer_data, tbm_surface_h buffer); +hal_tdm_error fbdev_layer_unset_buffer(tdm_fbdev_layer *layer_data); +hal_tdm_error fbdev_layer_set_info(tdm_fbdev_layer *layer_data, tdm_fbdev_layer_info *info); + +tdm_fbdev_layer *fbdev_output_data_get_layer_data(tdm_fbdev_output *output_data, int layer_zops); + +hal_tdm_error fbdev_hwc_initailize_target_window(tdm_fbdev_hwc *hwc_data); +hal_tdm_error fbdev_hwc_target_window_set_info(tdm_fbdev_hwc *hwc_data, int width, int height); + +#endif /* _TDM_FBDEV_H_ */ diff --git a/src/tdm_backend_fbdev_types.h b/src/tdm_backend_fbdev_types.h new file mode 100644 index 0000000..832d2da --- /dev/null +++ b/src/tdm_backend_fbdev_types.h @@ -0,0 +1,245 @@ +/************************************************************************** + +libtdm_drm + +Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim + +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_FBDEV_TYPES_H_ +#define _TDM_FBDEV_TYPES_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tdm_backend_list.h" +#include "tdm_fbdev_format.h" +#include "tdm_backend_log.h" + +typedef struct _tdm_fbdev_display tdm_fbdev_display; +typedef struct _tdm_fbdev_output tdm_fbdev_output; +typedef struct _tdm_fbdev_layer tdm_fbdev_layer; +typedef struct _tdm_fbdev_hwc tdm_fbdev_hwc; +typedef struct _tdm_fbdev_hwc_window tdm_fbdev_hwc_window; +typedef struct _tdm_fbdev_display_buffer tdm_fbdev_display_buffer; + +typedef enum { + TDM_FBDEV_LAYER_CAPABILITY_CURSOR = (1 << 0), /**< cursor */ + TDM_FBDEV_LAYER_CAPABILITY_PRIMARY = (1 << 1), /**< primary */ + TDM_FBDEV_LAYER_CAPABILITY_OVERLAY = (1 << 2), /**< overlay */ + TDM_FBDEV_LAYER_CAPABILITY_GRAPHIC = (1 << 4), /**< graphic */ + TDM_FBDEV_LAYER_CAPABILITY_VIDEO = (1 << 5), /**< video */ + TDM_FBDEV_LAYER_CAPABILITY_SCALE = (1 << 8), /**< if a layer_data has scale capability */ + TDM_FBDEV_LAYER_CAPABILITY_TRANSFORM = (1 << 9), /**< if a layer_data has transform capability */ + TDM_FBDEV_LAYER_CAPABILITY_SCANOUT = (1 << 10), /**< if a layer_data allows a scanout buffer only */ + TDM_FBDEV_LAYER_CAPABILITY_RESEVED_MEMORY = (1 << 11), /**< if a layer_data allows a reserved buffer only */ + TDM_FBDEV_LAYER_CAPABILITY_NO_CROP = (1 << 12), /**< if a layer_data has no cropping capability */ +} tdm_fbdev_layer_capability; + +typedef struct _tdm_fbdev_display { + tdm_fbdev_output *output_data; + + int fbdev_fd; + + hal_tdm_display *dpy; + + int hwc_mode; + + struct fb_fix_screeninfo *finfo; + struct fb_var_screeninfo *vinfo; + + struct list_head buffer_list; +} tdm_fbdev_display; + +struct _tdm_fbdev_output { + tdm_fbdev_display *display_data; + tdm_fbdev_layer *layer_data; + + uint32_t width; + uint32_t height; + uint32_t pitch; + uint32_t bpp; + size_t size; + uint32_t max_width; + uint32_t max_height; + + /* + * Poinetr to Framebuffers's mapped memory + */ + void *mem; + + int count_modes; + hal_tdm_output_mode *output_modes; + int mode_changed; + + /* + * Frambuffer device back end currently support only one mode + */ + const hal_tdm_output_mode *current_mode; + + hal_tdm_output_type connector_type; + hal_tdm_output_conn_status status; + unsigned int connector_type_id; + + hal_tdm_output_dpms dpms_value; + + /* + * Event handlers + */ + hal_tdm_output_vblank_handler vblank_func; + hal_tdm_output_commit_handler commit_func; + + void *user_data; + + /* + * Fake flags are used to simulate event-operated back end. Since tdm + * library assumes its back ends to be event-operated and Framebuffer + * device is not event-operated we have to make fake events + */ + int is_vblank; + int is_commit; + + int sequence; + + /* hwc */ + int hwc_enable; + tdm_fbdev_hwc *hwc_data; + + /* dpms */ + hal_tdm_output_dpms current_dpms; +}; + +typedef struct _tdm_fbdev_caps_layer { + tdm_fbdev_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_fbdev_caps_layer; + +typedef struct _tdm_fbdev_layer_info { + hal_tdm_info_config src_config; + hal_tdm_pos dst_pos; + hal_tdm_transform transform; +} tdm_fbdev_layer_info; + +struct _tdm_fbdev_layer { + tdm_fbdev_display *display_data; + tdm_fbdev_output *output_data; + + tdm_fbdev_display_buffer *display_buffer; + int display_buffer_changed; + + tdm_fbdev_layer_capability capabilities; + tdm_fbdev_layer_info info; + int info_changed; +}; + +struct _tdm_fbdev_display_buffer { + struct list_head link; + + int width; + int height; + + tbm_surface_h buffer; +}; + +struct _tdm_fbdev_hwc { + tdm_fbdev_hwc_window *target_hwc_window; + + int need_validate; + int need_target_window; + int need_set_crtc; + + int target_window_zpos; + + tdm_fbdev_output *output_data; + struct list_head hwc_window_list; + + tbm_surface_h cursor_tsurface; + + hal_tdm_hwc_commit_handler commit_func; +}; + +struct _tdm_fbdev_hwc_window { + struct list_head link; + + tdm_fbdev_hwc *hwc_data; + + hal_tdm_hwc_window_info info; + tbm_surface_h surface; + hal_tdm_hwc_window_composition client_type; + hal_tdm_hwc_window_composition validated_type; + int lzpos; + + char name[HAL_TDM_NAME_LEN]; + struct { + int width; + int height; + int stride; + void *ptr; + } cursor_img; + int cursor_img_surface; + int cursor_img_refresh; +}; + +#endif /* _TDM_FBDEV_TYPES_H_ */ diff --git a/src/tdm_backend_list.h b/src/tdm_backend_list.h new file mode 100644 index 0000000..3873817 --- /dev/null +++ b/src/tdm_backend_list.h @@ -0,0 +1,170 @@ +/* + * + * 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 + +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_*/ diff --git a/src/tdm_backend_log.c b/src/tdm_backend_log.c new file mode 100644 index 0000000..808ceb1 --- /dev/null +++ b/src/tdm_backend_log.c @@ -0,0 +1,70 @@ +/************************************************************************** + +libtdm_vc4 + +Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim + +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" + +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 diff --git a/src/tdm_backend_log.h b/src/tdm_backend_log.h new file mode 100644 index 0000000..a62ec86 --- /dev/null +++ b/src/tdm_backend_log.h @@ -0,0 +1,109 @@ +/************************************************************************** + +libtdm_vc4 + +Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim + +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 +#include +#include +#include + +#undef LOG_TAG +#define LOG_TAG "TDM_BACKEND" + +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 diff --git a/src/tdm_fbdev_display.c b/src/tdm_fbdev_display.c new file mode 100644 index 0000000..58393cb --- /dev/null +++ b/src/tdm_fbdev_display.c @@ -0,0 +1,894 @@ +/************************************************************************** + +libtdm_fbdev + +Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim + +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 +#include "tdm_backend_fbdev.h" + +#include +#include + +/* + * Framebuffer device supported formats + */ +static tbm_format supported_formats[] = { + /* + * TODO: add support of 16 bit formats + */ + TBM_FORMAT_ARGB8888, + TBM_FORMAT_ABGR8888, + TBM_FORMAT_RGBA8888, + TBM_FORMAT_BGRA8888, +}; + +static tdm_fbdev_display_buffer * +_tdm_fbdev_display_find_buffer(tdm_fbdev_display *display_data, tbm_surface_h buffer) +{ + tdm_fbdev_display_buffer *display_buffer = NULL; + + LIST_FOR_EACH_ENTRY(display_buffer, &display_data->buffer_list, link) + { + if (display_buffer->buffer == buffer) + return display_buffer; + } + + return NULL; +} + +static void +_tdm_fbdev_display_cb_destroy_buffer(tbm_surface_h buffer, void *user_data) +{ + tdm_fbdev_display *display_data; + tdm_fbdev_display_buffer *display_buffer; + + if (!user_data) { + TDM_BACKEND_ERR("no user_data"); + return; + } + if (!buffer) { + TDM_BACKEND_ERR("no buffer"); + return; + } + + display_data = (tdm_fbdev_display *)user_data; + + display_buffer = _tdm_fbdev_display_find_buffer(display_data, buffer); + if (!display_buffer) { + TDM_BACKEND_ERR("no display_buffer"); + return; + } + + LIST_DEL(&display_buffer->link); + + free(display_buffer); +} + + +static inline uint32_t +_get_refresh(struct fb_var_screeninfo *timing) +{ + uint32_t pixclock, hfreq, htotal, vtotal; + + pixclock = PICOS2KHZ(timing->pixclock) * 1000; + + htotal = timing->xres + timing->right_margin + timing->hsync_len + timing->left_margin; + vtotal = timing->yres + timing->lower_margin + timing->vsync_len + timing->upper_margin; + + if (timing->vmode & FB_VMODE_INTERLACED) + vtotal /= 2; + if (timing->vmode & FB_VMODE_DOUBLE) + vtotal *= 2; + + hfreq = pixclock / htotal; + return hfreq / vtotal; +} + +/* + * Convert fb_var_screeninfo to hal_tdm_output_mode + */ +static inline void +_tdm_fbdev_display_to_tdm_mode(struct fb_var_screeninfo *timing, hal_tdm_output_mode *mode) +{ + + if (!timing->pixclock) + return; + + mode->clock = timing->pixclock / 1000; + mode->vrefresh = _get_refresh(timing); + mode->hdisplay = timing->xres; + mode->hsync_start = mode->hdisplay + timing->right_margin; + mode->hsync_end = mode->hsync_start + timing->hsync_len; + mode->htotal = mode->hsync_end + timing->left_margin; + + mode->vdisplay = timing->yres; + mode->vsync_start = mode->vdisplay + timing->lower_margin; + mode->vsync_end = mode->vsync_start + timing->vsync_len; + mode->vtotal = mode->vsync_end + timing->upper_margin; + + int interlaced = !!(timing->vmode & FB_VMODE_INTERLACED); + snprintf(mode->name, HAL_TDM_NAME_LEN, "%dx%d%s", mode->hdisplay, mode->vdisplay, interlaced ? "i" : ""); +} + +void +tdm_fbdev_display_destroy_buffer_list(tdm_fbdev_display *display_data) +{ + tdm_fbdev_display_buffer *b = NULL, *bb = NULL; + + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &display_data->buffer_list, link) { + tbm_surface_internal_remove_destroy_handler(b->buffer, _tdm_fbdev_display_cb_destroy_buffer, display_data); + _tdm_fbdev_display_cb_destroy_buffer(b->buffer, display_data); + } +} + +hal_tdm_error +tdm_fbdev_create_output(tdm_fbdev_display *display_data) +{ + tdm_fbdev_output *output = NULL; + size_t size; + int i = 0; + + output = calloc(1, sizeof(tdm_fbdev_output)); + if (output == NULL) { + TDM_BACKEND_ERR("alloc output failed"); + return HAL_TDM_ERROR_OUT_OF_MEMORY; + } + + /* + * TODO: Size of framebuffer must be aligned to system page size before + * it is mapped + */ + size = display_data->vinfo->xres * display_data->vinfo->yres * display_data->vinfo->bits_per_pixel / 8 * MAX_BUF; + + TDM_BACKEND_INFO("\n" "MMaped size: %zu\n", size); + + output->mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, display_data->fbdev_fd, 0); + if (output->mem == MAP_FAILED) { + TDM_BACKEND_ERR("MMap framebuffer failed, errno=%d", errno); + return HAL_TDM_ERROR_OPERATION_FAILED; + } + + memset(output->mem, 0, size); + + output->width = display_data->vinfo->xres; + output->height = display_data->vinfo->yres; + output->pitch = display_data->vinfo->width; + output->bpp = display_data->vinfo->bits_per_pixel; + output->size = size; + output->max_width = display_data->vinfo->xres_virtual; + output->max_height = display_data->vinfo->yres_virtual; + + output->status = HAL_TDM_OUTPUT_CONN_STATUS_CONNECTED; + output->connector_type = HAL_TDM_OUTPUT_TYPE_LVDS; + + output->is_vblank = DOWN; + output->is_commit = DOWN; + output->sequence = 1; + + /* + * TODO: connector_type_id field relates to libdrm connector which framebuffer + * does not know. It have to be checked whether softaware above us use this + * field for its purposes. + */ + output->connector_type_id = 1; + + output->count_modes = 1; + output->output_modes = calloc(output->count_modes, sizeof(hal_tdm_output_mode)); + if (!output->output_modes) { + TDM_BACKEND_ERR("failed: alloc memory"); + return HAL_TDM_ERROR_OUT_OF_MEMORY; + } + + for (i = 0; i < output->count_modes; i++) { + _tdm_fbdev_display_to_tdm_mode(display_data->vinfo, &output->output_modes[i]); + + sprintf(output->output_modes[i].name, "%dx%d", display_data->vinfo->xres, display_data->vinfo->yres); + } + + /* + * We currently support only one mode + */ + if (output->count_modes == 1) { + output->current_mode = &output->output_modes[0]; + output->status = HAL_TDM_OUTPUT_CONN_STATUS_MODE_SETTED; + } + + output->display_data = display_data; + display_data->output_data = output; + + return HAL_TDM_ERROR_NONE; +} + +void +tdm_fbdev_destroy_output(tdm_fbdev_display *display_data) +{ + tdm_fbdev_output *fbdev_output = display_data->output_data; + + if (fbdev_output == NULL) + goto close; + + if (fbdev_output->mem == NULL) + goto close_2; + + munmap(fbdev_output->mem, fbdev_output->size); + + if (fbdev_output->output_modes == NULL) + goto close_2; + + free(fbdev_output->output_modes); + +close_2: + free(fbdev_output); +close: + return; +} + +hal_tdm_error +tdm_fbdev_create_layer(tdm_fbdev_display *display_data) +{ + tdm_fbdev_layer *layer; + tdm_fbdev_output *fbdev_output = display_data->output_data; + + /* + * Framebuffer does not support layer, therefore create only + * one layer by libtdm's demand; + */ + layer = calloc(1, sizeof(tdm_fbdev_layer)); + if (layer == NULL) { + TDM_BACKEND_ERR("alloc output failed"); + return HAL_TDM_ERROR_OUT_OF_MEMORY; + } + + layer->capabilities = TDM_FBDEV_LAYER_CAPABILITY_PRIMARY | TDM_FBDEV_LAYER_CAPABILITY_GRAPHIC; + + layer->display_data = display_data; + layer->output_data = fbdev_output; + fbdev_output->layer_data = layer; + + return HAL_TDM_ERROR_NONE; +} + +void +tdm_fbdev_destroy_layer(tdm_fbdev_display *display_data) +{ + tdm_fbdev_output *fbdev_output = display_data->output_data; + tdm_fbdev_layer *layer; + + if (fbdev_output == NULL) + return; + + layer = fbdev_output->layer_data; + if (layer != NULL) + free(layer); +} + +hal_tdm_error +fbdev_display_get_capability(hal_tdm_display *display, hal_tdm_caps_display *caps) +{ + TDM_BACKEND_RETURN_VAL_IF_FAIL(caps, HAL_TDM_ERROR_INVALID_PARAMETER); + + /* + * Framebuffer does not support layer, therefore create only + * one layer by libtdm's demand; + */ + caps->max_layer_count = 1; + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_output ** +fbdev_display_get_outputs(hal_tdm_display *display, int *count, hal_tdm_error *error) +{ + tdm_fbdev_display *display_data = (tdm_fbdev_display *)display; + tdm_fbdev_output *fbdev_output = display_data->output_data; + hal_tdm_output **outputs; + hal_tdm_error ret; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data, NULL); + TDM_BACKEND_RETURN_VAL_IF_FAIL(count, NULL); + + if (fbdev_output == NULL) { + ret = HAL_TDM_ERROR_NONE; + goto failed_get; + } + + /* + * Since it is Framebuffer device there is only one output + */ + *count = 1; + + /* will be freed in frontend */ + outputs = calloc(*count, sizeof(tdm_fbdev_output*)); + if (!outputs) { + TDM_BACKEND_ERR("failed: alloc memory"); + *count = 0; + ret = HAL_TDM_ERROR_OUT_OF_MEMORY; + goto failed_get; + } + + outputs[0] = fbdev_output; + + if (error) + *error = HAL_TDM_ERROR_NONE; + + return outputs; + +failed_get: + + if (error) + *error = ret; + return NULL; +} + +hal_tdm_error +fbdev_display_handle_events(hal_tdm_display *display) +{ + tdm_fbdev_display *display_data = (tdm_fbdev_display *)display; + void *user_data; + tdm_fbdev_output *fbdev_output; + unsigned int sequence = 0; + unsigned int tv_sec = 0; + unsigned int tv_usec = 0; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(display_data, HAL_TDM_ERROR_INVALID_PARAMETER); + + fbdev_output = display_data->output_data; + user_data = fbdev_output->user_data; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(user_data, HAL_TDM_ERROR_INVALID_PARAMETER); + + /* + (hal_tdm_output *output, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, + void *user_data); + */ + + /* + * Framebuffer does not produce events + * Fake flags are used to simulate event-operated back end. Since tdm + * library assumes its back ends to be event-operated and Framebuffer + * device is not event-operated we have to make fake events + */ + if (fbdev_output->is_vblank && fbdev_output->vblank_func) { + fbdev_output->is_vblank = DOWN; + + fbdev_output->vblank_func((hal_tdm_output *)display_data, sequence, tv_sec, tv_usec, user_data); + } + + if (fbdev_output->is_commit && fbdev_output->commit_func) { + fbdev_output->is_commit = DOWN; + + fbdev_output->commit_func((hal_tdm_output *)display_data, sequence, tv_sec, tv_usec, user_data); + } + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_output_get_capability(hal_tdm_output *output, hal_tdm_caps_output *caps) +{ + tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; + tdm_fbdev_display *display_data = NULL; + hal_tdm_error ret; + int i = 0; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, 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 = fbdev_output->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->status = fbdev_output->status; + caps->type = fbdev_output->connector_type; + caps->type_id = fbdev_output->connector_type_id; + + caps->mode_count = fbdev_output->count_modes; + caps->modes = calloc(caps->mode_count, sizeof(hal_tdm_output_mode)); + if (!caps->modes) { + ret = HAL_TDM_ERROR_OUT_OF_MEMORY; + TDM_BACKEND_ERR("alloc failed\n"); + goto failed_get; + } + + for (i = 0; i < caps->mode_count; i++) + caps->modes[i] = fbdev_output->output_modes[i]; + + caps->mmWidth = display_data->vinfo->width; + caps->mmHeight = display_data->vinfo->height; + caps->subpixel = -1; + + caps->min_w = fbdev_output->width; + caps->min_h = fbdev_output->height; + caps->max_w = fbdev_output->max_width; + caps->max_h = fbdev_output->max_height; + caps->preferred_align = -1; + + /* + * Framebuffer does not have output properties + */ + caps->prop_count = 0; + caps->props = NULL; + + caps->capabilities |= HAL_TDM_OUTPUT_CAPABILITY_HWC; + + return HAL_TDM_ERROR_NONE; + +failed_get: + memset(caps, 0, sizeof(hal_tdm_caps_output)); + return ret; +} + +hal_tdm_error +fbdev_output_set_property(hal_tdm_output *output, unsigned int id, hal_tdm_value value) +{ + /* + * Framebuffer does not have output properties + */ + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_output_get_property(hal_tdm_output *output, unsigned int id, hal_tdm_value *value) +{ + /* + * Framebuffer does not have output properties + */ + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_output_wait_vblank(hal_tdm_output *output, int interval, int sync, void *user_data) +{ + tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; + tdm_fbdev_display *display_data; + + int crtc = 0; + int ret; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); + + /* + * Frame buffer device does not support asynchronous events, that is + * why clients must get responsibility on handling asynchronous + * events. + */ + if (!sync) { + TDM_BACKEND_WRN("Framebuffer back end does not support asynchronous vblank"); + return HAL_TDM_ERROR_NONE; + } + + display_data = fbdev_output->display_data; + + ret = ioctl(display_data->fbdev_fd, FBIO_WAITFORVSYNC, &crtc); + if (ret < 0) { + TDM_BACKEND_ERR("FBIO_WAITFORVSYNC ioctl failed, errno=%d", errno); + return HAL_TDM_ERROR_OPERATION_FAILED; + } + + /* + * Up fake flag to simulate vsync event + */ + fbdev_output->is_vblank = UP; + fbdev_output->user_data = user_data; + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_output_set_vblank_handler(hal_tdm_output *output, hal_tdm_output_vblank_handler func) +{ + tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); + TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER); + + fbdev_output->vblank_func = func; + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_output_commit(hal_tdm_output *output, int sync, void *user_data) +{ + tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; + tdm_fbdev_layer *fbdev_layer; + tdm_fbdev_display_buffer *display_buffer; + tbm_bo bo; + tbm_bo_handle bo_handle; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); + + fbdev_layer = fbdev_output->layer_data; + + if (!fbdev_layer->display_buffer_changed) + return HAL_TDM_ERROR_NONE; + + fbdev_output->mode_changed = 0; + fbdev_layer->display_buffer_changed = 0; + fbdev_layer->info_changed = 0; + + display_buffer = fbdev_layer->display_buffer; + + bo = tbm_surface_internal_get_bo(display_buffer->buffer, 0); + if (!bo) { + TDM_BACKEND_ERR("get bo fail"); + return HAL_TDM_ERROR_OPERATION_FAILED; + } + + bo_handle = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_READ); + if (!bo_handle.ptr) { + TDM_BACKEND_ERR("map bo fail"); + return HAL_TDM_ERROR_OPERATION_FAILED; + } + + /* + * Display buffer's content to screen + */ + memcpy(fbdev_output->mem, bo_handle.ptr, tbm_bo_size(bo) * sizeof(char)); + + tbm_bo_unmap(bo); + + if (fbdev_output->commit_func) { + TDM_BACKEND_ERR("trace"); + fbdev_output->commit_func((hal_tdm_output *)output, fbdev_output->sequence++, 0, 0, user_data); + } + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_output_set_commit_handler(hal_tdm_output *output, hal_tdm_output_commit_handler func) +{ + tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); + TDM_BACKEND_RETURN_VAL_IF_FAIL(func, HAL_TDM_ERROR_INVALID_PARAMETER); + + fbdev_output->commit_func = func; + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_output_set_dpms(hal_tdm_output *output, hal_tdm_output_dpms dpms_value) +{ + tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; + tdm_fbdev_display *display_data; + int fbmode = 0; + int ret; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); + + /* + * Bypass context switching overhead + */ + if (fbdev_output->dpms_value == dpms_value) + return HAL_TDM_ERROR_NONE; + + display_data = fbdev_output->display_data; + + switch (dpms_value) { + case HAL_TDM_OUTPUT_DPMS_ON: + fbmode = FB_BLANK_UNBLANK; + break; + + case HAL_TDM_OUTPUT_DPMS_OFF: + fbmode = FB_BLANK_POWERDOWN; + break; + + case HAL_TDM_OUTPUT_DPMS_STANDBY: + fbmode = FB_BLANK_VSYNC_SUSPEND; + break; + + case HAL_TDM_OUTPUT_DPMS_SUSPEND: + fbmode = FB_BLANK_HSYNC_SUSPEND; + break; + + default: + TDM_BACKEND_ERR("NEVER GET HERE"); + break; + } + + ret = ioctl(display_data->fbdev_fd, FBIOBLANK, &fbmode); + if (ret < 0) { + TDM_BACKEND_ERR("FBIOBLANK ioctl failed, errno=%d", errno); + return HAL_TDM_ERROR_OPERATION_FAILED; + } + + /* + * TODO: framebuffer have to be reinitialized again, Maybe + */ + + fbdev_output->dpms_value = dpms_value; + fbmode = 0; + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_output_get_dpms(hal_tdm_output *output, hal_tdm_output_dpms *dpms_value) +{ + tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); + TDM_BACKEND_RETURN_VAL_IF_FAIL(dpms_value, HAL_TDM_ERROR_INVALID_PARAMETER); + + *dpms_value = fbdev_output->dpms_value; + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_output_set_mode(hal_tdm_output *output, const hal_tdm_output_mode *mode) +{ + tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); + TDM_BACKEND_RETURN_VAL_IF_FAIL(mode, HAL_TDM_ERROR_INVALID_PARAMETER); + + /* + * We currently support only one mode + */ + if (fbdev_output->count_modes == 1) + return HAL_TDM_ERROR_NONE; + + /* + * TODO: Implement mode switching + */ + fbdev_output->mode_changed = 0; + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_output_get_mode(hal_tdm_output *output, const hal_tdm_output_mode **mode) +{ + tdm_fbdev_output *fbdev_output = (tdm_fbdev_output *)output; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(fbdev_output, HAL_TDM_ERROR_INVALID_PARAMETER); + TDM_BACKEND_RETURN_VAL_IF_FAIL(mode, HAL_TDM_ERROR_INVALID_PARAMETER); + + *mode = fbdev_output->current_mode; + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_hwc * +fbdev_output_get_hwc(hal_tdm_output *output, hal_tdm_error *error) +{ + tdm_fbdev_hwc *hwc_data = NULL; + tdm_fbdev_output *output_data = output; + hal_tdm_error ret = HAL_TDM_ERROR_NONE; + + 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_fbdev_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; + + ret = fbdev_hwc_initailize_target_window(output_data->hwc_data); + if (ret != HAL_TDM_ERROR_NONE) { + TDM_BACKEND_ERR("create target hwc window failed (%d)", ret); + free(hwc_data); + if (error) + *error = ret; + return NULL; + } + + if (error) + *error = HAL_TDM_ERROR_NONE; + + return hwc_data; +} + +tdm_fbdev_layer * +fbdev_output_data_get_layer_data(tdm_fbdev_output *output_data, int layer_zpos) +{ + TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, NULL); + + if (layer_zpos == 0) + return output_data->layer_data; + + return NULL; +} + +hal_tdm_error +fbdev_layer_get_capability(tdm_fbdev_layer *layer_data, tdm_fbdev_caps_layer *caps) +{ + hal_tdm_error ret; + int i; + + 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_fbdev_caps_layer)); + + caps->capabilities = layer_data->capabilities; + + /* + * Make our single GRAPHIC layer the lowest one aka "Prime" + */ + caps->zpos = 0; + + caps->format_count = sizeof(supported_formats) / sizeof(supported_formats[0]); + caps->formats = calloc(caps->format_count, sizeof(tbm_format)); + if (!caps->formats) { + ret = HAL_TDM_ERROR_OUT_OF_MEMORY; + TDM_BACKEND_ERR("alloc failed\n"); + goto failed_get; + } + + for (i = 0; i < caps->format_count; i++) + caps->formats[i] = supported_formats[i]; + + /* + * Framebuffer does not have layer properties + */ + caps->prop_count = 0; + caps->props = NULL; + + return HAL_TDM_ERROR_NONE; + +failed_get: + + memset(caps, 0, sizeof(tdm_fbdev_caps_layer)); + return ret; +} + +hal_tdm_error +fbdev_layer_set_property(tdm_fbdev_layer *layer_data, unsigned int id, hal_tdm_value value) +{ + /* + * Framebuffer does not have layer properties + */ + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_layer_get_property(tdm_fbdev_layer *layer_data, unsigned int id, hal_tdm_value *value) +{ + /* + * Framebuffer does not have layer properties + */ + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_layer_set_info(tdm_fbdev_layer *layer_data, tdm_fbdev_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; + + /* + * We do not use info in this backend, therefore just ignore + * info's changing + */ + layer_data->info_changed = 0; + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_layer_get_info(tdm_fbdev_layer *layer_data, tdm_fbdev_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 +fbdev_layer_set_buffer(tdm_fbdev_layer *layer_data, tbm_surface_h buffer) +{ + tdm_fbdev_display_buffer *display_buffer; + tdm_fbdev_display *display_data; + hal_tdm_error err = HAL_TDM_ERROR_NONE; + + 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); + + if (tbm_surface_internal_get_num_bos(buffer) > 1) { + TDM_BACKEND_ERR("Framebuffer backend does not support surfaces with more than one bos"); + return HAL_TDM_ERROR_INVALID_PARAMETER; + } + + display_data = layer_data->display_data; + + display_buffer = _tdm_fbdev_display_find_buffer(display_data, buffer); + if (!display_buffer) { + display_buffer = calloc(1, sizeof(tdm_fbdev_display_buffer)); + if (display_buffer == NULL) { + TDM_BACKEND_ERR("alloc failed"); + return HAL_TDM_ERROR_OUT_OF_MEMORY; + } + + display_buffer->buffer = buffer; + display_buffer->width = tbm_surface_get_width(buffer); + display_buffer->height = tbm_surface_get_height(buffer); + + err = tbm_surface_internal_add_destroy_handler(buffer, _tdm_fbdev_display_cb_destroy_buffer, display_data); + if (err != HAL_TDM_ERROR_NONE) { + TDM_BACKEND_ERR("add destroy handler fail"); + free(display_buffer); + return HAL_TDM_ERROR_OPERATION_FAILED; + } + + LIST_ADDTAIL(&display_buffer->link, &display_data->buffer_list); + } + + layer_data->display_buffer = display_buffer; + layer_data->display_buffer_changed = 1; + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_layer_unset_buffer(tdm_fbdev_layer *layer_data) +{ + TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_INVALID_PARAMETER); + + layer_data->display_buffer = NULL; + layer_data->display_buffer_changed = 1; + + return HAL_TDM_ERROR_NONE; +} diff --git a/src/tdm_fbdev_format.h b/src/tdm_fbdev_format.h new file mode 100644 index 0000000..4b2d849 --- /dev/null +++ b/src/tdm_fbdev_format.h @@ -0,0 +1,69 @@ +/************************************************************************** + +libtdm_fbdev + +Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim + +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_FBDEV_FORMAT_H_ +#define _TDM_FBDEV_FORMAT_H_ + +#include + +#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 ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +#define CURSOR_MIN_W 192 +#define CURSOR_MIN_H 192 +#define CURSOR_MAX_W 192 +#define CURSOR_MAX_H 192 + +enum { + DOWN = 0, + UP, +}; + +#endif /* _TDM_FBDEV_FORMAT_H_ */ diff --git a/src/tdm_fbdev_hwc.c b/src/tdm_fbdev_hwc.c new file mode 100644 index 0000000..2f26722 --- /dev/null +++ b/src/tdm_fbdev_hwc.c @@ -0,0 +1,803 @@ +/************************************************************************** + +libtdm_fbdev + +Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim + +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_fbdev.h" + +#define MIN_WIDTH 32 + +#define NUM_LAYERS 1 +#define NUM_BUFFERS 3 + +#define NUM_UI_LAYERS 1 + +#define ZPOS_MAX 1 +#define ZPOS_CURSOR 2 +#define ZPOS_1 1 +#define ZPOS_0 0 +#define ZPOS_VIDEO1 0 +#define ZPOS_NONE -999 + +tbm_format hwc_window_video_formats[] = { + TBM_FORMAT_NV12, + TBM_FORMAT_YUV420 +}; + +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 +_fbdev_hwc_cursor_buffer_unset(tdm_fbdev_hwc_window *hwc_window_data) +{ + hwc_window_data->surface = NULL; + hwc_window_data->cursor_img_surface = 0; + + hwc_window_data->info.src_config.pos.w = hwc_window_data->cursor_img.width; + hwc_window_data->info.src_config.pos.h = hwc_window_data->cursor_img.height; + hwc_window_data->info.dst_pos.w = hwc_window_data->cursor_img.width; + hwc_window_data->info.dst_pos.h = hwc_window_data->cursor_img.height; + + return 1; +} + +static void +_fbdev_hwc_cursor_adjust_pos(tdm_fbdev_hwc_window *hwc_window_data) +{ + int x, y; + + /* dst pos of cursor is possible set by negative value + * this is temporary code. + */ + + x = hwc_window_data->info.dst_pos.x; + y = hwc_window_data->info.dst_pos.y; + + if (x < 0) hwc_window_data->info.dst_pos.x = 0; + if (y < 0) hwc_window_data->info.dst_pos.y = 0; +} + +static int +_fbdev_hwc_cursor_buffer_set(tdm_fbdev_hwc *hwc_data, tdm_fbdev_hwc_window *hwc_window_data) +{ + tbm_surface_h cursor_tsurface = NULL; + tbm_surface_info_s tsurface_info; + tbm_surface_error_e ret = TBM_SURFACE_ERROR_NONE; + int img_w, img_h, new_w, new_h; + tbm_format new_format; + unsigned int flags = TBM_BO_SCANOUT; + void *src_ptr = NULL, *dst_ptr = NULL; + int src_stride; + int i; + + _fbdev_hwc_cursor_adjust_pos(hwc_window_data); + + if (!hwc_window_data->cursor_img_refresh && hwc_window_data->surface) + return 1; + + img_w = hwc_window_data->cursor_img.width; + img_h = hwc_window_data->cursor_img.height; + new_format = hwc_window_data->info.src_config.format; + + /* cursor restriction to set the cursor layer */ + new_w = (CURSOR_MIN_W > img_w) ? CURSOR_MIN_W : img_w; + new_h = (CURSOR_MIN_H > img_h) ? CURSOR_MIN_H : img_h; + + if (hwc_data->cursor_tsurface) { + tbm_surface_internal_unref(hwc_data->cursor_tsurface); + hwc_data->cursor_tsurface = NULL; + } + + cursor_tsurface = tbm_surface_internal_create_with_flags(new_w, new_h, new_format, flags); + TDM_BACKEND_RETURN_VAL_IF_FAIL(cursor_tsurface, 0); + + hwc_data->cursor_tsurface = cursor_tsurface; + ret = tbm_surface_map(hwc_data->cursor_tsurface, TBM_SURF_OPTION_WRITE, &tsurface_info); + if (ret != TBM_SURFACE_ERROR_NONE) { + TDM_BACKEND_ERR("Failed to map tsurface\n"); + tbm_surface_internal_unref(hwc_data->cursor_tsurface); + hwc_data->cursor_tsurface = NULL; + return 0; + } + + src_ptr = hwc_window_data->cursor_img.ptr; + dst_ptr = tsurface_info.planes[0].ptr; + src_stride = hwc_window_data->cursor_img.stride; + + memset(dst_ptr, 0, tsurface_info.planes[0].stride * tsurface_info.height); + + for (i = 0 ; i < img_h ; i++) { + memcpy(dst_ptr, src_ptr, src_stride); + dst_ptr += tsurface_info.planes[0].stride; + src_ptr += src_stride; + } + + tbm_surface_unmap(hwc_data->cursor_tsurface); + + hwc_window_data->surface = hwc_data->cursor_tsurface; + hwc_window_data->cursor_img_surface = 1; + + /* fix the dst_pos info of the cursor window */ + hwc_window_data->info.src_config.pos.w = new_w; + hwc_window_data->info.src_config.pos.h = new_h; + hwc_window_data->info.dst_pos.w = new_w; + hwc_window_data->info.dst_pos.h = new_h; + + hwc_window_data->cursor_img_refresh = 0; + + return 1; +} + +static void +_print_validate_result(tdm_fbdev_hwc *hwc_data, hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds) +{ + tdm_fbdev_hwc_window *hwc_window_data = NULL; + int i; + + for (i = 0; i < num_wnds; i++) { + hwc_window_data = composited_wnds[i]; + switch (hwc_window_data->validated_type) { + case HAL_TDM_HWC_WIN_COMPOSITION_CLIENT: + TDM_BACKEND_INFO(" window(%p) %s -> %s : lzpos(%d) -- {%s} on TARGET WINDOW", hwc_window_data, + _comp_to_str(hwc_window_data->client_type), + _comp_to_str(hwc_window_data->validated_type), + hwc_data->target_hwc_window->lzpos, + hwc_window_data->name ? hwc_window_data->name : "NONE"); + break; + case HAL_TDM_HWC_WIN_COMPOSITION_DEVICE: + case HAL_TDM_HWC_WIN_COMPOSITION_VIDEO: + case HAL_TDM_HWC_WIN_COMPOSITION_CURSOR: + case HAL_TDM_HWC_WIN_COMPOSITION_NONE: + TDM_BACKEND_INFO(" window(%p) %s -> %s : lzpos(%d) -- {%s}", hwc_window_data, + _comp_to_str(hwc_window_data->client_type), + _comp_to_str(hwc_window_data->validated_type), + hwc_window_data->lzpos, + hwc_window_data->name ? hwc_window_data->name : "NONE"); + break; + default: + break; + } + } +} + +static int +_fbdev_hwc_window_can_set_on_hw_layer(tdm_fbdev_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.pos.w < MIN_WIDTH || hwc_window_data->info.src_config.pos.w % 2) + return 0; + + return 1; +} + +static tbm_surface_queue_h +_fbdev_hwc_window_get_tbm_buffer_queue(hal_tdm_hwc_window *hwc_window, hal_tdm_error *error) +{ + tdm_fbdev_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(NUM_BUFFERS, 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; +} + +static hal_tdm_error +_fbdev_hwc_layer_attach_window(tdm_fbdev_layer *layer_data, tdm_fbdev_hwc_window *hwc_window_data) +{ + hal_tdm_error ret = HAL_TDM_ERROR_NONE; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(layer_data, HAL_TDM_ERROR_OPERATION_FAILED); + + if (hwc_window_data == NULL || hwc_window_data->surface == NULL) { + if (layer_data->display_buffer) + ret = fbdev_layer_unset_buffer(layer_data); + TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret); + } else { + ret = fbdev_layer_set_info(layer_data, (tdm_fbdev_layer_info *)&(hwc_window_data->info)); + TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret); + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data->surface != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + ret = fbdev_layer_set_buffer(layer_data, hwc_window_data->surface); + TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret); + } + + return ret; +} + +static hal_tdm_error +_fbdev_hwc_prepare_commit(tdm_fbdev_hwc *hwc_data) +{ + tdm_fbdev_hwc_window *hwc_window_data = NULL; + tdm_fbdev_layer *layer_data = NULL; + int use_layers_zpos[NUM_LAYERS] = {0,}; + int lzpos = 0; + + /* set target hwc window to the layer */ + if (hwc_data->need_target_window) { + layer_data = fbdev_output_data_get_layer_data(hwc_data->output_data, hwc_data->target_hwc_window->lzpos); + _fbdev_hwc_layer_attach_window(layer_data, hwc_data->target_hwc_window); + use_layers_zpos[hwc_data->target_hwc_window->lzpos] = 1; + } + + /* set the hwc_windows to the layers */ + LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) { + if (hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_NONE || + hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_CLIENT) { + + if (hwc_window_data->cursor_img_surface) + _fbdev_hwc_cursor_buffer_unset(hwc_window_data); + + continue; + } + + if (hwc_window_data == hwc_data->target_hwc_window) + continue; + + /* set the cursor buffer HERE if it needs */ + if (hwc_window_data->validated_type == HAL_TDM_HWC_WIN_COMPOSITION_CURSOR) + _fbdev_hwc_cursor_buffer_set(hwc_data, hwc_window_data); + + layer_data = fbdev_output_data_get_layer_data(hwc_data->output_data, hwc_window_data->lzpos); + _fbdev_hwc_layer_attach_window(layer_data, hwc_window_data); + use_layers_zpos[hwc_window_data->lzpos] = 1; + } + + /* unset the unused layers */ + for (lzpos = 0; lzpos < NUM_LAYERS; lzpos++) { + if (use_layers_zpos[lzpos]) + continue; + + layer_data = fbdev_output_data_get_layer_data(hwc_data->output_data, lzpos); + if (!layer_data) + continue; + + _fbdev_hwc_layer_attach_window(layer_data, NULL); + } + + /* for debug */ + for (lzpos = NUM_LAYERS -1 ; lzpos >= 0; lzpos--) { + if (use_layers_zpos[lzpos]) + TDM_BACKEND_INFO(" lzpos(%d) : %s", lzpos, use_layers_zpos[lzpos] ? "SET" : "UNSET"); + } + + return HAL_TDM_ERROR_NONE; +} + +/* assign the validated_type to the composited_wnds + * assign the layer_zpos to the composited_wnds + */ +static void +_fbdev_hwc_apply_policy(tdm_fbdev_hwc *hwc_data , hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds) +{ + tdm_fbdev_hwc_window *hwc_window_data = NULL; + tdm_fbdev_hwc_window **composited_list = NULL; + int client_count = 0; + int device_count = 0; + int video_count = 0; + int cursor_count = 0; + int ui_lzpos_top = ZPOS_0; + int ui_lzpos_bottom = ZPOS_0; + int num_ui_layers = NUM_UI_LAYERS; + int set_clients_below = 0; + int i = 0; + + composited_list = (tdm_fbdev_hwc_window **)composited_wnds; + + /* initialize the need_target_window */ + hwc_data->need_target_window = 0; + + /* initialize the validated_types */ + LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) { + if (hwc_window_data->validated_type != HAL_TDM_HWC_WIN_COMPOSITION_NONE) + hwc_window_data->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_NONE; + } + + /* use the target_window to commit when there is no window. */ + if (num_wnds == 0) { + hwc_data->need_target_window = 1; + hwc_data->target_hwc_window->lzpos = ui_lzpos_bottom; + return; + } + + /* 1. first check validate_type without target_window */ + for (i = 0; i < num_wnds; i++) { + switch (composited_list[i]->client_type) { + case HAL_TDM_HWC_WIN_COMPOSITION_VIDEO: + composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_VIDEO; + video_count++; + continue; + case HAL_TDM_HWC_WIN_COMPOSITION_CURSOR: + if (set_clients_below) break; + if (cursor_count > 0) break; + + composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_CURSOR; + cursor_count++; + continue; + case HAL_TDM_HWC_WIN_COMPOSITION_DEVICE: + if (set_clients_below) break; + if (num_ui_layers <= 0) break; + if (!_fbdev_hwc_window_can_set_on_hw_layer(composited_list[i])) break; + + composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_DEVICE; + device_count++; + num_ui_layers--; + continue; + default: + break; + } + + composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_CLIENT; + client_count++; + set_clients_below = 1; + } + + /* 2. check need target window and set ui_lzpos top and bottom */ + num_ui_layers = NUM_UI_LAYERS; + + if (video_count > 0) { + ui_lzpos_bottom++; + num_ui_layers--; + } + + if (client_count > 0) { + ui_lzpos_bottom++; + num_ui_layers--; + hwc_data->need_target_window = 1; + hwc_data->target_hwc_window->lzpos = ui_lzpos_bottom - 1; + } + + if (num_ui_layers > device_count) + ui_lzpos_top = ui_lzpos_bottom + device_count - 1; + + /* 3. set lzpos and modify validate_type with target_window */ + for (i = 0; i < num_wnds; i++) { + switch (composited_list[i]->validated_type) { + case HAL_TDM_HWC_WIN_COMPOSITION_VIDEO: + composited_list[i]->lzpos = ZPOS_VIDEO1; + continue; + case HAL_TDM_HWC_WIN_COMPOSITION_CURSOR: + composited_list[i]->lzpos = ZPOS_CURSOR; + continue; + case HAL_TDM_HWC_WIN_COMPOSITION_DEVICE: + if (num_ui_layers <= 0) break; + composited_list[i]->lzpos = ui_lzpos_top; + ui_lzpos_top--; + num_ui_layers--; + continue; + default: + break; + } + + composited_list[i]->validated_type = HAL_TDM_HWC_WIN_COMPOSITION_CLIENT; + composited_list[i]->lzpos = ZPOS_NONE; + } +} + +static int +_fbdev_hwc_get_changed_number(tdm_fbdev_hwc *hwc_data) +{ + int num = 0; + tdm_fbdev_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; +} + +hal_tdm_hwc_window * +_fbdev_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_hwc_window_info *info, hal_tdm_error *error) +{ + tdm_fbdev_hwc *hwc_data = hwc; + tdm_fbdev_hwc_window *hwc_window_data = NULL; + + 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_fbdev_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->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_hwc_window * +fbdev_hwc_create_window(hal_tdm_hwc *hwc, hal_tdm_error *error) +{ + tdm_fbdev_hwc *hwc_data = hwc; + tdm_fbdev_hwc_window *hwc_window_data = NULL; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, NULL); + + hwc_window_data = _fbdev_hwc_create_window(hwc_data, NULL, error); + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data, NULL); + + LIST_ADDTAIL(&hwc_window_data->link, &hwc_data->hwc_window_list); + + TDM_BACKEND_INFO("hwc_window(%p) create", hwc_window_data); + if (error) + *error = HAL_TDM_ERROR_NONE; + + return hwc_window_data; +} + +hal_tdm_error +fbdev_hwc_get_video_supported_formats(hal_tdm_hwc *hwc, const tbm_format **formats, int *count) +{ + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc != 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: fix these formats. + *formats = hwc_window_video_formats; + *count = sizeof(hwc_window_video_formats) / sizeof(tbm_format); + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_hwc_get_capabilities(hal_tdm_hwc *hwc, hal_tdm_hwc_capability *capabilities) +{ + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + TDM_BACKEND_RETURN_VAL_IF_FAIL(capabilities != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + + *capabilities |= HAL_TDM_HWC_CAPABILITY_VIDEO_SCALE; + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_hwc_get_available_properties(hal_tdm_hwc *hwc, const hal_tdm_prop **props, int *count) +{ + tdm_fbdev_hwc *hwc_data = hwc; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + TDM_BACKEND_RETURN_VAL_IF_FAIL(props != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + TDM_BACKEND_RETURN_VAL_IF_FAIL(count != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + + *props = NULL; + *count = 0; + + return HAL_TDM_ERROR_NONE; +} + +tbm_surface_queue_h +fbdev_hwc_get_client_target_buffer_queue(hal_tdm_hwc *hwc, hal_tdm_error *error) +{ + tdm_fbdev_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 = _fbdev_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 +fbdev_hwc_set_client_target_buffer(hal_tdm_hwc *hwc, tbm_surface_h buffer, hal_tdm_region damage) +{ + tdm_fbdev_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 = fbdev_hwc_window_set_buffer(hwc_data->target_hwc_window, buffer); + TDM_BACKEND_RETURN_VAL_IF_FAIL(err == HAL_TDM_ERROR_NONE, err); + + err = fbdev_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 +fbdev_hwc_validate(hal_tdm_hwc *hwc, hal_tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types) +{ + tdm_fbdev_hwc *hwc_data = hwc; + tdm_fbdev_output *output_data; + + 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); + + output_data = hwc_data->output_data; + TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + + TDM_BACKEND_INFO(" ==============Validate================================="); + + _fbdev_hwc_apply_policy(hwc_data, composited_wnds, num_wnds); + + *num_types = _fbdev_hwc_get_changed_number(hwc_data); + + _print_validate_result(hwc_data, composited_wnds, num_wnds); + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_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_fbdev_hwc *hwc_data = hwc; + tdm_fbdev_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 = _fbdev_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 +fbdev_hwc_accept_validation(hal_tdm_hwc *hwc) +{ + tdm_fbdev_hwc *hwc_data = hwc; + hal_tdm_error ret = HAL_TDM_ERROR_NONE; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data->output_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + + TDM_BACKEND_INFO(" ==============Accept Changes Done================================="); + + if (hwc_data->output_data->current_dpms != HAL_TDM_OUTPUT_DPMS_ON) { + TDM_BACKEND_ERR("dpms is not on. do not set buffer"); + return HAL_TDM_ERROR_BAD_REQUEST; + } + + ret = _fbdev_hwc_prepare_commit(hwc_data); + TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret); + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_hwc_commit(hal_tdm_hwc *hwc, int sync, void *user_data) +{ + tdm_fbdev_hwc *hwc_data = hwc; + tdm_fbdev_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; + TDM_BACKEND_RETURN_VAL_IF_FAIL(output_data, HAL_TDM_ERROR_INVALID_PARAMETER); + + TDM_BACKEND_INFO(" ==============COMMIT================================="); + + if (hwc_data->output_data->current_dpms != HAL_TDM_OUTPUT_DPMS_ON) { + TDM_BACKEND_ERR("dpms is not on. do not commit"); + return HAL_TDM_ERROR_BAD_REQUEST; + } + + ret = fbdev_output_commit(output_data, sync, user_data); + TDM_BACKEND_RETURN_VAL_IF_FAIL(ret == HAL_TDM_ERROR_NONE, ret); + + if (hwc_data->commit_func) + hwc_data->commit_func(hwc, output_data->sequence++, 0, 0, user_data); + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_hwc_set_commit_handler(hal_tdm_hwc *hwc, hal_tdm_hwc_commit_handler func) +{ + tdm_fbdev_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; +} + +hal_tdm_error +fbdev_hwc_target_window_set_info(tdm_fbdev_hwc *hwc_data, int width, int height) +{ + hal_tdm_hwc_window_info info = {0}; + tdm_fbdev_hwc_window *target_hwc_window; + hal_tdm_error ret = HAL_TDM_ERROR_NONE; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data, HAL_TDM_ERROR_INVALID_PARAMETER); + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window, HAL_TDM_ERROR_INVALID_PARAMETER); + + target_hwc_window = hwc_data->target_hwc_window; + + info.dst_pos.x = 0; + info.dst_pos.y = 0; + info.dst_pos.w = width; + info.dst_pos.h = height; + + info.src_config.pos.x = 0; + info.src_config.pos.y = 0; + info.src_config.pos.w = width; + info.src_config.pos.h = height; + + info.src_config.size.h = width; + info.src_config.size.v = height; + info.src_config.format = TBM_FORMAT_ARGB8888; + + ret = fbdev_hwc_window_set_info(target_hwc_window, &info); + if (ret != HAL_TDM_ERROR_NONE) { + TDM_BACKEND_ERR("set info target hwc window failed (%d)", ret); + return HAL_TDM_ERROR_OPERATION_FAILED; + } + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_hwc_initailize_target_window(tdm_fbdev_hwc *hwc_data) +{ + hal_tdm_hwc_window_info info = {0}; + hal_tdm_error ret = HAL_TDM_ERROR_NONE; + tdm_fbdev_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.w = 2; + info.dst_pos.h = 1; + + info.src_config.pos.x = 0; + info.src_config.pos.y = 0; + info.src_config.pos.w = 2; + info.src_config.pos.h = 1; + + info.src_config.size.h = 2; + info.src_config.size.v = 1; + info.src_config.format = TBM_FORMAT_ARGB8888; + + target_hwc_window = _fbdev_hwc_create_window(hwc_data, &info, &ret); + if (ret != HAL_TDM_ERROR_NONE) { + TDM_BACKEND_ERR("create target hwc window failed (%d)", ret); + return HAL_TDM_ERROR_OPERATION_FAILED; + } + + if (hwc_data->target_hwc_window) + fbdev_hwc_window_destroy(hwc_data->target_hwc_window); + + hwc_data->target_hwc_window = target_hwc_window; + hwc_data->need_set_crtc = 1; + + return HAL_TDM_ERROR_NONE; +} diff --git a/src/tdm_fbdev_hwc_window.c b/src/tdm_fbdev_hwc_window.c new file mode 100644 index 0000000..55e2a71 --- /dev/null +++ b/src/tdm_fbdev_hwc_window.c @@ -0,0 +1,184 @@ +/************************************************************************** + +libtdm_fbdev + +Copyright 2021 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim + +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_fbdev.h" + +void +fbdev_hwc_window_destroy(hal_tdm_hwc_window *hwc_window) +{ + tdm_fbdev_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 +fbdev_hwc_window_set_composition_type(hal_tdm_hwc_window *hwc_window, + hal_tdm_hwc_window_composition comp_type) +{ + tdm_fbdev_hwc_window *hwc_window_data = hwc_window; + tdm_fbdev_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; + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_hwc_window_set_buffer_damage(hal_tdm_hwc_window *hwc_window, hal_tdm_region damage) +{ + tdm_fbdev_hwc_window *hwc_window_data = hwc_window; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + + //TODO:: + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_hwc_window_set_info(hal_tdm_hwc_window *hwc_window, hal_tdm_hwc_window_info *info) +{ + tdm_fbdev_hwc_window *hwc_window_data = hwc_window; + tdm_fbdev_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); + TDM_BACKEND_RETURN_VAL_IF_FAIL(info != 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; + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_hwc_window_set_buffer(hal_tdm_hwc_window *hwc_window, tbm_surface_h surface) +{ + tdm_fbdev_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 +fbdev_hwc_window_set_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value value) +{ + tdm_fbdev_hwc_window *hwc_window_data = hwc_window; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + + //TODO: + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_hwc_window_get_property(hal_tdm_hwc_window *hwc_window, unsigned int id, hal_tdm_value *value) +{ + tdm_fbdev_hwc_window *hwc_window_data = hwc_window; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + + //TODO: + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_hwc_window_get_constraints(hal_tdm_hwc_window *hwc_window, int *constraints) +{ + tdm_fbdev_hwc_window *hwc_window_data = hwc_window; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + TDM_BACKEND_RETURN_VAL_IF_FAIL(constraints != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + + // no constraints + *constraints = 0; + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_hwc_window_set_name(hal_tdm_hwc_window *hwc_window, const char *name) +{ + tdm_fbdev_hwc_window *hwc_window_data = hwc_window; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + + if (!name) + return HAL_TDM_ERROR_NONE; + + snprintf(hwc_window_data->name, HAL_TDM_NAME_LEN, "%s", name); + + return HAL_TDM_ERROR_NONE; +} + +hal_tdm_error +fbdev_hwc_window_set_cursor_image(hal_tdm_hwc_window *hwc_window, int width, int height, int stride, void *ptr) +{ + tdm_fbdev_hwc_window *hwc_window_data = hwc_window; + + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data != NULL, HAL_TDM_ERROR_INVALID_PARAMETER); + TDM_BACKEND_RETURN_VAL_IF_FAIL(hwc_window_data->client_type == HAL_TDM_HWC_WIN_COMPOSITION_CURSOR, HAL_TDM_ERROR_INVALID_PARAMETER); + + hwc_window_data->cursor_img.width = width; + hwc_window_data->cursor_img.height = height; + hwc_window_data->cursor_img.stride = stride; + hwc_window_data->cursor_img.ptr = ptr; + + hwc_window_data->cursor_img_refresh = 1; + + return HAL_TDM_ERROR_NONE; +}