From 858ebdf2af1a6c71ce55f0d9957a3314ccfe46bf Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Tue, 14 Mar 2017 16:45:08 +0900 Subject: [PATCH 2/4] add inital code libtdm-vc4 is based on the libtdm-drm code. Change-Id: Ief3e6f2301e95fd7fb54f8d5e6225e3f89771f1a Signed-off-by: SooChan Lim --- COPYING | 21 + Makefile.am | 1 + autogen.sh | 6 + configure.ac | 62 ++ packaging/libtdm-drm.manifest | 5 + packaging/libtdm-drm.spec | 47 ++ src/Makefile.am | 14 + src/tdm_drm.c | 411 ++++++++++ src/tdm_drm.h | 133 ++++ src/tdm_drm_display.c | 1704 +++++++++++++++++++++++++++++++++++++++++ src/tdm_drm_format.c | 104 +++ src/tdm_drm_pp.c | 411 ++++++++++ src/tdm_drm_pp.h | 13 + 13 files changed, 2932 insertions(+) create mode 100644 COPYING create mode 100644 Makefile.am create mode 100755 autogen.sh create mode 100644 configure.ac create mode 100644 packaging/libtdm-drm.manifest create mode 100644 packaging/libtdm-drm.spec create mode 100644 src/Makefile.am create mode 100644 src/tdm_drm.c create mode 100644 src/tdm_drm.h create mode 100644 src/tdm_drm_display.c create mode 100644 src/tdm_drm_format.c create mode 100644 src/tdm_drm_pp.c create mode 100644 src/tdm_drm_pp.h diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..817cb95 --- /dev/null +++ b/COPYING @@ -0,0 +1,21 @@ +Copyright 2013 Samsung Electronics co., Ltd. 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 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. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..af437a6 --- /dev/null +++ b/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = src diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..30d679f --- /dev/null +++ b/autogen.sh @@ -0,0 +1,6 @@ +#! /bin/sh + +test -n "$srcdir" || srcdir=`dirname "$0"` +test -n "$srcdir" || srcdir=. +autoreconf --force --install --verbose "$srcdir" +test -n "$NOCONFIGURE" || "$srcdir/configure" "$@" diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..3acfee2 --- /dev/null +++ b/configure.ac @@ -0,0 +1,62 @@ +AC_PREREQ([2.60]) +AC_INIT([libtdm-drm], + [1.0.0], + [https://www.tizen.org], + [libtdm-drm]) + +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_SRCDIR([Makefile.am]) +AM_INIT_AUTOMAKE([1.10 foreign dist-bzip2]) +AM_MAINTAINER_MODE([enable]) + +# Check for programs +AC_PROG_CC + +AC_USE_SYSTEM_EXTENSIONS +AC_SYS_LARGEFILE +AC_FUNC_ALLOCA + +# Initialize libtool +LT_PREREQ([2.2]) +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 pixman-1) +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" +fi + +AC_SUBST(TDM_DRM_CFLAGS) +AC_SUBST(TDM_DRM_LIBS) + +AC_DEFINE_UNQUOTED(LIBDRM_MAJOR_VERSION, [`pkg-config --modversion libdrm | cut -d '.' -f 1`], dnl + [libdrm major version]) +AC_DEFINE_UNQUOTED(LIBDRM_MINOR_VERSION, [`pkg-config --modversion libdrm | cut -d '.' -f 2`], dnl + [libdrm major version]) +AC_DEFINE_UNQUOTED(LIBDRM_MICRO_VERSION, [`pkg-config --modversion libdrm | cut -d '.' -f 3`], dnl + [libdrm major version]) + +# set the dir for the tbm 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) + +# For enumerating devices in test case +AC_OUTPUT([ + Makefile + src/Makefile]) + +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 "" diff --git a/packaging/libtdm-drm.manifest b/packaging/libtdm-drm.manifest new file mode 100644 index 0000000..75b0fa5 --- /dev/null +++ b/packaging/libtdm-drm.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/libtdm-drm.spec b/packaging/libtdm-drm.spec new file mode 100644 index 0000000..3bf892b --- /dev/null +++ b/packaging/libtdm-drm.spec @@ -0,0 +1,47 @@ +Name: libtdm-drm +Version: 1.0.5 +Release: 0 +Summary: Tizen Display Manager DRM Back-End Library +Group: Development/Libraries +License: MIT +Source0: %{name}-%{version}.tar.gz +Source1001: %{name}.manifest +BuildRequires: pkgconfig(libdrm) +BuildRequires: pkgconfig(libudev) +BuildRequires: pkgconfig(libtdm) +BuildRequires: pkgconfig(pixman-1) + +%description +Back-End library of Tizen Display Manager DRM : libtdm-mgr DRM library + +%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 \ + CFLAGS="${CFLAGS} -Wall -Werror" \ + LDFLAGS="${LDFLAGS} -Wl,--hash-style=both -Wl,--as-needed" +make %{?_smp_mflags} + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{TZ_SYS_RO_SHARE}/license +cp -af COPYING %{buildroot}/%{TZ_SYS_RO_SHARE}/license/%{name} +%make_install + +%post +if [ -f %{_libdir}/tdm/libtdm-default.so ]; then + rm -rf %{_libdir}/tdm/libtdm-default.so +fi +ln -s libtdm-drm.so %{_libdir}/tdm/libtdm-default.so + +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root,-) +%manifest %{name}.manifest +%{TZ_SYS_RO_SHARE}/license/%{name} +%{_libdir}/tdm/libtdm-drm.so diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..09338b8 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,14 @@ +AM_CFLAGS = \ + $(TDM_DRM_CFLAGS) \ + -I$(top_srcdir)/src + +libtdm_drm_la_LTLIBRARIES = libtdm-drm.la +libtdm_drm_ladir = $(TDM_MODULE_PATH) +libtdm_drm_la_LDFLAGS = -module -avoid-version +libtdm_drm_la_LIBADD = $(TDM_DRM_LIBS) -ldl + +libtdm_drm_la_SOURCES = \ + tdm_drm_format.c \ + tdm_drm_pp.c \ + tdm_drm_display.c \ + tdm_drm.c diff --git a/src/tdm_drm.c b/src/tdm_drm.c new file mode 100644 index 0000000..1817c6e --- /dev/null +++ b/src/tdm_drm.c @@ -0,0 +1,411 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if HAVE_UDEV +#include +#endif + +#include "tdm_drm.h" +#include + +#define ENABLE_PP + +#define TDM_DRM_NAME "vigs" + +static tdm_drm_data *drm_data; + +#ifdef HAVE_UDEV +static struct udev_device * +_tdm_find_primary_gpu(void) +{ + struct udev *udev; + struct udev_enumerate *e; + struct udev_list_entry *entry; + const char *path, *id; + struct udev_device *device, *drm_device, *pci; + + udev = udev_new(); + if (!udev) { + TDM_ERR("fail to initialize udev context\n"); + return NULL; + } + + e = udev_enumerate_new(udev); + udev_enumerate_add_match_subsystem(e, "drm"); + udev_enumerate_add_match_sysname(e, "card[0-9]*"); + + udev_enumerate_scan_devices(e); + drm_device = NULL; + udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) { + path = udev_list_entry_get_name(entry); + device = udev_device_new_from_syspath(udev, path); + if (!device) + continue; + + pci = udev_device_get_parent_with_subsystem_devtype(device, + "pci", NULL); + if (pci) { + id = udev_device_get_sysattr_value(pci, "boot_vga"); + if (id && !strcmp(id, "1")) { + if (drm_device) + udev_device_unref(drm_device); + drm_device = device; + break; + } + } + + if (!drm_device) + drm_device = device; + else + udev_device_unref(device); + } + + udev_enumerate_unref(e); + return drm_device; +} + +static tdm_error +_tdm_drm_udev_fd_handler(int fd, tdm_event_loop_mask mask, void *user_data) +{ + tdm_drm_data *edata = (tdm_drm_data*)user_data; + struct udev_device *dev; + const char *hotplug; + struct stat s; + dev_t udev_devnum; + int ret; + + dev = udev_monitor_receive_device(edata->uevent_monitor); + if (!dev) { + TDM_ERR("couldn't receive device"); + return TDM_ERROR_OPERATION_FAILED; + } + + udev_devnum = udev_device_get_devnum(dev); + + ret = fstat(edata->drm_fd, &s); + if (ret == -1) { + TDM_ERR("fstat failed"); + return TDM_ERROR_OPERATION_FAILED; + } + + hotplug = udev_device_get_property_value(dev, "HOTPLUG"); + + if (memcmp(&s.st_rdev, &udev_devnum, sizeof (dev_t)) == 0 && + hotplug && atoi(hotplug) == 1) + { + TDM_INFO("HotPlug"); + tdm_drm_display_update_output_status(edata); + } + + udev_device_unref(dev); + + return TDM_ERROR_NONE; +} + +static void +_tdm_drm_udev_init(tdm_drm_data *edata) +{ + struct udev *u = NULL; + struct udev_monitor *mon = NULL; + + u = udev_new(); + if (!u) { + TDM_ERR("couldn't create udev"); + goto failed; + } + + mon = udev_monitor_new_from_netlink(u, "udev"); + if (!mon) { + TDM_ERR("couldn't create udev monitor"); + goto failed; + } + + if (udev_monitor_filter_add_match_subsystem_devtype(mon, "drm", "drm_minor") > 0 || + udev_monitor_enable_receiving(mon) < 0) { + TDM_ERR("add match subsystem failed"); + goto failed; + } + + edata->uevent_source = + tdm_event_loop_add_fd_handler(edata->dpy, udev_monitor_get_fd(mon), + TDM_EVENT_LOOP_READABLE, + _tdm_drm_udev_fd_handler, + edata, NULL); + if (!edata->uevent_source) { + TDM_ERR("couldn't create udev event source"); + goto failed; + } + + edata->uevent_monitor = mon; + + TDM_INFO("hotplug monitor created"); + + return; +failed: + if (mon) + udev_monitor_unref(mon); + if (u) + udev_unref(u); +} + +static void +_tdm_drm_udev_deinit(tdm_drm_data *edata) +{ + if (edata->uevent_source) { + tdm_event_loop_source_remove(edata->uevent_source); + edata->uevent_source = NULL; + } + + if (edata->uevent_monitor) { + struct udev *u = udev_monitor_get_udev(edata->uevent_monitor); + udev_monitor_unref(edata->uevent_monitor); + udev_unref(u); + edata->uevent_monitor = NULL; + TDM_INFO("hotplug monitor destroyed"); + } +} +#endif + +static int +_tdm_drm_open_drm(void) +{ + int fd = -1; + + fd = drmOpen(TDM_DRM_NAME, NULL); + if (fd < 0) { + TDM_WRN("Cannot open '%s' drm", TDM_DRM_NAME); + } + +#ifdef HAVE_UDEV + if (fd < 0) { + struct udev_device *drm_device = NULL; + const char *filename; + TDM_WRN("Cannot open drm device.. search by udev"); + + drm_device = _tdm_find_primary_gpu(); + if (drm_device == NULL) { + TDM_ERR("fail to find drm device\n"); + goto close_l; + } + + filename = udev_device_get_devnode(drm_device); + + fd = open(filename, O_RDWR | O_CLOEXEC); + if (fd < 0) + TDM_ERR("Cannot open drm device(%s)\n", filename); + + TDM_DBG("open drm device (name:%s, fd:%d)", filename, fd); + + udev_device_unref(drm_device); + } +close_l: +#endif + return fd; +} + +void +tdm_drm_deinit(tdm_backend_data *bdata) +{ + if (drm_data != bdata) + return; + + TDM_INFO("deinit"); + +#ifdef HAVE_UDEV + _tdm_drm_udev_deinit(drm_data); +#endif + + tdm_drm_display_destroy_output_list(drm_data); + + if (drm_data->plane_res) + drmModeFreePlaneResources(drm_data->plane_res); + if (drm_data->mode_res) + drmModeFreeResources(drm_data->mode_res); + if (drm_data->drm_fd >= 0) + close(drm_data->drm_fd); + + free(drm_data); + drm_data = NULL; +} + +tdm_backend_data * +tdm_drm_init(tdm_display *dpy, tdm_error *error) +{ + tdm_func_display drm_func_display; + tdm_func_output drm_func_output; + tdm_func_layer drm_func_layer; +#ifdef ENABLE_PP + tdm_func_pp drm_func_pp; +#endif + tdm_error ret; + + if (!dpy) { + TDM_ERR("display is null"); + if (error) + *error = TDM_ERROR_INVALID_PARAMETER; + return NULL; + } + + if (drm_data) { + TDM_ERR("failed: init twice"); + if (error) + *error = TDM_ERROR_BAD_REQUEST; + return NULL; + } + + drm_data = calloc(1, sizeof(tdm_drm_data)); + if (!drm_data) { + TDM_ERR("alloc failed"); + if (error) + *error = TDM_ERROR_OUT_OF_MEMORY; + return NULL; + } + + LIST_INITHEAD(&drm_data->output_list); + LIST_INITHEAD(&drm_data->buffer_list); + + memset(&drm_func_display, 0, sizeof(drm_func_display)); + drm_func_display.display_get_capability = drm_display_get_capability; + drm_func_display.display_get_pp_capability = drm_display_get_pp_capability; + drm_func_display.display_get_outputs = drm_display_get_outputs; + drm_func_display.display_get_fd = drm_display_get_fd; + drm_func_display.display_handle_events = drm_display_handle_events; + drm_func_display.display_create_pp = drm_display_create_pp; + + memset(&drm_func_output, 0, sizeof(drm_func_output)); + drm_func_output.output_get_capability = drm_output_get_capability; + drm_func_output.output_get_layers = drm_output_get_layers; + drm_func_output.output_set_property = drm_output_set_property; + drm_func_output.output_get_property = drm_output_get_property; + drm_func_output.output_wait_vblank = drm_output_wait_vblank; + drm_func_output.output_set_vblank_handler = drm_output_set_vblank_handler; + drm_func_output.output_commit = drm_output_commit; + drm_func_output.output_set_commit_handler = drm_output_set_commit_handler; + drm_func_output.output_set_dpms = drm_output_set_dpms; + drm_func_output.output_get_dpms = drm_output_get_dpms; + drm_func_output.output_set_mode = drm_output_set_mode; + drm_func_output.output_get_mode = drm_output_get_mode; +#ifdef HAVE_UDEV + drm_func_output.output_set_status_handler = drm_output_set_status_handler; +#endif + + memset(&drm_func_layer, 0, sizeof(drm_func_layer)); + drm_func_layer.layer_get_capability = drm_layer_get_capability; + drm_func_layer.layer_set_property = drm_layer_set_property; + drm_func_layer.layer_get_property = drm_layer_get_property; + drm_func_layer.layer_set_info = drm_layer_set_info; + drm_func_layer.layer_get_info = drm_layer_get_info; + drm_func_layer.layer_set_buffer = drm_layer_set_buffer; + drm_func_layer.layer_unset_buffer = drm_layer_unset_buffer; + +#ifdef ENABLE_PP + memset(&drm_func_pp, 0, sizeof(drm_func_pp)); + drm_func_pp.pp_destroy = drm_pp_destroy; + drm_func_pp.pp_set_info = drm_pp_set_info; + drm_func_pp.pp_attach = drm_pp_attach; + drm_func_pp.pp_commit = drm_pp_commit; + drm_func_pp.pp_set_done_handler = drm_pp_set_done_handler; +#endif + + ret = tdm_backend_register_func_display(dpy, &drm_func_display); + if (ret != TDM_ERROR_NONE) + goto failed; + + ret = tdm_backend_register_func_output(dpy, &drm_func_output); + if (ret != TDM_ERROR_NONE) + goto failed; + + ret = tdm_backend_register_func_layer(dpy, &drm_func_layer); + if (ret != TDM_ERROR_NONE) + goto failed; + +#ifdef ENABLE_PP + ret = tdm_backend_register_func_pp(dpy, &drm_func_pp); + if (ret != TDM_ERROR_NONE) + goto failed; +#endif + + drm_data->dpy = dpy; + + /* The drm master fd can be opened by a tbm backend module in + * tbm_bufmgr_init() time. In this case, we just get it from + * TBM_DRM_MASTER_FD enviroment. + * + */ + drm_data->drm_fd = tdm_helper_get_fd("TBM_DRM_MASTER_FD"); + if (drm_data->drm_fd < 0) + drm_data->drm_fd = _tdm_drm_open_drm(); + + if (drm_data->drm_fd < 0) { + ret = TDM_ERROR_OPERATION_FAILED; + goto failed; + } + + /* To share the drm master fd with other modules in display server side. */ + tdm_helper_set_fd("TDM_DRM_MASTER_FD", drm_data->drm_fd); + +#ifdef HAVE_UDEV + _tdm_drm_udev_init(drm_data); +#endif + +#if LIBDRM_MAJOR_VERSION >= 2 && LIBDRM_MINOR_VERSION >= 4 && LIBDRM_MICRO_VERSION >= 47 + if (drmSetClientCap(drm_data->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) < 0) { + TDM_WRN("Set DRM_CLIENT_CAP_UNIVERSAL_PLANES failed"); + } else { + TDM_INFO("has universal planes"); + drm_data->has_universal_plane = 1; + } +#endif + + drm_data->mode_res = drmModeGetResources(drm_data->drm_fd); + if (!drm_data->mode_res) { + TDM_ERR("no drm resource: %m"); + ret = TDM_ERROR_OPERATION_FAILED; + goto failed; + } + + drm_data->plane_res = drmModeGetPlaneResources(drm_data->drm_fd); + if (!drm_data->plane_res) { + TDM_ERR("no drm plane resource: %m"); + ret = TDM_ERROR_OPERATION_FAILED; + goto failed; + } + + if (drm_data->plane_res->count_planes <= 0) { + TDM_ERR("no drm plane resource"); + ret = TDM_ERROR_OPERATION_FAILED; + goto failed; + } + + ret = tdm_drm_display_create_output_list(drm_data); + if (ret != TDM_ERROR_NONE) + goto failed; + + ret = tdm_drm_display_create_layer_list(drm_data); + if (ret != TDM_ERROR_NONE) + goto failed; + + if (error) + *error = TDM_ERROR_NONE; + + TDM_INFO("init success!"); + + return (tdm_backend_data *)drm_data; +failed: + if (error) + *error = ret; + + tdm_drm_deinit(drm_data); + + TDM_ERR("init failed!"); + return NULL; +} + +tdm_backend_module tdm_backend_module_data = { + "drm", + "Samsung", + TDM_BACKEND_SET_ABI_VERSION(1, 1), + tdm_drm_init, + tdm_drm_deinit +}; diff --git a/src/tdm_drm.h b/src/tdm_drm.h new file mode 100644 index 0000000..99d6a36 --- /dev/null +++ b/src/tdm_drm.h @@ -0,0 +1,133 @@ +#ifndef _TDM_DRM_H_ +#define _TDM_DRM_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if HAVE_UDEV +#include +#endif + +/* drm backend functions (display) */ +tdm_error drm_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps); +tdm_error drm_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps); +tdm_output** drm_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error); +tdm_error drm_display_get_fd(tdm_backend_data *bdata, int *fd); +tdm_error drm_display_handle_events(tdm_backend_data *bdata); +tdm_pp* drm_display_create_pp(tdm_backend_data *bdata, tdm_error *error); +tdm_error drm_output_get_capability(tdm_output *output, tdm_caps_output *caps); +tdm_layer** drm_output_get_layers(tdm_output *output, int *count, tdm_error *error); +tdm_error drm_output_set_property(tdm_output *output, unsigned int id, tdm_value value); +tdm_error drm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value); +tdm_error drm_output_wait_vblank(tdm_output *output, int interval, int sync, void *user_data); +tdm_error drm_output_set_vblank_handler(tdm_output *output, tdm_output_vblank_handler func); +tdm_error drm_output_commit(tdm_output *output, int sync, void *user_data); +tdm_error drm_output_set_commit_handler(tdm_output *output, tdm_output_commit_handler func); +tdm_error drm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value); +tdm_error drm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value); +tdm_error drm_output_set_mode(tdm_output *output, const tdm_output_mode *mode); +tdm_error drm_output_get_mode(tdm_output *output, const tdm_output_mode **mode); +tdm_error drm_output_set_status_handler(tdm_output *output, tdm_output_status_handler func, void *user_data); +tdm_error drm_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps); +tdm_error drm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value); +tdm_error drm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value); +tdm_error drm_layer_set_info(tdm_layer *layer, tdm_info_layer *info); +tdm_error drm_layer_get_info(tdm_layer *layer, tdm_info_layer *info); +tdm_error drm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer); +tdm_error drm_layer_unset_buffer(tdm_layer *layer); +void drm_pp_destroy(tdm_pp *pp); +tdm_error drm_pp_set_info(tdm_pp *pp, tdm_info_pp *info); +tdm_error drm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst); +tdm_error drm_pp_commit(tdm_pp *pp); +tdm_error drm_pp_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func, void *user_data); + +/* drm module internal macros, structures, functions */ +#define NEVER_GET_HERE() TDM_ERR("** NEVER GET HERE **") + +#define C(b,m) (((b) >> (m)) & 0xFF) +#define B(c,s) ((((unsigned int)(c)) & 0xff) << (s)) +#define FOURCC(a,b,c,d) (B(d,24) | B(c,16) | B(b,8) | B(a,0)) +#define FOURCC_STR(id) C(id,0), C(id,8), C(id,16), C(id,24) + +#define IS_RGB(format) (format == TBM_FORMAT_XRGB8888 || format == TBM_FORMAT_ARGB8888 || \ + format == TBM_FORMAT_XBGR8888 || format == TBM_FORMAT_ABGR8888) + +#define CLEAR(x) memset(&(x), 0, sizeof(x)) +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define SWAP(a, b) ({int t; t = a; a = b; b = t;}) +#define ROUNDUP(x) (ceil (floor ((float)(height) / 4))) + +#define ALIGN_TO_16B(x) ((((x) + (1 << 4) - 1) >> 4) << 4) +#define ALIGN_TO_32B(x) ((((x) + (1 << 5) - 1) >> 5) << 5) +#define ALIGN_TO_128B(x) ((((x) + (1 << 7) - 1) >> 7) << 7) +#define ALIGN_TO_2KB(x) ((((x) + (1 << 11) - 1) >> 11) << 11) +#define ALIGN_TO_8KB(x) ((((x) + (1 << 13) - 1) >> 13) << 13) +#define ALIGN_TO_64KB(x) ((((x) + (1 << 16) - 1) >> 16) << 16) + +#define RETURN_VAL_IF_FAIL(cond, val) {\ + if (!(cond)) {\ + TDM_ERR("'%s' failed", #cond);\ + return val;\ + }\ +} + +#define GOTO_IF_FAIL(cond, val) {\ + if (!(cond)) {\ + TDM_ERR("'%s' failed", #cond);\ + goto val;\ + }\ +} + +typedef struct _tdm_drm_data +{ + tdm_display *dpy; + + int drm_fd; + +#if LIBDRM_MAJOR_VERSION >= 2 && LIBDRM_MINOR_VERSION >= 4 && LIBDRM_MICRO_VERSION >= 47 + int has_universal_plane; +#endif + +#if HAVE_UDEV + struct udev_monitor *uevent_monitor; + tdm_event_loop_source *uevent_source; +#endif + + drmModeResPtr mode_res; + drmModePlaneResPtr plane_res; + + struct list_head output_list; + struct list_head buffer_list; +} tdm_drm_data; + +uint32_t tdm_drm_format_to_drm_format(tbm_format format); +tbm_format tdm_drm_format_to_tbm_format(uint32_t format); + +void tdm_drm_display_update_output_status(tdm_drm_data *drm_data); +tdm_error tdm_drm_display_create_output_list(tdm_drm_data *drm_data); +void tdm_drm_display_destroy_output_list(tdm_drm_data *drm_data); +tdm_error tdm_drm_display_create_layer_list(tdm_drm_data *drm_data); + +#endif /* _TDM_DRM_H_ */ diff --git a/src/tdm_drm_display.c b/src/tdm_drm_display.c new file mode 100644 index 0000000..312de60 --- /dev/null +++ b/src/tdm_drm_display.c @@ -0,0 +1,1704 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "tdm_drm.h" +#include "tdm_drm_pp.h" + +#define MIN_WIDTH 32 + +typedef struct _tdm_drm_output_data tdm_drm_output_data; +typedef struct _tdm_drm_layer_data tdm_drm_layer_data; +typedef struct _tdm_drm_event_data tdm_drm_event_data; + +typedef enum { + TDM_DRM_EVENT_TYPE_WAIT, + TDM_DRM_EVENT_TYPE_COMMIT, + TDM_DRM_EVENT_TYPE_PAGEFLIP, +} tdm_drm_event_type; + +typedef struct _tdm_drm_display_buffer { + struct list_head link; + + unsigned int fb_id; + tbm_surface_h buffer; + int width; +} tdm_drm_display_buffer; + +struct _tdm_drm_event_data { + tdm_drm_event_type type; + tdm_drm_output_data *output_data; + void *user_data; +}; + +struct _tdm_drm_output_data { + struct list_head link; + + /* data which are fixed at initializing */ + tdm_drm_data *drm_data; + uint32_t connector_id; + uint32_t encoder_id; + uint32_t crtc_id; + uint32_t pipe; + uint32_t dpms_prop_id; + int count_modes; + drmModeModeInfoPtr drm_modes; + tdm_output_mode *output_modes; + tdm_output_type connector_type; + unsigned int connector_type_id; + struct list_head layer_list; + tdm_drm_layer_data *primary_layer; + + /* not fixed data below */ + tdm_output_vblank_handler vblank_func; + tdm_output_commit_handler commit_func; + + tdm_output_conn_status status; + tdm_output_status_handler status_func; + void *status_user_data; + + int mode_changed; + const tdm_output_mode *current_mode; +}; + +struct _tdm_drm_layer_data { + struct list_head link; + + /* data which are fixed at initializing */ + tdm_drm_data *drm_data; + tdm_drm_output_data *output_data; + uint32_t plane_id; + tdm_layer_capability capabilities; + int zpos; + + /* not fixed data below */ + tdm_info_layer info; + int info_changed; + + tdm_drm_display_buffer *display_buffer; + int display_buffer_changed; +}; + +static drmModeModeInfoPtr +_tdm_drm_display_get_mode(tdm_drm_output_data *output_data) +{ + int i; + + if (!output_data->current_mode) { + TDM_ERR("no output_data->current_mode"); + return NULL; + } + + for (i = 0; i < output_data->count_modes; i++) { + drmModeModeInfoPtr drm_mode = &output_data->drm_modes[i]; + if ((drm_mode->hdisplay == output_data->current_mode->hdisplay) && + (drm_mode->vdisplay == output_data->current_mode->vdisplay) && + (drm_mode->vrefresh == output_data->current_mode->vrefresh) && + (drm_mode->flags == output_data->current_mode->flags) && + (drm_mode->type == output_data->current_mode->type) && + !(strncmp(drm_mode->name, output_data->current_mode->name, TDM_NAME_LEN))) + return drm_mode; + } + + return NULL; +} + +static tdm_drm_display_buffer * +_tdm_drm_display_find_buffer(tdm_drm_data *drm_data, tbm_surface_h buffer) +{ + tdm_drm_display_buffer *display_buffer = NULL; + + LIST_FOR_EACH_ENTRY(display_buffer, &drm_data->buffer_list, link) { + if (display_buffer->buffer == buffer) + return display_buffer; + } + + return NULL; +} + +static void +_tdm_drm_display_to_tdm_mode(drmModeModeInfoPtr drm_mode, + tdm_output_mode *tdm_mode) +{ + tdm_mode->clock = drm_mode->clock; + tdm_mode->hdisplay = drm_mode->hdisplay; + tdm_mode->hsync_start = drm_mode->hsync_start; + tdm_mode->hsync_end = drm_mode->hsync_end; + tdm_mode->htotal = drm_mode->htotal; + tdm_mode->hskew = drm_mode->hskew; + tdm_mode->vdisplay = drm_mode->vdisplay; + tdm_mode->vsync_start = drm_mode->vsync_start; + tdm_mode->vsync_end = drm_mode->vsync_end; + tdm_mode->vtotal = drm_mode->vtotal; + tdm_mode->vscan = drm_mode->vscan; + tdm_mode->vrefresh = drm_mode->vrefresh; + tdm_mode->flags = drm_mode->flags; + tdm_mode->type = drm_mode->type; + snprintf(tdm_mode->name, TDM_NAME_LEN, "%s", drm_mode->name); +} + +static tdm_error +_tdm_drm_display_get_cur_msc (int fd, int pipe, uint *msc) +{ + drmVBlank vbl; + + vbl.request.type = DRM_VBLANK_RELATIVE; + if (pipe > 0) + vbl.request.type |= DRM_VBLANK_SECONDARY; + + vbl.request.sequence = 0; + if (drmWaitVBlank(fd, &vbl)) { + TDM_ERR("get vblank counter failed: %m"); + *msc = 0; + return TDM_ERROR_OPERATION_FAILED; + } + + *msc = vbl.reply.sequence; + + return TDM_ERROR_NONE; +} + +static tdm_error +_tdm_drm_display_wait_vblank(int fd, int pipe, uint *target_msc, void *data) +{ + drmVBlank vbl; + + vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; + if (pipe > 0) + vbl.request.type |= DRM_VBLANK_SECONDARY; + + vbl.request.sequence = *target_msc; + vbl.request.signal = (unsigned long)(uintptr_t)data; + + if (drmWaitVBlank(fd, &vbl)) { + *target_msc = 0; + TDM_ERR("wait vblank failed: %m"); + return TDM_ERROR_OPERATION_FAILED; + } + + *target_msc = vbl.reply.sequence; + + return TDM_ERROR_NONE; +} + +static tdm_error +_tdm_drm_output_update_status(tdm_drm_output_data *output_data, + tdm_output_conn_status status) +{ + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + + if (output_data->status == status) + return TDM_ERROR_NONE; + + output_data->status = status; + + if (output_data->status_func) + output_data->status_func(output_data, status, + output_data->status_user_data); + + return TDM_ERROR_NONE; +} + +static tdm_error +_tdm_drm_display_commit_primary_layer(tdm_drm_layer_data *layer_data, + void *user_data, int *do_waitvblank) +{ + tdm_drm_data *drm_data = layer_data->drm_data; + tdm_drm_output_data *output_data = layer_data->output_data; + + if (output_data->mode_changed && layer_data->display_buffer_changed) { + drmModeModeInfoPtr mode; + + if (!layer_data->display_buffer) { + TDM_ERR("primary layer should have a buffer for modestting"); + return TDM_ERROR_BAD_REQUEST; + } + + output_data->mode_changed = 0; + layer_data->display_buffer_changed = 0; + layer_data->info_changed = 0; + + mode = _tdm_drm_display_get_mode(output_data); + if (!mode) { + TDM_ERR("couldn't find proper mode"); + return TDM_ERROR_BAD_REQUEST; + } + + if (drmModeSetCrtc(drm_data->drm_fd, output_data->crtc_id, + layer_data->display_buffer->fb_id, 0, 0, + &output_data->connector_id, 1, mode)) { + TDM_ERR("set crtc failed: %m"); + return TDM_ERROR_OPERATION_FAILED; + } + + _tdm_drm_output_update_status(output_data, TDM_OUTPUT_CONN_STATUS_MODE_SETTED); + + *do_waitvblank = 1; + return TDM_ERROR_NONE; + } else if (layer_data->display_buffer_changed) { + layer_data->display_buffer_changed = 0; + + if (!layer_data->display_buffer) { + if (drmModeSetCrtc(drm_data->drm_fd, output_data->crtc_id, + 0, 0, 0, NULL, 0, NULL)) { + TDM_ERR("unset crtc failed: %m"); + return TDM_ERROR_OPERATION_FAILED; + } + + if (output_data->status == TDM_OUTPUT_CONN_STATUS_MODE_SETTED) + _tdm_drm_output_update_status(output_data, TDM_OUTPUT_CONN_STATUS_CONNECTED); + + *do_waitvblank = 1; + } else { + tdm_drm_event_data *event_data = calloc(1, sizeof(tdm_drm_event_data)); + + if (!event_data) { + TDM_ERR("alloc failed"); + return TDM_ERROR_OUT_OF_MEMORY; + } + + event_data->type = TDM_DRM_EVENT_TYPE_PAGEFLIP; + event_data->output_data = output_data; + event_data->user_data = user_data; + if (drmModePageFlip(drm_data->drm_fd, output_data->crtc_id, + layer_data->display_buffer->fb_id, DRM_MODE_PAGE_FLIP_EVENT, event_data)) { + TDM_ERR("pageflip failed: %m"); + return TDM_ERROR_OPERATION_FAILED; + } + *do_waitvblank = 0; + } + } + + return TDM_ERROR_NONE; +} + +static tdm_error +_tdm_drm_display_commit_layer(tdm_drm_layer_data *layer_data) +{ + tdm_drm_data *drm_data = layer_data->drm_data; + tdm_drm_output_data *output_data = layer_data->output_data; + uint32_t fx, fy, fw, fh; + int crtc_w; + + if (!layer_data->display_buffer_changed && !layer_data->info_changed) + return TDM_ERROR_NONE; + + if (output_data->current_mode) + crtc_w = output_data->current_mode->hdisplay; + else { + drmModeCrtcPtr crtc = drmModeGetCrtc(drm_data->drm_fd, output_data->crtc_id); + if (!crtc) { + TDM_ERR("getting crtc failed"); + return TDM_ERROR_OPERATION_FAILED; + } + crtc_w = crtc->width; + if (crtc_w == 0) { + TDM_ERR("getting crtc width failed"); + drmModeFreeCrtc(crtc); + return TDM_ERROR_OPERATION_FAILED; + } + drmModeFreeCrtc(crtc); + } + + layer_data->display_buffer_changed = 0; + layer_data->info_changed = 0; + + if (!layer_data->display_buffer) { + if (drmModeSetPlane(drm_data->drm_fd, layer_data->plane_id, + output_data->crtc_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + TDM_ERR("unset plane(%d) filed: %m", layer_data->plane_id); + + return TDM_ERROR_NONE; + } + + /* Source values are 16.16 fixed point */ + fx = ((unsigned int)layer_data->info.src_config.pos.x) << 16; + fy = ((unsigned int)layer_data->info.src_config.pos.y) << 16; + fw = ((unsigned int)layer_data->info.src_config.pos.w) << 16; + fh = ((unsigned int)layer_data->info.src_config.pos.h) << 16; + + if (drmModeSetPlane(drm_data->drm_fd, layer_data->plane_id, + output_data->crtc_id, layer_data->display_buffer->fb_id, 0, + layer_data->info.dst_pos.x, layer_data->info.dst_pos.y, + layer_data->info.dst_pos.w, layer_data->info.dst_pos.h, + fx, fy, fw, fh) < 0) { + TDM_ERR("set plane(%d) failed: %m", layer_data->plane_id); + return TDM_ERROR_OPERATION_FAILED; + } + + TDM_DBG("plane(%d) crtc(%d) pos(%d) on: fb(%d,[%d,%d %dx%d]=>[%d,%d %dx%d])\n", + layer_data->plane_id, output_data->crtc_id, layer_data->zpos, + layer_data->display_buffer->fb_id, + layer_data->info.src_config.pos.x, layer_data->info.src_config.pos.y, + layer_data->info.src_config.pos.w, layer_data->info.src_config.pos.h, + layer_data->info.dst_pos.x, layer_data->info.dst_pos.y, + layer_data->info.dst_pos.w, layer_data->info.dst_pos.h); + + return TDM_ERROR_NONE; +} + +static void +_tdm_drm_display_cb_event(int fd, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, + void *user_data) +{ + tdm_drm_event_data *event_data = user_data; + tdm_drm_output_data *output_data; + + if (!event_data) { + TDM_ERR("no event data"); + return; + } + + output_data = event_data->output_data; + + switch (event_data->type) { + case TDM_DRM_EVENT_TYPE_PAGEFLIP: + if (output_data->commit_func) + output_data->commit_func(output_data, sequence, tv_sec, tv_usec, + event_data->user_data); + break; + case TDM_DRM_EVENT_TYPE_WAIT: + if (output_data->vblank_func) + output_data->vblank_func(output_data, sequence, tv_sec, tv_usec, + event_data->user_data); + break; + case TDM_DRM_EVENT_TYPE_COMMIT: + if (output_data->commit_func) + output_data->commit_func(output_data, sequence, tv_sec, tv_usec, + event_data->user_data); + break; + default: + break; + } + + free(event_data); +} + +static tdm_error +_tdm_drm_display_create_layer_list(tdm_drm_data *drm_data) +{ + tdm_drm_output_data *output_data = NULL; + int i; + + if (LIST_IS_EMPTY(&drm_data->output_list)) { + TDM_ERR("no output"); + return TDM_ERROR_OPERATION_FAILED; + } + + /* The TDM drm backend only support one output. */ + LIST_FOR_EACH_ENTRY(output_data, &drm_data->output_list, link) { + break; + } + + if (drm_data->plane_res->count_planes == 0) { + TDM_ERR("no layer error"); + return TDM_ERROR_OPERATION_FAILED; + } + + for (i = 0; i < drm_data->plane_res->count_planes; i++) { + tdm_drm_layer_data *layer_data; + drmModePlanePtr plane; + + plane = drmModeGetPlane(drm_data->drm_fd, drm_data->plane_res->planes[i]); + if (!plane) { + TDM_ERR("no plane"); + continue; + } + + if ((plane->possible_crtcs & (1 << output_data->pipe)) == 0) { + drmModeFreePlane(plane); + continue; + } + + layer_data = calloc(1, sizeof(tdm_drm_layer_data)); + if (!layer_data) { + TDM_ERR("alloc failed"); + drmModeFreePlane(plane); + continue; + } + + layer_data->drm_data = drm_data; + layer_data->output_data = output_data; + layer_data->plane_id = drm_data->plane_res->planes[i]; + + layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY | + TDM_LAYER_CAPABILITY_GRAPHIC; + output_data->primary_layer = layer_data; + + TDM_INFO("layer_data(%p) plane_id(%d) crtc_id(%d) capabilities(%x)", + layer_data, layer_data->plane_id, layer_data->output_data->crtc_id, + layer_data->capabilities); + + LIST_ADDTAIL(&layer_data->link, &output_data->layer_list); + + drmModeFreePlane(plane); + + /* can't take care of other planes for various hardware devices */ + break; + } + + return TDM_ERROR_NONE; +} + +#if LIBDRM_MAJOR_VERSION >= 2 && LIBDRM_MINOR_VERSION >= 4 && LIBDRM_MICRO_VERSION >= 47 + +static tdm_error +_tdm_drm_display_get_property(tdm_drm_data *drm_data, + unsigned int obj_id, unsigned int obj_type, + const char *name, unsigned int *value, + int *is_immutable) +{ + drmModeObjectPropertiesPtr props = NULL; + int i; + + props = drmModeObjectGetProperties(drm_data->drm_fd, obj_id, obj_type); + if (!props) + return TDM_ERROR_OPERATION_FAILED; + + for (i = 0; i < props->count_props; i++) { + drmModePropertyPtr prop = drmModeGetProperty(drm_data->drm_fd, + props->props[i]); + + if (!prop) + continue; + + if (!strcmp(prop->name, name)) { + if (is_immutable) + *is_immutable = prop->flags & DRM_MODE_PROP_IMMUTABLE; + if (value) + *value = (unsigned int)props->prop_values[i]; + drmModeFreeProperty(prop); + drmModeFreeObjectProperties(props); + return TDM_ERROR_NONE; + } + + drmModeFreeProperty(prop); + } + drmModeFreeObjectProperties(props); + TDM_DBG("coundn't find '%s' property", name); + return TDM_ERROR_OPERATION_FAILED; +} + +static tdm_error +_tdm_drm_display_create_layer_list_type(tdm_drm_data *drm_data) +{ + tdm_drm_output_data *output_data = NULL; + drmModePlanePtr *planes = NULL; + unsigned int *types = NULL; + unsigned int type = 0; + int plane_cnt, primary_cnt, ovl_cnt, cursor_cnt; + int opos_next, cpos_next; + tdm_error ret; + int i; + + if (LIST_IS_EMPTY(&drm_data->output_list)) { + TDM_ERR("no output"); + return TDM_ERROR_OPERATION_FAILED; + } + + /* The TDM drm backend only support one output. */ + LIST_FOR_EACH_ENTRY(output_data, &drm_data->output_list, link) { + break; + } + + ret = _tdm_drm_display_get_property(drm_data, + drm_data->plane_res->planes[0], + DRM_MODE_OBJECT_PLANE, "type", &type, + NULL); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("plane doesn't have 'type' property. Call a fallback function"); + + /* if a plane doesn't have "type" property, we call a fallback function + * as default + */ + return _tdm_drm_display_create_layer_list(drm_data); + } + + planes = calloc(drm_data->plane_res->count_planes, sizeof(drmModePlanePtr)); + if (!planes) { + TDM_ERR("alloc failed"); + goto failed; + } + + types = calloc(drm_data->plane_res->count_planes, sizeof(unsigned int)); + if (!types) { + TDM_ERR("alloc failed"); + goto failed; + } + + plane_cnt = 0; + for (i = 0; i < drm_data->plane_res->count_planes; i++) { + drmModePlanePtr plane; + + plane = drmModeGetPlane(drm_data->drm_fd, drm_data->plane_res->planes[i]); + if (!plane) { + TDM_ERR("no plane(%d)", drm_data->plane_res->planes[i]); + goto failed; + } + + if ((plane->possible_crtcs & (1 << output_data->pipe)) == 0) { + drmModeFreePlane(plane); + continue; + } + + ret = _tdm_drm_display_get_property(drm_data, + drm_data->plane_res->planes[i], + DRM_MODE_OBJECT_PLANE, "type", &type, + NULL); + if (ret != TDM_ERROR_NONE) { + drmModeFreePlane(plane); + TDM_ERR("plane(%d) doesn't have 'type' info", + drm_data->plane_res->planes[i]); + goto failed; + } + + planes[plane_cnt] = plane; + types[plane_cnt] = type; + plane_cnt++; + } + + primary_cnt = ovl_cnt = cursor_cnt = 0; + for (i = 0; i < plane_cnt; i++) { + if (types[i] == DRM_PLANE_TYPE_CURSOR) + cursor_cnt++; + else if (types[i] == DRM_PLANE_TYPE_OVERLAY) + ovl_cnt++; + else if (types[i] == DRM_PLANE_TYPE_PRIMARY) + primary_cnt++; + else + TDM_ERR("invalid type(%d)", types[i]); + } + + if (primary_cnt != 1) { + TDM_ERR("primary layer count(%d) should be one", primary_cnt); + goto failed; + } + + opos_next = 1; + cpos_next = ovl_cnt; + for (i = 0; i < plane_cnt; i++) { + tdm_drm_layer_data *layer_data; + + layer_data = calloc(1, sizeof(tdm_drm_layer_data)); + if (!layer_data) { + TDM_ERR("alloc failed"); + goto failed; + } + + layer_data->drm_data = drm_data; + layer_data->output_data = output_data; + layer_data->plane_id = planes[i]->plane_id; + + if (types[i] == DRM_PLANE_TYPE_CURSOR) { + layer_data->capabilities = TDM_LAYER_CAPABILITY_CURSOR | + TDM_LAYER_CAPABILITY_GRAPHIC; + layer_data->zpos = cpos_next++; + } else if (types[i] == DRM_PLANE_TYPE_OVERLAY) { + layer_data->capabilities = TDM_LAYER_CAPABILITY_OVERLAY | + TDM_LAYER_CAPABILITY_GRAPHIC; + layer_data->zpos = opos_next++; + } else if (types[i] == DRM_PLANE_TYPE_PRIMARY) { + layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY | + TDM_LAYER_CAPABILITY_GRAPHIC; + layer_data->zpos = 0; + output_data->primary_layer = layer_data; + } else { + free(layer_data); + continue; + } + + TDM_INFO("layer_data(%p) plane_id(%d) crtc_id(%d) zpos(%d) capabilities(%x)", + layer_data, layer_data->plane_id, layer_data->output_data->crtc_id, + layer_data->zpos, layer_data->capabilities); + + LIST_ADDTAIL(&layer_data->link, &output_data->layer_list); + } + + for (i = 0; i < plane_cnt; i++) + if (planes[i]) + drmModeFreePlane(planes[i]); + + free(planes); + free(types); + + return TDM_ERROR_NONE; + +failed: + if (planes) { + for (i = 0; i < drm_data->plane_res->count_planes; i++) + if (planes[i]) + drmModeFreePlane(planes[i]); + free(planes); + } + + free(types); + + return TDM_ERROR_OPERATION_FAILED; +} +#endif + +static void +_tdm_drm_display_cb_destroy_buffer(tbm_surface_h buffer, void *user_data) +{ + tdm_drm_data *drm_data; + tdm_drm_display_buffer *display_buffer; + int ret; + + if (!user_data) { + TDM_ERR("no user_data"); + return; + } + if (!buffer) { + TDM_ERR("no buffer"); + return; + } + + drm_data = (tdm_drm_data *)user_data; + + display_buffer = _tdm_drm_display_find_buffer(drm_data, buffer); + if (!display_buffer) { + TDM_ERR("no display_buffer"); + return; + } + LIST_DEL(&display_buffer->link); + + if (display_buffer->fb_id > 0) { + ret = drmModeRmFB(drm_data->drm_fd, display_buffer->fb_id); + if (ret < 0) { + TDM_ERR("rm fb failed"); + return; + } + TDM_DBG("drmModeRmFB success!!! fb_id:%d", display_buffer->fb_id); + } else + TDM_DBG("drmModeRmFB not called fb_id:%d", display_buffer->fb_id); + + free(display_buffer); +} + +tdm_error +tdm_drm_display_create_layer_list(tdm_drm_data *drm_data) +{ + tdm_drm_output_data *output_data = NULL; + tdm_error ret; + +#if LIBDRM_MAJOR_VERSION >= 2 && LIBDRM_MINOR_VERSION >= 4 && LIBDRM_MICRO_VERSION >= 47 + if (drm_data->has_universal_plane) + ret = _tdm_drm_display_create_layer_list_type(drm_data); + else +#endif + ret = _tdm_drm_display_create_layer_list(drm_data); + + if (ret != TDM_ERROR_NONE) + return ret; + + LIST_FOR_EACH_ENTRY(output_data, &drm_data->output_list, link) { + if (!output_data->primary_layer) { + TDM_ERR("output(%d) no primary layer", output_data->pipe); + return TDM_ERROR_OPERATION_FAILED; + } + } + + return TDM_ERROR_NONE; +} + +void +tdm_drm_display_destroy_output_list(tdm_drm_data *drm_data) +{ + tdm_drm_output_data *o = NULL, *oo = NULL; + + if (LIST_IS_EMPTY(&drm_data->output_list)) + return; + + LIST_FOR_EACH_ENTRY_SAFE(o, oo, &drm_data->output_list, link) { + LIST_DEL(&o->link); + if (!LIST_IS_EMPTY(&o->layer_list)) { + tdm_drm_layer_data *l = NULL, *ll = NULL; + LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link) { + LIST_DEL(&l->link); + free(l); + } + } + free(o->drm_modes); + free(o->output_modes); + free(o); + } +} + +void +tdm_drm_display_update_output_status(tdm_drm_data *drm_data) +{ + tdm_drm_output_data *output_data = NULL; + + if (LIST_IS_EMPTY(&drm_data->output_list)) + return; + + LIST_FOR_EACH_ENTRY(output_data, &drm_data->output_list, link) { + drmModeConnectorPtr connector; + tdm_output_conn_status new_status; + + connector = drmModeGetConnector(drm_data->drm_fd, + output_data->connector_id); + if (!connector) { + TDM_ERR("no connector: %d", output_data->connector_id); + continue; + } + + if (connector->connection == DRM_MODE_CONNECTED) + new_status = TDM_OUTPUT_CONN_STATUS_CONNECTED; + else + new_status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED; + + _tdm_drm_output_update_status(output_data, new_status); + + drmModeFreeConnector(connector); + } +} + +tdm_error +tdm_drm_display_create_output_list(tdm_drm_data *drm_data) +{ + tdm_drm_output_data *output_data; + int i; + tdm_error ret; + int allocated = 0; + + RETURN_VAL_IF_FAIL(LIST_IS_EMPTY(&drm_data->output_list), + TDM_ERROR_OPERATION_FAILED); + + for (i = 0; i < drm_data->mode_res->count_connectors; i++) { + drmModeConnectorPtr connector; + drmModeEncoderPtr encoder; + int crtc_id = 0, c, j; + + connector = drmModeGetConnector(drm_data->drm_fd, + drm_data->mode_res->connectors[i]); + if (!connector) { + TDM_ERR("no connector"); + ret = TDM_ERROR_OPERATION_FAILED; + goto failed_create; + } + + /* The TDM drm backend is not interested with disconnected connectors. + * And it only considers 1 connected connector because it is the TDM + * reference backend and can't take care of all hardware devices. + * To support various connectors, planes and crtcs, the new TDM backend + * should be implemented. + */ + if (connector->connection != DRM_MODE_CONNECTED) { + drmModeFreeConnector(connector); + continue; + } + + if (connector->count_encoders != 1) { + TDM_ERR("too many encoders: %d", connector->count_encoders); + drmModeFreeConnector(connector); + ret = TDM_ERROR_OPERATION_FAILED; + goto failed_create; + } + + encoder = drmModeGetEncoder(drm_data->drm_fd, connector->encoders[0]); + if (!encoder) { + TDM_ERR("no encoder"); + drmModeFreeConnector(connector); + ret = TDM_ERROR_OPERATION_FAILED; + goto failed_create; + } + + for (c = 0; c < drm_data->mode_res->count_crtcs; c++) { + if (allocated & (1 << c)) + continue; + + if ((encoder->possible_crtcs & (1 << c)) == 0) + continue; + + crtc_id = drm_data->mode_res->crtcs[c]; + allocated |= (1 << c); + break; + } + + if (crtc_id == 0) { + TDM_ERR("no possible crtc"); + drmModeFreeConnector(connector); + ret = TDM_ERROR_OPERATION_FAILED; + goto failed_create; + } + + output_data = calloc(1, sizeof(tdm_drm_output_data)); + if (!output_data) { + TDM_ERR("alloc failed"); + drmModeFreeConnector(connector); + drmModeFreeEncoder(encoder); + ret = TDM_ERROR_OUT_OF_MEMORY; + goto failed_create; + } + + LIST_INITHEAD(&output_data->layer_list); + + output_data->drm_data = drm_data; + output_data->connector_id = drm_data->mode_res->connectors[i]; + output_data->encoder_id = encoder->encoder_id; + output_data->crtc_id = crtc_id; + output_data->pipe = c; + output_data->connector_type = connector->connector_type; + output_data->connector_type_id = connector->connector_type_id; + + if (connector->connection == DRM_MODE_CONNECTED) + output_data->status = TDM_OUTPUT_CONN_STATUS_CONNECTED; + else + output_data->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED; + + for (j = 0; j < connector->count_props; j++) { + drmModePropertyPtr prop = drmModeGetProperty(drm_data->drm_fd, + connector->props[j]); + if (!prop) + continue; + if (!strcmp(prop->name, "DPMS")) { + output_data->dpms_prop_id = connector->props[j]; + drmModeFreeProperty(prop); + break; + } + drmModeFreeProperty(prop); + } + + if (output_data->dpms_prop_id == 0) + TDM_WRN("not support DPMS"); + + output_data->count_modes = connector->count_modes; + output_data->drm_modes = calloc(connector->count_modes, + sizeof(drmModeModeInfo)); + if (!output_data->drm_modes) { + TDM_ERR("alloc failed"); + free(output_data); + drmModeFreeConnector(connector); + drmModeFreeEncoder(encoder); + ret = TDM_ERROR_OUT_OF_MEMORY; + goto failed_create; + } + output_data->output_modes = calloc(connector->count_modes, + sizeof(tdm_output_mode)); + if (!output_data->output_modes) { + TDM_ERR("alloc failed"); + free(output_data->drm_modes); + free(output_data); + drmModeFreeConnector(connector); + drmModeFreeEncoder(encoder); + ret = TDM_ERROR_OUT_OF_MEMORY; + goto failed_create; + } + for (j = 0; j < connector->count_modes; j++) { + output_data->drm_modes[j] = connector->modes[j]; + _tdm_drm_display_to_tdm_mode(&output_data->drm_modes[j], + &output_data->output_modes[j]); + } + + LIST_ADDTAIL(&output_data->link, &drm_data->output_list); + + TDM_DBG("output_data(%p) connector_id(%d:%d:%d-%d) encoder_id(%d) crtc_id(%d) pipe(%d) dpms_id(%d)", + output_data, output_data->connector_id, output_data->status, + output_data->connector_type, + output_data->connector_type_id, output_data->encoder_id, output_data->crtc_id, + output_data->pipe, output_data->dpms_prop_id); + + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + + /* The TDM drm backend is not interested with disconnected connectors. + * And it only considers 1 connected connector because it is the TDM + * reference backend and can't take care of all hardware devices. + * To support various connectors, planes and crtcs, the new TDM backend + * should be implemented. + */ + break; + } + + TDM_DBG("output count: %d", drm_data->mode_res->count_connectors); + + return TDM_ERROR_NONE; +failed_create: + tdm_drm_display_destroy_output_list(drm_data); + return ret; +} + +tdm_error +drm_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps) +{ + RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER); + + caps->max_layer_count = -1; /* not defined */ + + return TDM_ERROR_NONE; +} + +tdm_error +drm_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps) +{ + return tdm_drm_pp_get_capability(bdata, caps); +} + +tdm_output ** +drm_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error) +{ + tdm_drm_data *drm_data = bdata; + tdm_drm_output_data *output_data = NULL; + tdm_output **outputs; + tdm_error ret; + int i; + + RETURN_VAL_IF_FAIL(drm_data, NULL); + RETURN_VAL_IF_FAIL(count, NULL); + + *count = 0; + LIST_FOR_EACH_ENTRY(output_data, &drm_data->output_list, link) + (*count)++; + + if (*count == 0) { + ret = TDM_ERROR_NONE; + goto failed_get; + } + + /* will be freed in frontend */ + outputs = calloc(*count, sizeof(tdm_drm_output_data *)); + if (!outputs) { + TDM_ERR("failed: alloc memory"); + *count = 0; + ret = TDM_ERROR_OUT_OF_MEMORY; + goto failed_get; + } + + i = 0; + LIST_FOR_EACH_ENTRY(output_data, &drm_data->output_list, link) + outputs[i++] = output_data; + + if (error) + *error = TDM_ERROR_NONE; + + return outputs; +failed_get: + if (error) + *error = ret; + return NULL; +} + +tdm_error +drm_display_get_fd(tdm_backend_data *bdata, int *fd) +{ + tdm_drm_data *drm_data = bdata; + + RETURN_VAL_IF_FAIL(drm_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(fd, TDM_ERROR_INVALID_PARAMETER); + + *fd = drm_data->drm_fd; + + return TDM_ERROR_NONE; +} + +tdm_error +drm_display_handle_events(tdm_backend_data *bdata) +{ + tdm_drm_data *drm_data = bdata; + drmEventContext ctx; + + RETURN_VAL_IF_FAIL(drm_data, TDM_ERROR_INVALID_PARAMETER); + + memset(&ctx, 0, sizeof(drmEventContext)); + + ctx.version = DRM_EVENT_CONTEXT_VERSION; + ctx.page_flip_handler = _tdm_drm_display_cb_event; + ctx.vblank_handler = _tdm_drm_display_cb_event; + + drmHandleEvent(drm_data->drm_fd, &ctx); + + return TDM_ERROR_NONE; +} + +tdm_pp * +drm_display_create_pp(tdm_backend_data *bdata, tdm_error *error) +{ + tdm_drm_data *drm_data = bdata; + + RETURN_VAL_IF_FAIL(drm_data, NULL); + + return tdm_drm_pp_create(drm_data, error); +} + +tdm_error +drm_output_get_capability(tdm_output *output, tdm_caps_output *caps) +{ + tdm_drm_output_data *output_data = output; + tdm_drm_data *drm_data; + drmModeConnectorPtr connector = NULL; + drmModeCrtcPtr crtc = NULL; + drmModeObjectPropertiesPtr props = NULL; + int i; + tdm_error ret; + + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER); + + memset(caps, 0, sizeof(tdm_caps_output)); + + drm_data = output_data->drm_data; + + snprintf(caps->maker, TDM_NAME_LEN, "unknown"); + snprintf(caps->model, TDM_NAME_LEN, "unknown"); + snprintf(caps->name, TDM_NAME_LEN, "unknown"); + + caps->status = output_data->status; + caps->type = output_data->connector_type; + caps->type_id = output_data->connector_type_id; + + connector = drmModeGetConnector(drm_data->drm_fd, output_data->connector_id); + RETURN_VAL_IF_FAIL(connector, TDM_ERROR_OPERATION_FAILED); + + caps->mode_count = connector->count_modes; + caps->modes = calloc(1, sizeof(tdm_output_mode) * caps->mode_count); + if (!caps->modes) { + ret = TDM_ERROR_OUT_OF_MEMORY; + TDM_ERR("alloc failed\n"); + goto failed_get; + } + for (i = 0; i < caps->mode_count; i++) + caps->modes[i] = output_data->output_modes[i]; + + caps->mmWidth = connector->mmWidth; + caps->mmHeight = connector->mmHeight; + caps->subpixel = connector->subpixel; + + caps->min_w = drm_data->mode_res->min_width; + caps->min_h = drm_data->mode_res->min_height; + caps->max_w = drm_data->mode_res->max_width; + caps->max_h = drm_data->mode_res->max_height; + caps->preferred_align = -1; + + crtc = drmModeGetCrtc(drm_data->drm_fd, output_data->crtc_id); + if (!crtc) { + ret = TDM_ERROR_OPERATION_FAILED; + TDM_ERR("get crtc failed: %m\n"); + goto failed_get; + } + + props = drmModeObjectGetProperties(drm_data->drm_fd, output_data->crtc_id, + DRM_MODE_OBJECT_CRTC); + if (!props) { + ret = TDM_ERROR_OPERATION_FAILED; + TDM_ERR("get crtc properties failed: %m\n"); + goto failed_get; + } + + caps->prop_count = props->count_props; + caps->props = calloc(1, sizeof(tdm_prop) * caps->prop_count); + if (!caps->props) { + ret = TDM_ERROR_OUT_OF_MEMORY; + TDM_ERR("alloc failed\n"); + goto failed_get; + } + + for (i = 0; i < caps->prop_count; i++) { + drmModePropertyPtr prop = drmModeGetProperty(drm_data->drm_fd, props->props[i]); + if (!prop) + continue; + snprintf(caps->props[i].name, TDM_NAME_LEN, "%s", prop->name); + caps->props[i].id = props->props[i]; + drmModeFreeProperty(prop); + } + + drmModeFreeObjectProperties(props); + drmModeFreeCrtc(crtc); + drmModeFreeConnector(connector); + + return TDM_ERROR_NONE; +failed_get: + drmModeFreeCrtc(crtc); + drmModeFreeObjectProperties(props); + drmModeFreeConnector(connector); + free(caps->modes); + free(caps->props); + memset(caps, 0, sizeof(tdm_caps_output)); + return ret; +} + +tdm_layer ** +drm_output_get_layers(tdm_output *output, int *count, tdm_error *error) +{ + tdm_drm_output_data *output_data = output; + tdm_drm_layer_data *layer_data = NULL; + tdm_layer **layers; + tdm_error ret; + int i; + + RETURN_VAL_IF_FAIL(output_data, NULL); + RETURN_VAL_IF_FAIL(count, NULL); + + *count = 0; + LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) + (*count)++; + + if (*count == 0) { + ret = TDM_ERROR_NONE; + goto failed_get; + } + + /* will be freed in frontend */ + layers = calloc(*count, sizeof(tdm_drm_layer_data *)); + if (!layers) { + TDM_ERR("failed: alloc memory"); + *count = 0; + ret = TDM_ERROR_OUT_OF_MEMORY; + goto failed_get; + } + + i = 0; + LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) + layers[i++] = layer_data; + + if (error) + *error = TDM_ERROR_NONE; + + return layers; +failed_get: + if (error) + *error = ret; + return NULL; +} + +tdm_error +drm_output_set_property(tdm_output *output, unsigned int id, tdm_value value) +{ + tdm_drm_output_data *output_data = output; + tdm_drm_data *drm_data; + int ret; + + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(output_data->crtc_id > 0, TDM_ERROR_INVALID_PARAMETER); + + drm_data = output_data->drm_data; + ret = drmModeObjectSetProperty(drm_data->drm_fd, + output_data->crtc_id, DRM_MODE_OBJECT_CRTC, + id, value.u32); + if (ret < 0) { + TDM_ERR("set property failed: %m"); + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +tdm_error +drm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value) +{ + tdm_drm_output_data *output_data = output; + tdm_drm_data *drm_data; + drmModeObjectPropertiesPtr props; + int i; + + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(output_data->crtc_id > 0, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(value, TDM_ERROR_INVALID_PARAMETER); + + drm_data = output_data->drm_data; + props = drmModeObjectGetProperties(drm_data->drm_fd, output_data->crtc_id, + DRM_MODE_OBJECT_CRTC); + if (props == NULL) { + TDM_ERR("get property failed: %m"); + return TDM_ERROR_OPERATION_FAILED; + } + + for (i = 0; i < props->count_props; i++) + if (props->props[i] == id) { + (*value).u32 = (uint)props->prop_values[i]; + break; + } + + drmModeFreeObjectProperties(props); + + return TDM_ERROR_NONE; +} + +tdm_error +drm_output_wait_vblank(tdm_output *output, int interval, int sync, + void *user_data) +{ + tdm_drm_output_data *output_data = output; + tdm_drm_data *drm_data; + tdm_drm_event_data *event_data; + uint target_msc; + tdm_error ret; + + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + + event_data = calloc(1, sizeof(tdm_drm_event_data)); + if (!event_data) { + TDM_ERR("alloc failed"); + return TDM_ERROR_OUT_OF_MEMORY; + } + + drm_data = output_data->drm_data; + + ret = _tdm_drm_display_get_cur_msc(drm_data->drm_fd, output_data->pipe, + &target_msc); + if (ret != TDM_ERROR_NONE) + goto failed_vblank; + + target_msc += interval; + + event_data->type = TDM_DRM_EVENT_TYPE_WAIT; + event_data->output_data = output_data; + event_data->user_data = user_data; + + ret = _tdm_drm_display_wait_vblank(drm_data->drm_fd, output_data->pipe, + &target_msc, event_data); + if (ret != TDM_ERROR_NONE) + goto failed_vblank; + + return TDM_ERROR_NONE; +failed_vblank: + free(event_data); + return ret; +} + +tdm_error +drm_output_set_vblank_handler(tdm_output *output, + tdm_output_vblank_handler func) +{ + tdm_drm_output_data *output_data = output; + + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER); + + output_data->vblank_func = func; + + return TDM_ERROR_NONE; +} + +tdm_error +drm_output_commit(tdm_output *output, int sync, void *user_data) +{ + tdm_drm_output_data *output_data = output; + tdm_drm_data *drm_data; + tdm_drm_layer_data *layer_data = NULL; + tdm_error ret; + int do_waitvblank = 1; + + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + + drm_data = output_data->drm_data; + + LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) { + if (layer_data == output_data->primary_layer) { + ret = _tdm_drm_display_commit_primary_layer(layer_data, user_data, + &do_waitvblank); + if (ret != TDM_ERROR_NONE) + return ret; + } else { + ret = _tdm_drm_display_commit_layer(layer_data); + if (ret != TDM_ERROR_NONE) + return ret; + } + } + + if (do_waitvblank == 1) { + tdm_drm_event_data *event_data = calloc(1, sizeof(tdm_drm_event_data)); + uint target_msc; + + if (!event_data) { + TDM_ERR("alloc failed"); + return TDM_ERROR_OUT_OF_MEMORY; + } + + ret = _tdm_drm_display_get_cur_msc(drm_data->drm_fd, output_data->pipe, + &target_msc); + if (ret != TDM_ERROR_NONE) { + free(event_data); + return ret; + } + + target_msc++; + + event_data->type = TDM_DRM_EVENT_TYPE_COMMIT; + event_data->output_data = output_data; + event_data->user_data = user_data; + + ret = _tdm_drm_display_wait_vblank(drm_data->drm_fd, output_data->pipe, + &target_msc, event_data); + if (ret != TDM_ERROR_NONE) { + free(event_data); + return ret; + } + } + + return TDM_ERROR_NONE; +} + +tdm_error +drm_output_set_commit_handler(tdm_output *output, + tdm_output_commit_handler func) +{ + tdm_drm_output_data *output_data = output; + + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER); + + output_data->commit_func = func; + + return TDM_ERROR_NONE; +} + +tdm_error +drm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) +{ + tdm_drm_output_data *output_data = output; + tdm_drm_data *drm_data; + int ret; + + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + + if (output_data->dpms_prop_id == 0) { + TDM_WRN("not support DPMS"); + return TDM_ERROR_OPERATION_FAILED; + } + + drm_data = output_data->drm_data; + ret = drmModeObjectSetProperty(drm_data->drm_fd, + output_data->connector_id, DRM_MODE_OBJECT_CONNECTOR, + output_data->dpms_prop_id, dpms_value); + if (ret < 0) { + TDM_ERR("set dpms failed: %m"); + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +tdm_error +drm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value) +{ + tdm_drm_output_data *output_data = output; + tdm_drm_data *drm_data; + drmModeObjectPropertiesPtr props; + int i; + + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(dpms_value, TDM_ERROR_INVALID_PARAMETER); + + drm_data = output_data->drm_data; + props = drmModeObjectGetProperties(drm_data->drm_fd, output_data->connector_id, + DRM_MODE_OBJECT_CONNECTOR); + if (props == NULL) { + TDM_ERR("get property failed: %m"); + return TDM_ERROR_OPERATION_FAILED; + } + + for (i = 0; i < props->count_props; i++) + if (props->props[i] == output_data->dpms_prop_id) { + *dpms_value = (uint)props->prop_values[i]; + break; + } + + drmModeFreeObjectProperties(props); + + return TDM_ERROR_NONE; +} + +tdm_error +drm_output_set_mode(tdm_output *output, const tdm_output_mode *mode) +{ + tdm_drm_output_data *output_data = output; + + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER); + + output_data->current_mode = mode; + output_data->mode_changed = 1; + + return TDM_ERROR_NONE; +} + +tdm_error +drm_output_get_mode(tdm_output *output, const tdm_output_mode **mode) +{ + tdm_drm_output_data *output_data = output; + + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER); + + *mode = output_data->current_mode; + + return TDM_ERROR_NONE; +} + +tdm_error +drm_output_set_status_handler(tdm_output *output, + tdm_output_status_handler func, + void *user_data) +{ + tdm_drm_output_data *output_data = output; + + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER); + + output_data->status_func = func; + output_data->status_user_data = user_data; + + return TDM_ERROR_NONE; +} + +tdm_error +drm_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps) +{ + tdm_drm_layer_data *layer_data = layer; + tdm_drm_data *drm_data; + drmModePlanePtr plane = NULL; + drmModeObjectPropertiesPtr props = NULL; + int i, format_count = 0; + tdm_error ret; + + RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER); + + memset(caps, 0, sizeof(tdm_caps_layer)); + + drm_data = layer_data->drm_data; + plane = drmModeGetPlane(drm_data->drm_fd, layer_data->plane_id); + if (!plane) { + TDM_ERR("get plane failed: %m"); + ret = TDM_ERROR_OPERATION_FAILED; + goto failed_get; + } + + caps->capabilities = layer_data->capabilities; + caps->zpos = layer_data->zpos; /* if VIDEO layer, zpos is -1 */ + + caps->format_count = plane->count_formats; + caps->formats = calloc(1, sizeof(tbm_format) * caps->format_count); + 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++) { + /* TODO: kernel reports wrong formats */ + if (plane->formats[i] != DRM_FORMAT_XRGB8888 && + plane->formats[i] != DRM_FORMAT_ARGB8888) + continue; + caps->formats[i] = tdm_drm_format_to_tbm_format(plane->formats[i]); + format_count++; + } + + caps->format_count = format_count; + + props = drmModeObjectGetProperties(drm_data->drm_fd, layer_data->plane_id, + DRM_MODE_OBJECT_PLANE); + if (!props) { + ret = TDM_ERROR_OPERATION_FAILED; + TDM_ERR("get plane properties failed: %m\n"); + goto failed_get; + } + + caps->props = calloc(1, sizeof(tdm_prop) * props->count_props); + if (!caps->props) { + ret = TDM_ERROR_OUT_OF_MEMORY; + TDM_ERR("alloc failed\n"); + goto failed_get; + } + + caps->prop_count = 0; + for (i = 0; i < props->count_props; i++) { + drmModePropertyPtr prop = drmModeGetProperty(drm_data->drm_fd, props->props[i]); + if (!prop) + continue; + if (!strncmp(prop->name, "type", TDM_NAME_LEN)) + continue; + if (!strncmp(prop->name, "zpos", TDM_NAME_LEN)) + continue; + snprintf(caps->props[i].name, TDM_NAME_LEN, "%s", prop->name); + caps->props[i].id = props->props[i]; + caps->prop_count++; + drmModeFreeProperty(prop); + } + + drmModeFreeObjectProperties(props); + drmModeFreePlane(plane); + + return TDM_ERROR_NONE; +failed_get: + drmModeFreeObjectProperties(props); + drmModeFreePlane(plane); + free(caps->formats); + free(caps->props); + memset(caps, 0, sizeof(tdm_caps_layer)); + return ret; +} + +tdm_error +drm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value) +{ + tdm_drm_layer_data *layer_data = layer; + tdm_drm_data *drm_data; + int ret; + + RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(layer_data->plane_id > 0, TDM_ERROR_INVALID_PARAMETER); + + drm_data = layer_data->drm_data; + ret = drmModeObjectSetProperty(drm_data->drm_fd, + layer_data->plane_id, DRM_MODE_OBJECT_PLANE, + id, value.u32); + if (ret < 0) { + TDM_ERR("set property failed: %m"); + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +tdm_error +drm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value) +{ + tdm_drm_layer_data *layer_data = layer; + tdm_drm_data *drm_data; + drmModeObjectPropertiesPtr props; + int i; + + RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(layer_data->plane_id > 0, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(value, TDM_ERROR_INVALID_PARAMETER); + + drm_data = layer_data->drm_data; + props = drmModeObjectGetProperties(drm_data->drm_fd, layer_data->plane_id, + DRM_MODE_OBJECT_PLANE); + if (props == NULL) { + TDM_ERR("get property failed: %m"); + return TDM_ERROR_OPERATION_FAILED; + } + + for (i = 0; i < props->count_props; i++) + if (props->props[i] == id) { + (*value).u32 = (uint)props->prop_values[i]; + break; + } + + drmModeFreeObjectProperties(props); + + return TDM_ERROR_NONE; +} + +tdm_error +drm_layer_set_info(tdm_layer *layer, tdm_info_layer *info) +{ + tdm_drm_layer_data *layer_data = layer; + + RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER); + + layer_data->info = *info; + layer_data->info_changed = 1; + + return TDM_ERROR_NONE; +} + +tdm_error +drm_layer_get_info(tdm_layer *layer, tdm_info_layer *info) +{ + tdm_drm_layer_data *layer_data = layer; + + RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER); + + *info = layer_data->info; + + return TDM_ERROR_NONE; +} + +tdm_error +drm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) +{ + tdm_drm_layer_data *layer_data = layer; + tdm_drm_data *drm_data; + tdm_drm_display_buffer *display_buffer; + tdm_error err = TDM_ERROR_NONE; + int ret, i, count; + + RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(buffer, TDM_ERROR_INVALID_PARAMETER); + + drm_data = layer_data->drm_data; + + display_buffer = _tdm_drm_display_find_buffer(drm_data, buffer); + if (!display_buffer) { + display_buffer = calloc(1, sizeof(tdm_drm_display_buffer)); + if (!display_buffer) { + TDM_ERR("alloc failed"); + return TDM_ERROR_OUT_OF_MEMORY; + } + display_buffer->buffer = buffer; + + err = tdm_buffer_add_destroy_handler(buffer, _tdm_drm_display_cb_destroy_buffer, + drm_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, &drm_data->buffer_list); + } + + if (display_buffer->fb_id == 0) { + unsigned int width; + unsigned int height; + unsigned int format; + unsigned int handles[4] = {0,}; + unsigned int pitches[4] = {0,}; + unsigned int offsets[4] = {0,}; + unsigned int size; + + width = tbm_surface_get_width(buffer); + height = tbm_surface_get_height(buffer); + format = tbm_surface_get_format(buffer); + count = tbm_surface_internal_get_num_bos(buffer); + for (i = 0; i < count; i++) { + tbm_bo bo = tbm_surface_internal_get_bo(buffer, i); + handles[i] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32; + } + count = tbm_surface_internal_get_num_planes(format); + for (i = 0; i < count; i++) + tbm_surface_internal_get_plane_data(buffer, i, &size, &offsets[i], &pitches[i]); + + ret = drmModeAddFB2(drm_data->drm_fd, width, height, format, + handles, pitches, offsets, &display_buffer->fb_id, 0); + if (ret < 0) { + TDM_ERR("add fb failed: %m"); + return TDM_ERROR_OPERATION_FAILED; + } + TDM_DBG("drm_data->drm_fd : %d, display_buffer->fb_id:%u", drm_data->drm_fd, + display_buffer->fb_id); + + if (IS_RGB(format)) + display_buffer->width = pitches[0] >> 2; + else + display_buffer->width = pitches[0]; + } + + layer_data->display_buffer = display_buffer; + layer_data->display_buffer_changed = 1; + + return TDM_ERROR_NONE; +} + +tdm_error +drm_layer_unset_buffer(tdm_layer *layer) +{ + tdm_drm_layer_data *layer_data = layer; + + RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER); + + layer_data->display_buffer = NULL; + layer_data->display_buffer_changed = 1; + + return TDM_ERROR_NONE; +} diff --git a/src/tdm_drm_format.c b/src/tdm_drm_format.c new file mode 100644 index 0000000..eeda432 --- /dev/null +++ b/src/tdm_drm_format.c @@ -0,0 +1,104 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "tdm_drm.h" + +typedef struct { + tbm_format tbm_format; + uint32_t drm_format; +} tbm_drm_format_data; + +static const tbm_drm_format_data formats[] = { + {TBM_FORMAT_C8, DRM_FORMAT_C8}, + {TBM_FORMAT_RGB332, DRM_FORMAT_RGB332}, + {TBM_FORMAT_BGR233, DRM_FORMAT_BGR233}, + {TBM_FORMAT_XRGB4444, DRM_FORMAT_XRGB4444}, + {TBM_FORMAT_XBGR4444, DRM_FORMAT_XBGR4444}, + {TBM_FORMAT_RGBX4444, DRM_FORMAT_RGBX4444}, + {TBM_FORMAT_BGRX4444, DRM_FORMAT_BGRX4444}, + {TBM_FORMAT_ARGB4444, DRM_FORMAT_ARGB4444}, + {TBM_FORMAT_ABGR4444, DRM_FORMAT_ABGR4444}, + {TBM_FORMAT_RGBA4444, DRM_FORMAT_RGBA4444}, + {TBM_FORMAT_BGRA4444, DRM_FORMAT_BGRA4444}, + {TBM_FORMAT_XRGB1555, DRM_FORMAT_XRGB1555}, + {TBM_FORMAT_XBGR1555, DRM_FORMAT_XBGR1555}, + {TBM_FORMAT_RGBX5551, DRM_FORMAT_RGBX5551}, + {TBM_FORMAT_BGRX5551, DRM_FORMAT_BGRX5551}, + {TBM_FORMAT_ARGB1555, DRM_FORMAT_ARGB1555}, + {TBM_FORMAT_ABGR1555, DRM_FORMAT_ABGR1555}, + {TBM_FORMAT_RGBA5551, DRM_FORMAT_RGBA5551}, + {TBM_FORMAT_BGRA5551, DRM_FORMAT_BGRA5551}, + {TBM_FORMAT_RGB565, DRM_FORMAT_RGB565}, + {TBM_FORMAT_BGR565, DRM_FORMAT_BGR565}, + {TBM_FORMAT_RGB888, DRM_FORMAT_RGB888}, + {TBM_FORMAT_BGR888, DRM_FORMAT_BGR888}, + {TBM_FORMAT_XRGB8888, DRM_FORMAT_XRGB8888}, + {TBM_FORMAT_XBGR8888, DRM_FORMAT_XBGR8888}, + {TBM_FORMAT_RGBX8888, DRM_FORMAT_RGBX8888}, + {TBM_FORMAT_BGRX8888, DRM_FORMAT_BGRX8888}, + {TBM_FORMAT_ARGB8888, DRM_FORMAT_ARGB8888}, + {TBM_FORMAT_ABGR8888, DRM_FORMAT_ABGR8888}, + {TBM_FORMAT_RGBA8888, DRM_FORMAT_RGBA8888}, + {TBM_FORMAT_BGRA8888, DRM_FORMAT_BGRA8888}, + {TBM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB2101010}, + {TBM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR2101010}, + {TBM_FORMAT_RGBX1010102, DRM_FORMAT_RGBX1010102}, + {TBM_FORMAT_BGRX1010102, DRM_FORMAT_BGRX1010102}, + {TBM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB2101010}, + {TBM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR2101010}, + {TBM_FORMAT_RGBA1010102, DRM_FORMAT_RGBA1010102}, + {TBM_FORMAT_BGRA1010102, DRM_FORMAT_BGRA1010102}, + {TBM_FORMAT_YUYV, DRM_FORMAT_YUYV}, + {TBM_FORMAT_YVYU, DRM_FORMAT_YVYU}, + {TBM_FORMAT_UYVY, DRM_FORMAT_UYVY}, + {TBM_FORMAT_VYUY, DRM_FORMAT_VYUY}, + {TBM_FORMAT_AYUV, DRM_FORMAT_AYUV}, + {TBM_FORMAT_NV12, DRM_FORMAT_NV12}, + {TBM_FORMAT_NV21, DRM_FORMAT_NV21}, + {TBM_FORMAT_NV16, DRM_FORMAT_NV16}, + {TBM_FORMAT_NV61, DRM_FORMAT_NV61}, + {TBM_FORMAT_YUV410, DRM_FORMAT_YUV410}, + {TBM_FORMAT_YVU410, DRM_FORMAT_YVU410}, + {TBM_FORMAT_YUV411, DRM_FORMAT_YUV411}, + {TBM_FORMAT_YVU411, DRM_FORMAT_YVU411}, + {TBM_FORMAT_YUV420, DRM_FORMAT_YUV420}, + {TBM_FORMAT_YVU420, DRM_FORMAT_YVU420}, + {TBM_FORMAT_YUV422, DRM_FORMAT_YUV422}, + {TBM_FORMAT_YVU422, DRM_FORMAT_YVU422}, + {TBM_FORMAT_YUV444, DRM_FORMAT_YUV444}, + {TBM_FORMAT_YVU444, DRM_FORMAT_YVU444}, +}; + +#define NUM_FORMATS (sizeof(formats) / sizeof(formats[0])) + +uint32_t +tdm_drm_format_to_drm_format(tbm_format format) +{ + int i; + + for (i = 0; i < NUM_FORMATS; i++) + if (formats[i].tbm_format == format) + return formats[i].drm_format; + + TDM_ERR("tbm format '%c%c%c%c' not found", FOURCC_STR(format)); + + return 0; +} + +tbm_format +tdm_drm_format_to_tbm_format(uint32_t format) +{ + int i; + + for (i = 0; i < NUM_FORMATS; i++) + if (formats[i].drm_format == format) + return formats[i].tbm_format; + + TDM_ERR("drm format '%c%c%c%c' not found", FOURCC_STR(format)); + + return 0; +} diff --git a/src/tdm_drm_pp.c b/src/tdm_drm_pp.c new file mode 100644 index 0000000..97ee9de --- /dev/null +++ b/src/tdm_drm_pp.c @@ -0,0 +1,411 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "tdm_drm.h" +#include "tdm_helper.h" + +typedef struct _tdm_drm_pp_buffer { + tbm_surface_h src; + tbm_surface_h dst; + + struct list_head link; +} tdm_drm_pp_buffer; + +typedef struct _tdm_drm_pp_data { + tdm_drm_data *drm_data; + + tdm_info_pp info; + + struct list_head pending_buffer_list; + + tdm_pp_done_handler done_func; + void *done_user_data; + + struct list_head link; +} tdm_drm_pp_data; + + +static tbm_format pp_formats[] = { + TBM_FORMAT_ARGB8888, + TBM_FORMAT_XRGB8888, + TBM_FORMAT_YUV420, + TBM_FORMAT_YVU420 +}; + +#define NUM_PP_FORMAT (sizeof(pp_formats) / sizeof(pp_formats[0])) + +static int pp_list_init; +static struct list_head pp_list; + +static pixman_format_code_t +_tdm_drm_pp_pixman_get_format(tbm_format tbmfmt) +{ + switch (tbmfmt) { + case TBM_FORMAT_ARGB8888: + return PIXMAN_a8r8g8b8; + case TBM_FORMAT_XRGB8888: + return PIXMAN_x8r8g8b8; + case TBM_FORMAT_YUV420: + case TBM_FORMAT_YVU420: + return PIXMAN_yv12; + default: + return 0; + } +} + +int +_tdm_drm_pp_pixman_convert(pixman_op_t op, + unsigned char *srcbuf, unsigned char *dstbuf, + pixman_format_code_t src_format, pixman_format_code_t dst_format, + int sbw, int sbh, int sx, int sy, int sw, int sh, + int dbw, int dbh, int dx, int dy, int dw, int dh, + int rotate, int hflip, int vflip) +{ + pixman_image_t *src_img; + pixman_image_t *dst_img; + struct pixman_f_transform ft; + pixman_transform_t transform; + int src_stride, dst_stride; + int src_bpp; + int dst_bpp; + double scale_x, scale_y; + int rotate_step; + int ret = 0; + + RETURN_VAL_IF_FAIL(srcbuf != NULL, 0); + RETURN_VAL_IF_FAIL(dstbuf != NULL, 0); + + TDM_DBG("src(%dx%d: %d,%d %dx%d) dst(%dx%d: %d,%d %dx%d) flip(%d,%d), rot(%d)", + sbw, sbh, sx, sy, sw, sh, dbw, dbh, dx, dy, dw, dh, hflip, vflip, rotate); + + src_bpp = PIXMAN_FORMAT_BPP(src_format) / 8; + RETURN_VAL_IF_FAIL(src_bpp > 0, 0); + + dst_bpp = PIXMAN_FORMAT_BPP(dst_format) / 8; + RETURN_VAL_IF_FAIL(dst_bpp > 0, 0); + + rotate_step = (rotate + 360) / 90 % 4; + + src_stride = sbw * src_bpp; + dst_stride = dbw * dst_bpp; + + src_img = pixman_image_create_bits(src_format, sbw, sbh, (uint32_t *)srcbuf, + src_stride); + dst_img = pixman_image_create_bits(dst_format, dbw, dbh, (uint32_t *)dstbuf, + dst_stride); + + GOTO_IF_FAIL(src_img != NULL, CANT_CONVERT); + GOTO_IF_FAIL(dst_img != NULL, CANT_CONVERT); + + pixman_f_transform_init_identity(&ft); + + if (hflip) { + pixman_f_transform_scale(&ft, NULL, -1, 1); + pixman_f_transform_translate(&ft, NULL, dw, 0); + } + + if (vflip) { + pixman_f_transform_scale(&ft, NULL, 1, -1); + pixman_f_transform_translate(&ft, NULL, 0, dh); + } + + if (rotate_step > 0) { + int c = 0, s = 0, tx = 0, ty = 0; + switch (rotate_step) { + case 1: /* 90 degrees */ + s = -1, tx = -dw; + break; + case 2: /* 180 degrees */ + c = -1, tx = -dw, ty = -dh; + break; + case 3: /* 270 degrees */ + s = 1, ty = -dh; + break; + default: + break; + } + + pixman_f_transform_translate(&ft, NULL, tx, ty); + pixman_f_transform_rotate(&ft, NULL, c, s); + } + + if (rotate_step % 2 == 0) { + scale_x = (double)sw / dw; + scale_y = (double)sh / dh; + } else { + scale_x = (double)sw / dh; + scale_y = (double)sh / dw; + } + + pixman_f_transform_scale(&ft, NULL, scale_x, scale_y); + pixman_f_transform_translate(&ft, NULL, sx, sy); + + pixman_transform_from_pixman_f_transform(&transform, &ft); + pixman_image_set_transform(src_img, &transform); + + pixman_image_composite(op, src_img, NULL, dst_img, 0, 0, 0, 0, dx, dy, dw, dh); + + ret = 1; + +CANT_CONVERT: + if (src_img) + pixman_image_unref(src_img); + if (dst_img) + pixman_image_unref(dst_img); + + return ret; +} + +static tdm_error +_tdm_drm_pp_convert(tdm_drm_pp_buffer *buffer, tdm_info_pp *info) +{ + tbm_surface_info_s src_info, dst_info; + pixman_format_code_t src_format, dst_format; + int sbw, dbw; + int rotate = 0, hflip = 0; + tbm_bo bo = NULL; + int bo_cnt = 0; + int bo_size = 0; + + RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(buffer->src != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(buffer->dst != NULL, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER); + + bo_cnt = tbm_surface_internal_get_num_bos(buffer->src); + RETURN_VAL_IF_FAIL(bo_cnt == 1, TDM_ERROR_INVALID_PARAMETER); + + bo_cnt = tbm_surface_internal_get_num_bos(buffer->dst); + RETURN_VAL_IF_FAIL(bo_cnt == 1, TDM_ERROR_INVALID_PARAMETER); + + bo = tbm_surface_internal_get_bo(buffer->src, 0); + RETURN_VAL_IF_FAIL(bo != NULL, TDM_ERROR_INVALID_PARAMETER); + + bo_size = tbm_bo_size(bo); + + /* not handle buffers which have 2 more gem handles */ + + memset(&src_info, 0, sizeof(tbm_surface_info_s)); + tbm_surface_map(buffer->src, TBM_OPTION_READ, &src_info); + GOTO_IF_FAIL(src_info.planes[0].ptr != NULL, fail_convert); + + memset(&dst_info, 0, sizeof(tbm_surface_info_s)); + tbm_surface_map(buffer->dst, TBM_OPTION_WRITE, &dst_info); + GOTO_IF_FAIL(dst_info.planes[0].ptr != NULL, fail_convert); + + src_format = _tdm_drm_pp_pixman_get_format(src_info.format); + GOTO_IF_FAIL(src_format > 0, fail_convert); + dst_format = _tdm_drm_pp_pixman_get_format(dst_info.format); + GOTO_IF_FAIL(dst_format > 0, fail_convert); + + if (src_info.format == TBM_FORMAT_YUV420) { + if (dst_info.format == TBM_FORMAT_XRGB8888) + dst_format = PIXMAN_x8b8g8r8; + else if (dst_info.format == TBM_FORMAT_ARGB8888) + dst_format = PIXMAN_a8b8g8r8; + else if (dst_info.format == TBM_FORMAT_YVU420) { + TDM_ERR("can't convert %c%c%c%c to %c%c%c%c", + FOURCC_STR(src_info.format), FOURCC_STR(dst_info.format)); + goto fail_convert; + } + } + /* need checking for other formats also? */ + + if (IS_RGB(src_info.format)) + sbw = src_info.planes[0].stride >> 2; + else + sbw = src_info.planes[0].stride; + + if (IS_RGB(dst_info.format)) + dbw = dst_info.planes[0].stride >> 2; + else + dbw = dst_info.planes[0].stride; + + rotate = (info->transform % 4) * 90; + if (info->transform >= TDM_TRANSFORM_FLIPPED) + hflip = 1; + + if (bo_size < src_info.planes[0].stride * src_info.height) { + TDM_WRN("bo size(%d) is smaller than the expected size(%d)", + bo_size, src_info.planes[0].stride * src_info.height); + goto fail_convert; + } + + _tdm_drm_pp_pixman_convert(PIXMAN_OP_SRC, + src_info.planes[0].ptr, dst_info.planes[0].ptr, + src_format, dst_format, + sbw, src_info.height, + info->src_config.pos.x, info->src_config.pos.y, + info->src_config.pos.w, info->src_config.pos.h, + dbw, dst_info.height, + info->dst_config.pos.x, info->dst_config.pos.y, + info->dst_config.pos.w, info->dst_config.pos.h, + rotate, hflip, 0); + tbm_surface_unmap(buffer->src); + tbm_surface_unmap(buffer->dst); + + return TDM_ERROR_NONE; +fail_convert: + tbm_surface_unmap(buffer->src); + tbm_surface_unmap(buffer->dst); + return TDM_ERROR_OPERATION_FAILED; +} + +tdm_error +tdm_drm_pp_get_capability(tdm_drm_data *drm_data, tdm_caps_pp *caps) +{ + int i; + + if (!caps) { + TDM_ERR("invalid params"); + return TDM_ERROR_INVALID_PARAMETER; + } + + caps->capabilities = TDM_PP_CAPABILITY_SYNC; + + caps->format_count = NUM_PP_FORMAT; + + /* will be freed in frontend */ + caps->formats = calloc(1, sizeof pp_formats); + if (!caps->formats) { + TDM_ERR("alloc failed"); + return TDM_ERROR_OUT_OF_MEMORY; + } + for (i = 0; i < caps->format_count; i++) + caps->formats[i] = pp_formats[i]; + + caps->min_w = 16; + caps->min_h = 8; + caps->max_w = -1; /* not defined */ + caps->max_h = -1; + caps->preferred_align = 16; + + return TDM_ERROR_NONE; +} + +tdm_pp * +tdm_drm_pp_create(tdm_drm_data *drm_data, tdm_error *error) +{ + tdm_drm_pp_data *pp_data = calloc(1, sizeof(tdm_drm_pp_data)); + if (!pp_data) { + TDM_ERR("alloc failed"); + if (error) + *error = TDM_ERROR_OUT_OF_MEMORY; + return NULL; + } + + pp_data->drm_data = drm_data; + + LIST_INITHEAD(&pp_data->pending_buffer_list); + + if (!pp_list_init) { + pp_list_init = 1; + LIST_INITHEAD(&pp_list); + } + LIST_ADDTAIL(&pp_data->link, &pp_list); + + return pp_data; +} + +void +drm_pp_destroy(tdm_pp *pp) +{ + tdm_drm_pp_data *pp_data = pp; + tdm_drm_pp_buffer *b = NULL, *bb = NULL; + + if (!pp_data) + return; + + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->pending_buffer_list, link) { + LIST_DEL(&b->link); + free(b); + } + + LIST_DEL(&pp_data->link); + + free(pp_data); +} + +tdm_error +drm_pp_set_info(tdm_pp *pp, tdm_info_pp *info) +{ + tdm_drm_pp_data *pp_data = pp; + + RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER); + + pp_data->info = *info; + + return TDM_ERROR_NONE; +} + +tdm_error +drm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst) +{ + tdm_drm_pp_data *pp_data = pp; + tdm_drm_pp_buffer *buffer; + + RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(src, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(dst, TDM_ERROR_INVALID_PARAMETER); + + if (tbm_surface_internal_get_num_bos(src) > 1 || + tbm_surface_internal_get_num_bos(dst) > 1) { + TDM_ERR("can't handle multiple tbm bos"); + return TDM_ERROR_OPERATION_FAILED; + } + + buffer = calloc(1, sizeof(tdm_drm_pp_buffer)); + if (!buffer) { + TDM_ERR("alloc failed"); + return TDM_ERROR_NONE; + } + + LIST_ADDTAIL(&buffer->link, &pp_data->pending_buffer_list); + + buffer->src = src; + buffer->dst = dst; + + return TDM_ERROR_NONE; +} + +tdm_error +drm_pp_commit(tdm_pp *pp) +{ + tdm_drm_pp_data *pp_data = pp; + tdm_drm_pp_buffer *b = NULL, *bb = NULL; + + RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER); + + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->pending_buffer_list, link) { + LIST_DEL(&b->link); + + _tdm_drm_pp_convert(b, &pp_data->info); + + if (pp_data->done_func) + pp_data->done_func(pp_data, + b->src, + b->dst, + pp_data->done_user_data); + free(b); + } + + return TDM_ERROR_NONE; +} + +tdm_error +drm_pp_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func, void *user_data) +{ + tdm_drm_pp_data *pp_data = pp; + + RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER); + + pp_data->done_func = func; + pp_data->done_user_data = user_data; + + return TDM_ERROR_NONE; +} diff --git a/src/tdm_drm_pp.h b/src/tdm_drm_pp.h new file mode 100644 index 0000000..acbb425 --- /dev/null +++ b/src/tdm_drm_pp.h @@ -0,0 +1,13 @@ +#ifndef _TDM_DRM_PP_H_ +#define _TDM_DRM_PP_H_ + +#include "tdm_drm.h" + +tdm_error tdm_drm_pp_get_capability(tdm_drm_data *drm_data, tdm_caps_pp *caps); +tdm_pp* tdm_drm_pp_create(tdm_drm_data *drm_data, tdm_error *error); +void tdm_drm_pp_handler(unsigned int prop_id, unsigned int *buf_idx, + unsigned int tv_sec, unsigned int tv_usec, void *data); +void tdm_drm_pp_cb(int fd, unsigned int prop_id, unsigned int *buf_idx, + unsigned int tv_sec, unsigned int tv_usec, + void *user_data); +#endif /* _TDM_DRM_PP_H_ */ -- 2.7.4 From 9e79fbd799f4be4e62b05de5adb2404df99feadc Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Tue, 14 Mar 2017 17:11:03 +0900 Subject: [PATCH 3/4] rename file names, package name and the prefix of the symbols change drm to vc4.. Change-Id: I43fa091be38f75a75e77fedd6e46b0079c115f4c Signed-off-by: SooChan Lim --- COPYING | 2 +- configure.ac | 22 +- .../{libtdm-drm.manifest => libtdm-vc4.manifest} | 0 packaging/{libtdm-drm.spec => libtdm-vc4.spec} | 12 +- src/Makefile.am | 20 +- src/tdm_drm_pp.h | 13 - src/{tdm_drm.c => tdm_vc4.c} | 190 +++---- src/{tdm_drm.h => tdm_vc4.h} | 84 ++-- src/{tdm_drm_display.c => tdm_vc4_display.c} | 544 ++++++++++----------- src/{tdm_drm_format.c => tdm_vc4_format.c} | 10 +- src/{tdm_drm_pp.c => tdm_vc4_pp.c} | 62 +-- src/tdm_vc4_pp.h | 13 + 12 files changed, 486 insertions(+), 486 deletions(-) rename packaging/{libtdm-drm.manifest => libtdm-vc4.manifest} (100%) rename packaging/{libtdm-drm.spec => libtdm-vc4.spec} (80%) delete mode 100644 src/tdm_drm_pp.h rename src/{tdm_drm.c => tdm_vc4.c} (57%) rename src/{tdm_drm.h => tdm_vc4.h} (54%) rename src/{tdm_drm_display.c => tdm_vc4_display.c} (70%) rename src/{tdm_drm_format.c => tdm_vc4_format.c} (94%) rename src/{tdm_drm_pp.c => tdm_vc4_pp.c} (87%) create mode 100644 src/tdm_vc4_pp.h diff --git a/COPYING b/COPYING index 817cb95..1bb9610 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright 2013 Samsung Electronics co., Ltd. All Rights Reserved. +Copyright 2017 Samsung Electronics co., Ltd. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/configure.ac b/configure.ac index 3acfee2..4017c5a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ AC_PREREQ([2.60]) -AC_INIT([libtdm-drm], - [1.0.0], +AC_INIT([libtdm-vc4], + [0.5.0], [https://www.tizen.org], - [libtdm-drm]) + [libtdm-vc4]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([Makefile.am]) @@ -23,16 +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 pixman-1) +PKG_CHECK_MODULES(TDM_VC4, libtdm libtbm libdrm pixman-1) 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" + TDM_VC4_CFLAGS="$TDM_VC4_CFLAGS $UDEV_CFLAGS" + TDM_VC4_LIBS="$TDM_VC4_LIBS $UDEV_LIBS" fi -AC_SUBST(TDM_DRM_CFLAGS) -AC_SUBST(TDM_DRM_LIBS) +AC_SUBST(TDM_VC4_CFLAGS) +AC_SUBST(TDM_VC4_LIBS) AC_DEFINE_UNQUOTED(LIBDRM_MAJOR_VERSION, [`pkg-config --modversion libdrm | cut -d '.' -f 1`], dnl [libdrm major version]) @@ -56,7 +56,7 @@ AC_OUTPUT([ 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 "TDM_VC4_CFLAGS : $TDM_VC4_CFLAGS" +echo "TDM_VC4_LIBS : $TDM_VC4_LIBS" +echo "TDM_MODULE_DIR : $TDM_MODULE_PATH" echo "" diff --git a/packaging/libtdm-drm.manifest b/packaging/libtdm-vc4.manifest similarity index 100% rename from packaging/libtdm-drm.manifest rename to packaging/libtdm-vc4.manifest diff --git a/packaging/libtdm-drm.spec b/packaging/libtdm-vc4.spec similarity index 80% rename from packaging/libtdm-drm.spec rename to packaging/libtdm-vc4.spec index 3bf892b..9b751de 100644 --- a/packaging/libtdm-drm.spec +++ b/packaging/libtdm-vc4.spec @@ -1,7 +1,7 @@ -Name: libtdm-drm -Version: 1.0.5 +Name: libtdm-vc4 +Version: 0.5.0 Release: 0 -Summary: Tizen Display Manager DRM Back-End Library +Summary: Tizen Display Manager VC4 Back-End Library Group: Development/Libraries License: MIT Source0: %{name}-%{version}.tar.gz @@ -12,7 +12,7 @@ BuildRequires: pkgconfig(libtdm) BuildRequires: pkgconfig(pixman-1) %description -Back-End library of Tizen Display Manager DRM : libtdm-mgr DRM library +Back-End library of Tizen Display Manager VC4 : libtdm-mgr VC4 library %global TZ_SYS_RO_SHARE %{?TZ_SYS_RO_SHARE:%TZ_SYS_RO_SHARE}%{!?TZ_SYS_RO_SHARE:/usr/share} @@ -36,7 +36,7 @@ cp -af COPYING %{buildroot}/%{TZ_SYS_RO_SHARE}/license/%{name} if [ -f %{_libdir}/tdm/libtdm-default.so ]; then rm -rf %{_libdir}/tdm/libtdm-default.so fi -ln -s libtdm-drm.so %{_libdir}/tdm/libtdm-default.so +ln -s libtdm-vc4.so %{_libdir}/tdm/libtdm-default.so %postun -p /sbin/ldconfig @@ -44,4 +44,4 @@ ln -s libtdm-drm.so %{_libdir}/tdm/libtdm-default.so %defattr(-,root,root,-) %manifest %{name}.manifest %{TZ_SYS_RO_SHARE}/license/%{name} -%{_libdir}/tdm/libtdm-drm.so +%{_libdir}/tdm/libtdm-vc4.so diff --git a/src/Makefile.am b/src/Makefile.am index 09338b8..01f7669 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,14 +1,14 @@ AM_CFLAGS = \ - $(TDM_DRM_CFLAGS) \ + $(TDM_VC4_CFLAGS) \ -I$(top_srcdir)/src -libtdm_drm_la_LTLIBRARIES = libtdm-drm.la -libtdm_drm_ladir = $(TDM_MODULE_PATH) -libtdm_drm_la_LDFLAGS = -module -avoid-version -libtdm_drm_la_LIBADD = $(TDM_DRM_LIBS) -ldl +libtdm_vc4_la_LTLIBRARIES = libtdm-vc4.la +libtdm_vc4_ladir = $(TDM_MODULE_PATH) +libtdm_vc4_la_LDFLAGS = -module -avoid-version +libtdm_vc4_la_LIBADD = $(TDM_VC4_LIBS) -ldl -libtdm_drm_la_SOURCES = \ - tdm_drm_format.c \ - tdm_drm_pp.c \ - tdm_drm_display.c \ - tdm_drm.c +libtdm_vc4_la_SOURCES = \ + tdm_vc4_format.c \ + tdm_vc4_pp.c \ + tdm_vc4_display.c \ + tdm_vc4.c diff --git a/src/tdm_drm_pp.h b/src/tdm_drm_pp.h deleted file mode 100644 index acbb425..0000000 --- a/src/tdm_drm_pp.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _TDM_DRM_PP_H_ -#define _TDM_DRM_PP_H_ - -#include "tdm_drm.h" - -tdm_error tdm_drm_pp_get_capability(tdm_drm_data *drm_data, tdm_caps_pp *caps); -tdm_pp* tdm_drm_pp_create(tdm_drm_data *drm_data, tdm_error *error); -void tdm_drm_pp_handler(unsigned int prop_id, unsigned int *buf_idx, - unsigned int tv_sec, unsigned int tv_usec, void *data); -void tdm_drm_pp_cb(int fd, unsigned int prop_id, unsigned int *buf_idx, - unsigned int tv_sec, unsigned int tv_usec, - void *user_data); -#endif /* _TDM_DRM_PP_H_ */ diff --git a/src/tdm_drm.c b/src/tdm_vc4.c similarity index 57% rename from src/tdm_drm.c rename to src/tdm_vc4.c index 1817c6e..e97b89b 100644 --- a/src/tdm_drm.c +++ b/src/tdm_vc4.c @@ -6,14 +6,14 @@ #include #endif -#include "tdm_drm.h" +#include "tdm_vc4.h" #include #define ENABLE_PP -#define TDM_DRM_NAME "vigs" +#define TDM_DRM_NAME "vc4-drm" -static tdm_drm_data *drm_data; +static tdm_vc4_data *vc4_data; #ifdef HAVE_UDEV static struct udev_device * @@ -66,9 +66,9 @@ _tdm_find_primary_gpu(void) } static tdm_error -_tdm_drm_udev_fd_handler(int fd, tdm_event_loop_mask mask, void *user_data) +_tdm_vc4_udev_fd_handler(int fd, tdm_event_loop_mask mask, void *user_data) { - tdm_drm_data *edata = (tdm_drm_data*)user_data; + tdm_vc4_data *edata = (tdm_vc4_data*)user_data; struct udev_device *dev; const char *hotplug; struct stat s; @@ -95,7 +95,7 @@ _tdm_drm_udev_fd_handler(int fd, tdm_event_loop_mask mask, void *user_data) hotplug && atoi(hotplug) == 1) { TDM_INFO("HotPlug"); - tdm_drm_display_update_output_status(edata); + tdm_vc4_display_update_output_status(edata); } udev_device_unref(dev); @@ -104,7 +104,7 @@ _tdm_drm_udev_fd_handler(int fd, tdm_event_loop_mask mask, void *user_data) } static void -_tdm_drm_udev_init(tdm_drm_data *edata) +_tdm_vc4_udev_init(tdm_vc4_data *edata) { struct udev *u = NULL; struct udev_monitor *mon = NULL; @@ -130,7 +130,7 @@ _tdm_drm_udev_init(tdm_drm_data *edata) edata->uevent_source = tdm_event_loop_add_fd_handler(edata->dpy, udev_monitor_get_fd(mon), TDM_EVENT_LOOP_READABLE, - _tdm_drm_udev_fd_handler, + _tdm_vc4_udev_fd_handler, edata, NULL); if (!edata->uevent_source) { TDM_ERR("couldn't create udev event source"); @@ -150,7 +150,7 @@ failed: } static void -_tdm_drm_udev_deinit(tdm_drm_data *edata) +_tdm_vc4_udev_deinit(tdm_vc4_data *edata) { if (edata->uevent_source) { tdm_event_loop_source_remove(edata->uevent_source); @@ -168,7 +168,7 @@ _tdm_drm_udev_deinit(tdm_drm_data *edata) #endif static int -_tdm_drm_open_drm(void) +_tdm_vc4_open_drm(void) { int fd = -1; @@ -205,38 +205,38 @@ close_l: } void -tdm_drm_deinit(tdm_backend_data *bdata) +tdm_vc4_deinit(tdm_backend_data *bdata) { - if (drm_data != bdata) + if (vc4_data != bdata) return; TDM_INFO("deinit"); #ifdef HAVE_UDEV - _tdm_drm_udev_deinit(drm_data); + _tdm_vc4_udev_deinit(vc4_data); #endif - tdm_drm_display_destroy_output_list(drm_data); + tdm_vc4_display_destroy_output_list(vc4_data); - if (drm_data->plane_res) - drmModeFreePlaneResources(drm_data->plane_res); - if (drm_data->mode_res) - drmModeFreeResources(drm_data->mode_res); - if (drm_data->drm_fd >= 0) - close(drm_data->drm_fd); + if (vc4_data->plane_res) + drmModeFreePlaneResources(vc4_data->plane_res); + if (vc4_data->mode_res) + drmModeFreeResources(vc4_data->mode_res); + if (vc4_data->drm_fd >= 0) + close(vc4_data->drm_fd); - free(drm_data); - drm_data = NULL; + free(vc4_data); + vc4_data = NULL; } tdm_backend_data * -tdm_drm_init(tdm_display *dpy, tdm_error *error) +tdm_vc4_init(tdm_display *dpy, tdm_error *error) { - tdm_func_display drm_func_display; - tdm_func_output drm_func_output; - tdm_func_layer drm_func_layer; + tdm_func_display vc4_func_display; + tdm_func_output vc4_func_output; + tdm_func_layer vc4_func_layer; #ifdef ENABLE_PP - tdm_func_pp drm_func_pp; + tdm_func_pp vc4_func_pp; #endif tdm_error ret; @@ -247,142 +247,142 @@ tdm_drm_init(tdm_display *dpy, tdm_error *error) return NULL; } - if (drm_data) { + if (vc4_data) { TDM_ERR("failed: init twice"); if (error) *error = TDM_ERROR_BAD_REQUEST; return NULL; } - drm_data = calloc(1, sizeof(tdm_drm_data)); - if (!drm_data) { + vc4_data = calloc(1, sizeof(tdm_vc4_data)); + if (!vc4_data) { TDM_ERR("alloc failed"); if (error) *error = TDM_ERROR_OUT_OF_MEMORY; return NULL; } - LIST_INITHEAD(&drm_data->output_list); - LIST_INITHEAD(&drm_data->buffer_list); - - memset(&drm_func_display, 0, sizeof(drm_func_display)); - drm_func_display.display_get_capability = drm_display_get_capability; - drm_func_display.display_get_pp_capability = drm_display_get_pp_capability; - drm_func_display.display_get_outputs = drm_display_get_outputs; - drm_func_display.display_get_fd = drm_display_get_fd; - drm_func_display.display_handle_events = drm_display_handle_events; - drm_func_display.display_create_pp = drm_display_create_pp; - - memset(&drm_func_output, 0, sizeof(drm_func_output)); - drm_func_output.output_get_capability = drm_output_get_capability; - drm_func_output.output_get_layers = drm_output_get_layers; - drm_func_output.output_set_property = drm_output_set_property; - drm_func_output.output_get_property = drm_output_get_property; - drm_func_output.output_wait_vblank = drm_output_wait_vblank; - drm_func_output.output_set_vblank_handler = drm_output_set_vblank_handler; - drm_func_output.output_commit = drm_output_commit; - drm_func_output.output_set_commit_handler = drm_output_set_commit_handler; - drm_func_output.output_set_dpms = drm_output_set_dpms; - drm_func_output.output_get_dpms = drm_output_get_dpms; - drm_func_output.output_set_mode = drm_output_set_mode; - drm_func_output.output_get_mode = drm_output_get_mode; + LIST_INITHEAD(&vc4_data->output_list); + LIST_INITHEAD(&vc4_data->buffer_list); + + memset(&vc4_func_display, 0, sizeof(vc4_func_display)); + vc4_func_display.display_get_capability = vc4_display_get_capability; + vc4_func_display.display_get_pp_capability = vc4_display_get_pp_capability; + vc4_func_display.display_get_outputs = vc4_display_get_outputs; + vc4_func_display.display_get_fd = vc4_display_get_fd; + vc4_func_display.display_handle_events = vc4_display_handle_events; + vc4_func_display.display_create_pp = vc4_display_create_pp; + + memset(&vc4_func_output, 0, sizeof(vc4_func_output)); + vc4_func_output.output_get_capability = vc4_output_get_capability; + vc4_func_output.output_get_layers = vc4_output_get_layers; + vc4_func_output.output_set_property = vc4_output_set_property; + vc4_func_output.output_get_property = vc4_output_get_property; + vc4_func_output.output_wait_vblank = vc4_output_wait_vblank; + vc4_func_output.output_set_vblank_handler = vc4_output_set_vblank_handler; + vc4_func_output.output_commit = vc4_output_commit; + vc4_func_output.output_set_commit_handler = vc4_output_set_commit_handler; + vc4_func_output.output_set_dpms = vc4_output_set_dpms; + vc4_func_output.output_get_dpms = vc4_output_get_dpms; + vc4_func_output.output_set_mode = vc4_output_set_mode; + vc4_func_output.output_get_mode = vc4_output_get_mode; #ifdef HAVE_UDEV - drm_func_output.output_set_status_handler = drm_output_set_status_handler; + vc4_func_output.output_set_status_handler = vc4_output_set_status_handler; #endif - memset(&drm_func_layer, 0, sizeof(drm_func_layer)); - drm_func_layer.layer_get_capability = drm_layer_get_capability; - drm_func_layer.layer_set_property = drm_layer_set_property; - drm_func_layer.layer_get_property = drm_layer_get_property; - drm_func_layer.layer_set_info = drm_layer_set_info; - drm_func_layer.layer_get_info = drm_layer_get_info; - drm_func_layer.layer_set_buffer = drm_layer_set_buffer; - drm_func_layer.layer_unset_buffer = drm_layer_unset_buffer; + memset(&vc4_func_layer, 0, sizeof(vc4_func_layer)); + vc4_func_layer.layer_get_capability = vc4_layer_get_capability; + vc4_func_layer.layer_set_property = vc4_layer_set_property; + vc4_func_layer.layer_get_property = vc4_layer_get_property; + vc4_func_layer.layer_set_info = vc4_layer_set_info; + vc4_func_layer.layer_get_info = vc4_layer_get_info; + vc4_func_layer.layer_set_buffer = vc4_layer_set_buffer; + vc4_func_layer.layer_unset_buffer = vc4_layer_unset_buffer; #ifdef ENABLE_PP - memset(&drm_func_pp, 0, sizeof(drm_func_pp)); - drm_func_pp.pp_destroy = drm_pp_destroy; - drm_func_pp.pp_set_info = drm_pp_set_info; - drm_func_pp.pp_attach = drm_pp_attach; - drm_func_pp.pp_commit = drm_pp_commit; - drm_func_pp.pp_set_done_handler = drm_pp_set_done_handler; + memset(&vc4_func_pp, 0, sizeof(vc4_func_pp)); + vc4_func_pp.pp_destroy = vc4_pp_destroy; + vc4_func_pp.pp_set_info = vc4_pp_set_info; + vc4_func_pp.pp_attach = vc4_pp_attach; + vc4_func_pp.pp_commit = vc4_pp_commit; + vc4_func_pp.pp_set_done_handler = vc4_pp_set_done_handler; #endif - ret = tdm_backend_register_func_display(dpy, &drm_func_display); + ret = tdm_backend_register_func_display(dpy, &vc4_func_display); if (ret != TDM_ERROR_NONE) goto failed; - ret = tdm_backend_register_func_output(dpy, &drm_func_output); + ret = tdm_backend_register_func_output(dpy, &vc4_func_output); if (ret != TDM_ERROR_NONE) goto failed; - ret = tdm_backend_register_func_layer(dpy, &drm_func_layer); + ret = tdm_backend_register_func_layer(dpy, &vc4_func_layer); if (ret != TDM_ERROR_NONE) goto failed; #ifdef ENABLE_PP - ret = tdm_backend_register_func_pp(dpy, &drm_func_pp); + ret = tdm_backend_register_func_pp(dpy, &vc4_func_pp); if (ret != TDM_ERROR_NONE) goto failed; #endif - drm_data->dpy = dpy; + vc4_data->dpy = dpy; - /* The drm master fd can be opened by a tbm backend module in + /* The vc4 master fd can be opened by a tbm backend module in * tbm_bufmgr_init() time. In this case, we just get it from - * TBM_DRM_MASTER_FD enviroment. + * TBM_vc4_MASTER_FD enviroment. * */ - drm_data->drm_fd = tdm_helper_get_fd("TBM_DRM_MASTER_FD"); - if (drm_data->drm_fd < 0) - drm_data->drm_fd = _tdm_drm_open_drm(); + vc4_data->drm_fd = tdm_helper_get_fd("TBM_DRM_MASTER_FD"); + if (vc4_data->drm_fd < 0) + vc4_data->drm_fd = _tdm_vc4_open_drm(); - if (drm_data->drm_fd < 0) { + if (vc4_data->drm_fd < 0) { ret = TDM_ERROR_OPERATION_FAILED; goto failed; } /* To share the drm master fd with other modules in display server side. */ - tdm_helper_set_fd("TDM_DRM_MASTER_FD", drm_data->drm_fd); + tdm_helper_set_fd("TDM_DRM_MASTER_FD", vc4_data->drm_fd); #ifdef HAVE_UDEV - _tdm_drm_udev_init(drm_data); + _tdm_vc4_udev_init(vc4_data); #endif #if LIBDRM_MAJOR_VERSION >= 2 && LIBDRM_MINOR_VERSION >= 4 && LIBDRM_MICRO_VERSION >= 47 - if (drmSetClientCap(drm_data->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) < 0) { + if (drmSetClientCap(vc4_data->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) < 0) { TDM_WRN("Set DRM_CLIENT_CAP_UNIVERSAL_PLANES failed"); } else { TDM_INFO("has universal planes"); - drm_data->has_universal_plane = 1; + vc4_data->has_universal_plane = 1; } #endif - drm_data->mode_res = drmModeGetResources(drm_data->drm_fd); - if (!drm_data->mode_res) { + vc4_data->mode_res = drmModeGetResources(vc4_data->drm_fd); + if (!vc4_data->mode_res) { TDM_ERR("no drm resource: %m"); ret = TDM_ERROR_OPERATION_FAILED; goto failed; } - drm_data->plane_res = drmModeGetPlaneResources(drm_data->drm_fd); - if (!drm_data->plane_res) { + vc4_data->plane_res = drmModeGetPlaneResources(vc4_data->drm_fd); + if (!vc4_data->plane_res) { TDM_ERR("no drm plane resource: %m"); ret = TDM_ERROR_OPERATION_FAILED; goto failed; } - if (drm_data->plane_res->count_planes <= 0) { + if (vc4_data->plane_res->count_planes <= 0) { TDM_ERR("no drm plane resource"); ret = TDM_ERROR_OPERATION_FAILED; goto failed; } - ret = tdm_drm_display_create_output_list(drm_data); + ret = tdm_vc4_display_create_output_list(vc4_data); if (ret != TDM_ERROR_NONE) goto failed; - ret = tdm_drm_display_create_layer_list(drm_data); + ret = tdm_vc4_display_create_layer_list(vc4_data); if (ret != TDM_ERROR_NONE) goto failed; @@ -391,12 +391,12 @@ tdm_drm_init(tdm_display *dpy, tdm_error *error) TDM_INFO("init success!"); - return (tdm_backend_data *)drm_data; + return (tdm_backend_data *)vc4_data; failed: if (error) *error = ret; - tdm_drm_deinit(drm_data); + tdm_vc4_deinit(vc4_data); TDM_ERR("init failed!"); return NULL; @@ -406,6 +406,6 @@ tdm_backend_module tdm_backend_module_data = { "drm", "Samsung", TDM_BACKEND_SET_ABI_VERSION(1, 1), - tdm_drm_init, - tdm_drm_deinit + tdm_vc4_init, + tdm_vc4_deinit }; diff --git a/src/tdm_drm.h b/src/tdm_vc4.h similarity index 54% rename from src/tdm_drm.h rename to src/tdm_vc4.h index 99d6a36..8de6c1f 100644 --- a/src/tdm_drm.h +++ b/src/tdm_vc4.h @@ -1,5 +1,5 @@ -#ifndef _TDM_DRM_H_ -#define _TDM_DRM_H_ +#ifndef _TDM_VC4_H_ +#define _TDM_VC4_H_ #ifdef HAVE_CONFIG_H #include "config.h" @@ -30,37 +30,37 @@ #endif /* drm backend functions (display) */ -tdm_error drm_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps); -tdm_error drm_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps); -tdm_output** drm_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error); -tdm_error drm_display_get_fd(tdm_backend_data *bdata, int *fd); -tdm_error drm_display_handle_events(tdm_backend_data *bdata); -tdm_pp* drm_display_create_pp(tdm_backend_data *bdata, tdm_error *error); -tdm_error drm_output_get_capability(tdm_output *output, tdm_caps_output *caps); -tdm_layer** drm_output_get_layers(tdm_output *output, int *count, tdm_error *error); -tdm_error drm_output_set_property(tdm_output *output, unsigned int id, tdm_value value); -tdm_error drm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value); -tdm_error drm_output_wait_vblank(tdm_output *output, int interval, int sync, void *user_data); -tdm_error drm_output_set_vblank_handler(tdm_output *output, tdm_output_vblank_handler func); -tdm_error drm_output_commit(tdm_output *output, int sync, void *user_data); -tdm_error drm_output_set_commit_handler(tdm_output *output, tdm_output_commit_handler func); -tdm_error drm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value); -tdm_error drm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value); -tdm_error drm_output_set_mode(tdm_output *output, const tdm_output_mode *mode); -tdm_error drm_output_get_mode(tdm_output *output, const tdm_output_mode **mode); -tdm_error drm_output_set_status_handler(tdm_output *output, tdm_output_status_handler func, void *user_data); -tdm_error drm_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps); -tdm_error drm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value); -tdm_error drm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value); -tdm_error drm_layer_set_info(tdm_layer *layer, tdm_info_layer *info); -tdm_error drm_layer_get_info(tdm_layer *layer, tdm_info_layer *info); -tdm_error drm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer); -tdm_error drm_layer_unset_buffer(tdm_layer *layer); -void drm_pp_destroy(tdm_pp *pp); -tdm_error drm_pp_set_info(tdm_pp *pp, tdm_info_pp *info); -tdm_error drm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst); -tdm_error drm_pp_commit(tdm_pp *pp); -tdm_error drm_pp_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func, void *user_data); +tdm_error vc4_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps); +tdm_error vc4_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps); +tdm_output** vc4_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error); +tdm_error vc4_display_get_fd(tdm_backend_data *bdata, int *fd); +tdm_error vc4_display_handle_events(tdm_backend_data *bdata); +tdm_pp* vc4_display_create_pp(tdm_backend_data *bdata, tdm_error *error); +tdm_error vc4_output_get_capability(tdm_output *output, tdm_caps_output *caps); +tdm_layer** vc4_output_get_layers(tdm_output *output, int *count, tdm_error *error); +tdm_error vc4_output_set_property(tdm_output *output, unsigned int id, tdm_value value); +tdm_error vc4_output_get_property(tdm_output *output, unsigned int id, tdm_value *value); +tdm_error vc4_output_wait_vblank(tdm_output *output, int interval, int sync, void *user_data); +tdm_error vc4_output_set_vblank_handler(tdm_output *output, tdm_output_vblank_handler func); +tdm_error vc4_output_commit(tdm_output *output, int sync, void *user_data); +tdm_error vc4_output_set_commit_handler(tdm_output *output, tdm_output_commit_handler func); +tdm_error vc4_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value); +tdm_error vc4_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value); +tdm_error vc4_output_set_mode(tdm_output *output, const tdm_output_mode *mode); +tdm_error vc4_output_get_mode(tdm_output *output, const tdm_output_mode **mode); +tdm_error vc4_output_set_status_handler(tdm_output *output, tdm_output_status_handler func, void *user_data); +tdm_error vc4_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps); +tdm_error vc4_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value); +tdm_error vc4_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value); +tdm_error vc4_layer_set_info(tdm_layer *layer, tdm_info_layer *info); +tdm_error vc4_layer_get_info(tdm_layer *layer, tdm_info_layer *info); +tdm_error vc4_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer); +tdm_error vc4_layer_unset_buffer(tdm_layer *layer); +void vc4_pp_destroy(tdm_pp *pp); +tdm_error vc4_pp_set_info(tdm_pp *pp, tdm_info_pp *info); +tdm_error vc4_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst); +tdm_error vc4_pp_commit(tdm_pp *pp); +tdm_error vc4_pp_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func, void *user_data); /* drm module internal macros, structures, functions */ #define NEVER_GET_HERE() TDM_ERR("** NEVER GET HERE **") @@ -100,7 +100,7 @@ tdm_error drm_pp_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func, void }\ } -typedef struct _tdm_drm_data +typedef struct _tdm_vc4_data { tdm_display *dpy; @@ -120,14 +120,14 @@ typedef struct _tdm_drm_data struct list_head output_list; struct list_head buffer_list; -} tdm_drm_data; +} tdm_vc4_data; -uint32_t tdm_drm_format_to_drm_format(tbm_format format); -tbm_format tdm_drm_format_to_tbm_format(uint32_t format); +uint32_t tdm_vc4_format_to_drm_format(tbm_format format); +tbm_format tdm_vc4_format_to_tbm_format(uint32_t format); -void tdm_drm_display_update_output_status(tdm_drm_data *drm_data); -tdm_error tdm_drm_display_create_output_list(tdm_drm_data *drm_data); -void tdm_drm_display_destroy_output_list(tdm_drm_data *drm_data); -tdm_error tdm_drm_display_create_layer_list(tdm_drm_data *drm_data); +void tdm_vc4_display_update_output_status(tdm_vc4_data *vc4_data); +tdm_error tdm_vc4_display_create_output_list(tdm_vc4_data *vc4_data); +void tdm_vc4_display_destroy_output_list(tdm_vc4_data *vc4_data); +tdm_error tdm_vc4_display_create_layer_list(tdm_vc4_data *vc4_data); -#endif /* _TDM_DRM_H_ */ +#endif /* _TDM_VC4_H_ */ diff --git a/src/tdm_drm_display.c b/src/tdm_vc4_display.c similarity index 70% rename from src/tdm_drm_display.c rename to src/tdm_vc4_display.c index 312de60..348089f 100644 --- a/src/tdm_drm_display.c +++ b/src/tdm_vc4_display.c @@ -5,52 +5,52 @@ #include #include -#include "tdm_drm.h" -#include "tdm_drm_pp.h" +#include "tdm_vc4.h" +#include "tdm_vc4_pp.h" #define MIN_WIDTH 32 -typedef struct _tdm_drm_output_data tdm_drm_output_data; -typedef struct _tdm_drm_layer_data tdm_drm_layer_data; -typedef struct _tdm_drm_event_data tdm_drm_event_data; +typedef struct _tdm_vc4_output_data tdm_vc4_output_data; +typedef struct _tdm_vc4_layer_data tdm_vc4_layer_data; +typedef struct _tdm_vc4_event_data tdm_vc4_event_data; typedef enum { TDM_DRM_EVENT_TYPE_WAIT, TDM_DRM_EVENT_TYPE_COMMIT, TDM_DRM_EVENT_TYPE_PAGEFLIP, -} tdm_drm_event_type; +} tdm_vc4_event_type; -typedef struct _tdm_drm_display_buffer { +typedef struct _tdm_vc4_display_buffer { struct list_head link; unsigned int fb_id; tbm_surface_h buffer; int width; -} tdm_drm_display_buffer; +} tdm_vc4_display_buffer; -struct _tdm_drm_event_data { - tdm_drm_event_type type; - tdm_drm_output_data *output_data; +struct _tdm_vc4_event_data { + tdm_vc4_event_type type; + tdm_vc4_output_data *output_data; void *user_data; }; -struct _tdm_drm_output_data { +struct _tdm_vc4_output_data { struct list_head link; /* data which are fixed at initializing */ - tdm_drm_data *drm_data; + tdm_vc4_data *vc4_data; uint32_t connector_id; uint32_t encoder_id; uint32_t crtc_id; uint32_t pipe; uint32_t dpms_prop_id; int count_modes; - drmModeModeInfoPtr drm_modes; + drmModeModeInfoPtr vc4_modes; tdm_output_mode *output_modes; tdm_output_type connector_type; unsigned int connector_type_id; struct list_head layer_list; - tdm_drm_layer_data *primary_layer; + tdm_vc4_layer_data *primary_layer; /* not fixed data below */ tdm_output_vblank_handler vblank_func; @@ -64,12 +64,12 @@ struct _tdm_drm_output_data { const tdm_output_mode *current_mode; }; -struct _tdm_drm_layer_data { +struct _tdm_vc4_layer_data { struct list_head link; /* data which are fixed at initializing */ - tdm_drm_data *drm_data; - tdm_drm_output_data *output_data; + tdm_vc4_data *vc4_data; + tdm_vc4_output_data *output_data; uint32_t plane_id; tdm_layer_capability capabilities; int zpos; @@ -78,12 +78,12 @@ struct _tdm_drm_layer_data { tdm_info_layer info; int info_changed; - tdm_drm_display_buffer *display_buffer; + tdm_vc4_display_buffer *display_buffer; int display_buffer_changed; }; static drmModeModeInfoPtr -_tdm_drm_display_get_mode(tdm_drm_output_data *output_data) +_tdm_vc4_display_get_mode(tdm_vc4_output_data *output_data) { int i; @@ -93,25 +93,25 @@ _tdm_drm_display_get_mode(tdm_drm_output_data *output_data) } for (i = 0; i < output_data->count_modes; i++) { - drmModeModeInfoPtr drm_mode = &output_data->drm_modes[i]; - if ((drm_mode->hdisplay == output_data->current_mode->hdisplay) && - (drm_mode->vdisplay == output_data->current_mode->vdisplay) && - (drm_mode->vrefresh == output_data->current_mode->vrefresh) && - (drm_mode->flags == output_data->current_mode->flags) && - (drm_mode->type == output_data->current_mode->type) && - !(strncmp(drm_mode->name, output_data->current_mode->name, TDM_NAME_LEN))) - return drm_mode; + drmModeModeInfoPtr vc4_mode = &output_data->vc4_modes[i]; + if ((vc4_mode->hdisplay == output_data->current_mode->hdisplay) && + (vc4_mode->vdisplay == output_data->current_mode->vdisplay) && + (vc4_mode->vrefresh == output_data->current_mode->vrefresh) && + (vc4_mode->flags == output_data->current_mode->flags) && + (vc4_mode->type == output_data->current_mode->type) && + !(strncmp(vc4_mode->name, output_data->current_mode->name, TDM_NAME_LEN))) + return vc4_mode; } return NULL; } -static tdm_drm_display_buffer * -_tdm_drm_display_find_buffer(tdm_drm_data *drm_data, tbm_surface_h buffer) +static tdm_vc4_display_buffer * +_tdm_vc4_display_find_buffer(tdm_vc4_data *vc4_data, tbm_surface_h buffer) { - tdm_drm_display_buffer *display_buffer = NULL; + tdm_vc4_display_buffer *display_buffer = NULL; - LIST_FOR_EACH_ENTRY(display_buffer, &drm_data->buffer_list, link) { + LIST_FOR_EACH_ENTRY(display_buffer, &vc4_data->buffer_list, link) { if (display_buffer->buffer == buffer) return display_buffer; } @@ -120,28 +120,28 @@ _tdm_drm_display_find_buffer(tdm_drm_data *drm_data, tbm_surface_h buffer) } static void -_tdm_drm_display_to_tdm_mode(drmModeModeInfoPtr drm_mode, +_tdm_vc4_display_to_tdm_mode(drmModeModeInfoPtr vc4_mode, tdm_output_mode *tdm_mode) { - tdm_mode->clock = drm_mode->clock; - tdm_mode->hdisplay = drm_mode->hdisplay; - tdm_mode->hsync_start = drm_mode->hsync_start; - tdm_mode->hsync_end = drm_mode->hsync_end; - tdm_mode->htotal = drm_mode->htotal; - tdm_mode->hskew = drm_mode->hskew; - tdm_mode->vdisplay = drm_mode->vdisplay; - tdm_mode->vsync_start = drm_mode->vsync_start; - tdm_mode->vsync_end = drm_mode->vsync_end; - tdm_mode->vtotal = drm_mode->vtotal; - tdm_mode->vscan = drm_mode->vscan; - tdm_mode->vrefresh = drm_mode->vrefresh; - tdm_mode->flags = drm_mode->flags; - tdm_mode->type = drm_mode->type; - snprintf(tdm_mode->name, TDM_NAME_LEN, "%s", drm_mode->name); + tdm_mode->clock = vc4_mode->clock; + tdm_mode->hdisplay = vc4_mode->hdisplay; + tdm_mode->hsync_start = vc4_mode->hsync_start; + tdm_mode->hsync_end = vc4_mode->hsync_end; + tdm_mode->htotal = vc4_mode->htotal; + tdm_mode->hskew = vc4_mode->hskew; + tdm_mode->vdisplay = vc4_mode->vdisplay; + tdm_mode->vsync_start = vc4_mode->vsync_start; + tdm_mode->vsync_end = vc4_mode->vsync_end; + tdm_mode->vtotal = vc4_mode->vtotal; + tdm_mode->vscan = vc4_mode->vscan; + tdm_mode->vrefresh = vc4_mode->vrefresh; + tdm_mode->flags = vc4_mode->flags; + tdm_mode->type = vc4_mode->type; + snprintf(tdm_mode->name, TDM_NAME_LEN, "%s", vc4_mode->name); } static tdm_error -_tdm_drm_display_get_cur_msc (int fd, int pipe, uint *msc) +_tdm_vc4_display_get_cur_msc (int fd, int pipe, uint *msc) { drmVBlank vbl; @@ -162,7 +162,7 @@ _tdm_drm_display_get_cur_msc (int fd, int pipe, uint *msc) } static tdm_error -_tdm_drm_display_wait_vblank(int fd, int pipe, uint *target_msc, void *data) +_tdm_vc4_display_wait_vblank(int fd, int pipe, uint *target_msc, void *data) { drmVBlank vbl; @@ -185,7 +185,7 @@ _tdm_drm_display_wait_vblank(int fd, int pipe, uint *target_msc, void *data) } static tdm_error -_tdm_drm_output_update_status(tdm_drm_output_data *output_data, +_tdm_vc4_output_update_status(tdm_vc4_output_data *output_data, tdm_output_conn_status status) { RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); @@ -203,11 +203,11 @@ _tdm_drm_output_update_status(tdm_drm_output_data *output_data, } static tdm_error -_tdm_drm_display_commit_primary_layer(tdm_drm_layer_data *layer_data, +_tdm_vc4_display_commit_primary_layer(tdm_vc4_layer_data *layer_data, void *user_data, int *do_waitvblank) { - tdm_drm_data *drm_data = layer_data->drm_data; - tdm_drm_output_data *output_data = layer_data->output_data; + tdm_vc4_data *vc4_data = layer_data->vc4_data; + tdm_vc4_output_data *output_data = layer_data->output_data; if (output_data->mode_changed && layer_data->display_buffer_changed) { drmModeModeInfoPtr mode; @@ -221,20 +221,20 @@ _tdm_drm_display_commit_primary_layer(tdm_drm_layer_data *layer_data, layer_data->display_buffer_changed = 0; layer_data->info_changed = 0; - mode = _tdm_drm_display_get_mode(output_data); + mode = _tdm_vc4_display_get_mode(output_data); if (!mode) { TDM_ERR("couldn't find proper mode"); return TDM_ERROR_BAD_REQUEST; } - if (drmModeSetCrtc(drm_data->drm_fd, output_data->crtc_id, + if (drmModeSetCrtc(vc4_data->drm_fd, output_data->crtc_id, layer_data->display_buffer->fb_id, 0, 0, &output_data->connector_id, 1, mode)) { TDM_ERR("set crtc failed: %m"); return TDM_ERROR_OPERATION_FAILED; } - _tdm_drm_output_update_status(output_data, TDM_OUTPUT_CONN_STATUS_MODE_SETTED); + _tdm_vc4_output_update_status(output_data, TDM_OUTPUT_CONN_STATUS_MODE_SETTED); *do_waitvblank = 1; return TDM_ERROR_NONE; @@ -242,18 +242,18 @@ _tdm_drm_display_commit_primary_layer(tdm_drm_layer_data *layer_data, layer_data->display_buffer_changed = 0; if (!layer_data->display_buffer) { - if (drmModeSetCrtc(drm_data->drm_fd, output_data->crtc_id, + if (drmModeSetCrtc(vc4_data->drm_fd, output_data->crtc_id, 0, 0, 0, NULL, 0, NULL)) { TDM_ERR("unset crtc failed: %m"); return TDM_ERROR_OPERATION_FAILED; } if (output_data->status == TDM_OUTPUT_CONN_STATUS_MODE_SETTED) - _tdm_drm_output_update_status(output_data, TDM_OUTPUT_CONN_STATUS_CONNECTED); + _tdm_vc4_output_update_status(output_data, TDM_OUTPUT_CONN_STATUS_CONNECTED); *do_waitvblank = 1; } else { - tdm_drm_event_data *event_data = calloc(1, sizeof(tdm_drm_event_data)); + tdm_vc4_event_data *event_data = calloc(1, sizeof(tdm_vc4_event_data)); if (!event_data) { TDM_ERR("alloc failed"); @@ -263,7 +263,7 @@ _tdm_drm_display_commit_primary_layer(tdm_drm_layer_data *layer_data, event_data->type = TDM_DRM_EVENT_TYPE_PAGEFLIP; event_data->output_data = output_data; event_data->user_data = user_data; - if (drmModePageFlip(drm_data->drm_fd, output_data->crtc_id, + if (drmModePageFlip(vc4_data->drm_fd, output_data->crtc_id, layer_data->display_buffer->fb_id, DRM_MODE_PAGE_FLIP_EVENT, event_data)) { TDM_ERR("pageflip failed: %m"); return TDM_ERROR_OPERATION_FAILED; @@ -276,10 +276,10 @@ _tdm_drm_display_commit_primary_layer(tdm_drm_layer_data *layer_data, } static tdm_error -_tdm_drm_display_commit_layer(tdm_drm_layer_data *layer_data) +_tdm_vc4_display_commit_layer(tdm_vc4_layer_data *layer_data) { - tdm_drm_data *drm_data = layer_data->drm_data; - tdm_drm_output_data *output_data = layer_data->output_data; + tdm_vc4_data *vc4_data = layer_data->vc4_data; + tdm_vc4_output_data *output_data = layer_data->output_data; uint32_t fx, fy, fw, fh; int crtc_w; @@ -289,7 +289,7 @@ _tdm_drm_display_commit_layer(tdm_drm_layer_data *layer_data) if (output_data->current_mode) crtc_w = output_data->current_mode->hdisplay; else { - drmModeCrtcPtr crtc = drmModeGetCrtc(drm_data->drm_fd, output_data->crtc_id); + drmModeCrtcPtr crtc = drmModeGetCrtc(vc4_data->drm_fd, output_data->crtc_id); if (!crtc) { TDM_ERR("getting crtc failed"); return TDM_ERROR_OPERATION_FAILED; @@ -307,7 +307,7 @@ _tdm_drm_display_commit_layer(tdm_drm_layer_data *layer_data) layer_data->info_changed = 0; if (!layer_data->display_buffer) { - if (drmModeSetPlane(drm_data->drm_fd, layer_data->plane_id, + if (drmModeSetPlane(vc4_data->drm_fd, layer_data->plane_id, output_data->crtc_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) TDM_ERR("unset plane(%d) filed: %m", layer_data->plane_id); @@ -320,7 +320,7 @@ _tdm_drm_display_commit_layer(tdm_drm_layer_data *layer_data) fw = ((unsigned int)layer_data->info.src_config.pos.w) << 16; fh = ((unsigned int)layer_data->info.src_config.pos.h) << 16; - if (drmModeSetPlane(drm_data->drm_fd, layer_data->plane_id, + if (drmModeSetPlane(vc4_data->drm_fd, layer_data->plane_id, output_data->crtc_id, layer_data->display_buffer->fb_id, 0, layer_data->info.dst_pos.x, layer_data->info.dst_pos.y, layer_data->info.dst_pos.w, layer_data->info.dst_pos.h, @@ -341,12 +341,12 @@ _tdm_drm_display_commit_layer(tdm_drm_layer_data *layer_data) } static void -_tdm_drm_display_cb_event(int fd, unsigned int sequence, +_tdm_vc4_display_cb_event(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) { - tdm_drm_event_data *event_data = user_data; - tdm_drm_output_data *output_data; + tdm_vc4_event_data *event_data = user_data; + tdm_vc4_output_data *output_data; if (!event_data) { TDM_ERR("no event data"); @@ -379,31 +379,31 @@ _tdm_drm_display_cb_event(int fd, unsigned int sequence, } static tdm_error -_tdm_drm_display_create_layer_list(tdm_drm_data *drm_data) +_tdm_vc4_display_create_layer_list(tdm_vc4_data *vc4_data) { - tdm_drm_output_data *output_data = NULL; + tdm_vc4_output_data *output_data = NULL; int i; - if (LIST_IS_EMPTY(&drm_data->output_list)) { + if (LIST_IS_EMPTY(&vc4_data->output_list)) { TDM_ERR("no output"); return TDM_ERROR_OPERATION_FAILED; } /* The TDM drm backend only support one output. */ - LIST_FOR_EACH_ENTRY(output_data, &drm_data->output_list, link) { + LIST_FOR_EACH_ENTRY(output_data, &vc4_data->output_list, link) { break; } - if (drm_data->plane_res->count_planes == 0) { + if (vc4_data->plane_res->count_planes == 0) { TDM_ERR("no layer error"); return TDM_ERROR_OPERATION_FAILED; } - for (i = 0; i < drm_data->plane_res->count_planes; i++) { - tdm_drm_layer_data *layer_data; + for (i = 0; i < vc4_data->plane_res->count_planes; i++) { + tdm_vc4_layer_data *layer_data; drmModePlanePtr plane; - plane = drmModeGetPlane(drm_data->drm_fd, drm_data->plane_res->planes[i]); + plane = drmModeGetPlane(vc4_data->drm_fd, vc4_data->plane_res->planes[i]); if (!plane) { TDM_ERR("no plane"); continue; @@ -414,16 +414,16 @@ _tdm_drm_display_create_layer_list(tdm_drm_data *drm_data) continue; } - layer_data = calloc(1, sizeof(tdm_drm_layer_data)); + layer_data = calloc(1, sizeof(tdm_vc4_layer_data)); if (!layer_data) { TDM_ERR("alloc failed"); drmModeFreePlane(plane); continue; } - layer_data->drm_data = drm_data; + layer_data->vc4_data = vc4_data; layer_data->output_data = output_data; - layer_data->plane_id = drm_data->plane_res->planes[i]; + layer_data->plane_id = vc4_data->plane_res->planes[i]; layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY | TDM_LAYER_CAPABILITY_GRAPHIC; @@ -447,7 +447,7 @@ _tdm_drm_display_create_layer_list(tdm_drm_data *drm_data) #if LIBDRM_MAJOR_VERSION >= 2 && LIBDRM_MINOR_VERSION >= 4 && LIBDRM_MICRO_VERSION >= 47 static tdm_error -_tdm_drm_display_get_property(tdm_drm_data *drm_data, +_tdm_vc4_display_get_property(tdm_vc4_data *vc4_data, unsigned int obj_id, unsigned int obj_type, const char *name, unsigned int *value, int *is_immutable) @@ -455,12 +455,12 @@ _tdm_drm_display_get_property(tdm_drm_data *drm_data, drmModeObjectPropertiesPtr props = NULL; int i; - props = drmModeObjectGetProperties(drm_data->drm_fd, obj_id, obj_type); + props = drmModeObjectGetProperties(vc4_data->drm_fd, obj_id, obj_type); if (!props) return TDM_ERROR_OPERATION_FAILED; for (i = 0; i < props->count_props; i++) { - drmModePropertyPtr prop = drmModeGetProperty(drm_data->drm_fd, + drmModePropertyPtr prop = drmModeGetProperty(vc4_data->drm_fd, props->props[i]); if (!prop) @@ -484,9 +484,9 @@ _tdm_drm_display_get_property(tdm_drm_data *drm_data, } static tdm_error -_tdm_drm_display_create_layer_list_type(tdm_drm_data *drm_data) +_tdm_vc4_display_create_layer_list_type(tdm_vc4_data *vc4_data) { - tdm_drm_output_data *output_data = NULL; + tdm_vc4_output_data *output_data = NULL; drmModePlanePtr *planes = NULL; unsigned int *types = NULL; unsigned int type = 0; @@ -495,18 +495,18 @@ _tdm_drm_display_create_layer_list_type(tdm_drm_data *drm_data) tdm_error ret; int i; - if (LIST_IS_EMPTY(&drm_data->output_list)) { + if (LIST_IS_EMPTY(&vc4_data->output_list)) { TDM_ERR("no output"); return TDM_ERROR_OPERATION_FAILED; } /* The TDM drm backend only support one output. */ - LIST_FOR_EACH_ENTRY(output_data, &drm_data->output_list, link) { + LIST_FOR_EACH_ENTRY(output_data, &vc4_data->output_list, link) { break; } - ret = _tdm_drm_display_get_property(drm_data, - drm_data->plane_res->planes[0], + ret = _tdm_vc4_display_get_property(vc4_data, + vc4_data->plane_res->planes[0], DRM_MODE_OBJECT_PLANE, "type", &type, NULL); if (ret != TDM_ERROR_NONE) { @@ -515,28 +515,28 @@ _tdm_drm_display_create_layer_list_type(tdm_drm_data *drm_data) /* if a plane doesn't have "type" property, we call a fallback function * as default */ - return _tdm_drm_display_create_layer_list(drm_data); + return _tdm_vc4_display_create_layer_list(vc4_data); } - planes = calloc(drm_data->plane_res->count_planes, sizeof(drmModePlanePtr)); + planes = calloc(vc4_data->plane_res->count_planes, sizeof(drmModePlanePtr)); if (!planes) { TDM_ERR("alloc failed"); goto failed; } - types = calloc(drm_data->plane_res->count_planes, sizeof(unsigned int)); + types = calloc(vc4_data->plane_res->count_planes, sizeof(unsigned int)); if (!types) { TDM_ERR("alloc failed"); goto failed; } plane_cnt = 0; - for (i = 0; i < drm_data->plane_res->count_planes; i++) { + for (i = 0; i < vc4_data->plane_res->count_planes; i++) { drmModePlanePtr plane; - plane = drmModeGetPlane(drm_data->drm_fd, drm_data->plane_res->planes[i]); + plane = drmModeGetPlane(vc4_data->drm_fd, vc4_data->plane_res->planes[i]); if (!plane) { - TDM_ERR("no plane(%d)", drm_data->plane_res->planes[i]); + TDM_ERR("no plane(%d)", vc4_data->plane_res->planes[i]); goto failed; } @@ -545,14 +545,14 @@ _tdm_drm_display_create_layer_list_type(tdm_drm_data *drm_data) continue; } - ret = _tdm_drm_display_get_property(drm_data, - drm_data->plane_res->planes[i], + ret = _tdm_vc4_display_get_property(vc4_data, + vc4_data->plane_res->planes[i], DRM_MODE_OBJECT_PLANE, "type", &type, NULL); if (ret != TDM_ERROR_NONE) { drmModeFreePlane(plane); TDM_ERR("plane(%d) doesn't have 'type' info", - drm_data->plane_res->planes[i]); + vc4_data->plane_res->planes[i]); goto failed; } @@ -581,15 +581,15 @@ _tdm_drm_display_create_layer_list_type(tdm_drm_data *drm_data) opos_next = 1; cpos_next = ovl_cnt; for (i = 0; i < plane_cnt; i++) { - tdm_drm_layer_data *layer_data; + tdm_vc4_layer_data *layer_data; - layer_data = calloc(1, sizeof(tdm_drm_layer_data)); + layer_data = calloc(1, sizeof(tdm_vc4_layer_data)); if (!layer_data) { TDM_ERR("alloc failed"); goto failed; } - layer_data->drm_data = drm_data; + layer_data->vc4_data = vc4_data; layer_data->output_data = output_data; layer_data->plane_id = planes[i]->plane_id; @@ -629,7 +629,7 @@ _tdm_drm_display_create_layer_list_type(tdm_drm_data *drm_data) failed: if (planes) { - for (i = 0; i < drm_data->plane_res->count_planes; i++) + for (i = 0; i < vc4_data->plane_res->count_planes; i++) if (planes[i]) drmModeFreePlane(planes[i]); free(planes); @@ -642,10 +642,10 @@ failed: #endif static void -_tdm_drm_display_cb_destroy_buffer(tbm_surface_h buffer, void *user_data) +_tdm_vc4_display_cb_destroy_buffer(tbm_surface_h buffer, void *user_data) { - tdm_drm_data *drm_data; - tdm_drm_display_buffer *display_buffer; + tdm_vc4_data *vc4_data; + tdm_vc4_display_buffer *display_buffer; int ret; if (!user_data) { @@ -657,9 +657,9 @@ _tdm_drm_display_cb_destroy_buffer(tbm_surface_h buffer, void *user_data) return; } - drm_data = (tdm_drm_data *)user_data; + vc4_data = (tdm_vc4_data *)user_data; - display_buffer = _tdm_drm_display_find_buffer(drm_data, buffer); + display_buffer = _tdm_vc4_display_find_buffer(vc4_data, buffer); if (!display_buffer) { TDM_ERR("no display_buffer"); return; @@ -667,7 +667,7 @@ _tdm_drm_display_cb_destroy_buffer(tbm_surface_h buffer, void *user_data) LIST_DEL(&display_buffer->link); if (display_buffer->fb_id > 0) { - ret = drmModeRmFB(drm_data->drm_fd, display_buffer->fb_id); + ret = drmModeRmFB(vc4_data->drm_fd, display_buffer->fb_id); if (ret < 0) { TDM_ERR("rm fb failed"); return; @@ -680,22 +680,22 @@ _tdm_drm_display_cb_destroy_buffer(tbm_surface_h buffer, void *user_data) } tdm_error -tdm_drm_display_create_layer_list(tdm_drm_data *drm_data) +tdm_vc4_display_create_layer_list(tdm_vc4_data *vc4_data) { - tdm_drm_output_data *output_data = NULL; + tdm_vc4_output_data *output_data = NULL; tdm_error ret; #if LIBDRM_MAJOR_VERSION >= 2 && LIBDRM_MINOR_VERSION >= 4 && LIBDRM_MICRO_VERSION >= 47 - if (drm_data->has_universal_plane) - ret = _tdm_drm_display_create_layer_list_type(drm_data); + if (vc4_data->has_universal_plane) + ret = _tdm_vc4_display_create_layer_list_type(vc4_data); else #endif - ret = _tdm_drm_display_create_layer_list(drm_data); + ret = _tdm_vc4_display_create_layer_list(vc4_data); if (ret != TDM_ERROR_NONE) return ret; - LIST_FOR_EACH_ENTRY(output_data, &drm_data->output_list, link) { + LIST_FOR_EACH_ENTRY(output_data, &vc4_data->output_list, link) { if (!output_data->primary_layer) { TDM_ERR("output(%d) no primary layer", output_data->pipe); return TDM_ERROR_OPERATION_FAILED; @@ -706,41 +706,41 @@ tdm_drm_display_create_layer_list(tdm_drm_data *drm_data) } void -tdm_drm_display_destroy_output_list(tdm_drm_data *drm_data) +tdm_vc4_display_destroy_output_list(tdm_vc4_data *vc4_data) { - tdm_drm_output_data *o = NULL, *oo = NULL; + tdm_vc4_output_data *o = NULL, *oo = NULL; - if (LIST_IS_EMPTY(&drm_data->output_list)) + if (LIST_IS_EMPTY(&vc4_data->output_list)) return; - LIST_FOR_EACH_ENTRY_SAFE(o, oo, &drm_data->output_list, link) { + LIST_FOR_EACH_ENTRY_SAFE(o, oo, &vc4_data->output_list, link) { LIST_DEL(&o->link); if (!LIST_IS_EMPTY(&o->layer_list)) { - tdm_drm_layer_data *l = NULL, *ll = NULL; + tdm_vc4_layer_data *l = NULL, *ll = NULL; LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link) { LIST_DEL(&l->link); free(l); } } - free(o->drm_modes); + free(o->vc4_modes); free(o->output_modes); free(o); } } void -tdm_drm_display_update_output_status(tdm_drm_data *drm_data) +tdm_vc4_display_update_output_status(tdm_vc4_data *vc4_data) { - tdm_drm_output_data *output_data = NULL; + tdm_vc4_output_data *output_data = NULL; - if (LIST_IS_EMPTY(&drm_data->output_list)) + if (LIST_IS_EMPTY(&vc4_data->output_list)) return; - LIST_FOR_EACH_ENTRY(output_data, &drm_data->output_list, link) { + LIST_FOR_EACH_ENTRY(output_data, &vc4_data->output_list, link) { drmModeConnectorPtr connector; tdm_output_conn_status new_status; - connector = drmModeGetConnector(drm_data->drm_fd, + connector = drmModeGetConnector(vc4_data->drm_fd, output_data->connector_id); if (!connector) { TDM_ERR("no connector: %d", output_data->connector_id); @@ -752,30 +752,30 @@ tdm_drm_display_update_output_status(tdm_drm_data *drm_data) else new_status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED; - _tdm_drm_output_update_status(output_data, new_status); + _tdm_vc4_output_update_status(output_data, new_status); drmModeFreeConnector(connector); } } tdm_error -tdm_drm_display_create_output_list(tdm_drm_data *drm_data) +tdm_vc4_display_create_output_list(tdm_vc4_data *vc4_data) { - tdm_drm_output_data *output_data; + tdm_vc4_output_data *output_data; int i; tdm_error ret; int allocated = 0; - RETURN_VAL_IF_FAIL(LIST_IS_EMPTY(&drm_data->output_list), + RETURN_VAL_IF_FAIL(LIST_IS_EMPTY(&vc4_data->output_list), TDM_ERROR_OPERATION_FAILED); - for (i = 0; i < drm_data->mode_res->count_connectors; i++) { + for (i = 0; i < vc4_data->mode_res->count_connectors; i++) { drmModeConnectorPtr connector; drmModeEncoderPtr encoder; int crtc_id = 0, c, j; - connector = drmModeGetConnector(drm_data->drm_fd, - drm_data->mode_res->connectors[i]); + connector = drmModeGetConnector(vc4_data->drm_fd, + vc4_data->mode_res->connectors[i]); if (!connector) { TDM_ERR("no connector"); ret = TDM_ERROR_OPERATION_FAILED; @@ -800,7 +800,7 @@ tdm_drm_display_create_output_list(tdm_drm_data *drm_data) goto failed_create; } - encoder = drmModeGetEncoder(drm_data->drm_fd, connector->encoders[0]); + encoder = drmModeGetEncoder(vc4_data->drm_fd, connector->encoders[0]); if (!encoder) { TDM_ERR("no encoder"); drmModeFreeConnector(connector); @@ -808,14 +808,14 @@ tdm_drm_display_create_output_list(tdm_drm_data *drm_data) goto failed_create; } - for (c = 0; c < drm_data->mode_res->count_crtcs; c++) { + for (c = 0; c < vc4_data->mode_res->count_crtcs; c++) { if (allocated & (1 << c)) continue; if ((encoder->possible_crtcs & (1 << c)) == 0) continue; - crtc_id = drm_data->mode_res->crtcs[c]; + crtc_id = vc4_data->mode_res->crtcs[c]; allocated |= (1 << c); break; } @@ -827,7 +827,7 @@ tdm_drm_display_create_output_list(tdm_drm_data *drm_data) goto failed_create; } - output_data = calloc(1, sizeof(tdm_drm_output_data)); + output_data = calloc(1, sizeof(tdm_vc4_output_data)); if (!output_data) { TDM_ERR("alloc failed"); drmModeFreeConnector(connector); @@ -838,8 +838,8 @@ tdm_drm_display_create_output_list(tdm_drm_data *drm_data) LIST_INITHEAD(&output_data->layer_list); - output_data->drm_data = drm_data; - output_data->connector_id = drm_data->mode_res->connectors[i]; + output_data->vc4_data = vc4_data; + output_data->connector_id = vc4_data->mode_res->connectors[i]; output_data->encoder_id = encoder->encoder_id; output_data->crtc_id = crtc_id; output_data->pipe = c; @@ -852,7 +852,7 @@ tdm_drm_display_create_output_list(tdm_drm_data *drm_data) output_data->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED; for (j = 0; j < connector->count_props; j++) { - drmModePropertyPtr prop = drmModeGetProperty(drm_data->drm_fd, + drmModePropertyPtr prop = drmModeGetProperty(vc4_data->drm_fd, connector->props[j]); if (!prop) continue; @@ -868,9 +868,9 @@ tdm_drm_display_create_output_list(tdm_drm_data *drm_data) TDM_WRN("not support DPMS"); output_data->count_modes = connector->count_modes; - output_data->drm_modes = calloc(connector->count_modes, + output_data->vc4_modes = calloc(connector->count_modes, sizeof(drmModeModeInfo)); - if (!output_data->drm_modes) { + if (!output_data->vc4_modes) { TDM_ERR("alloc failed"); free(output_data); drmModeFreeConnector(connector); @@ -882,7 +882,7 @@ tdm_drm_display_create_output_list(tdm_drm_data *drm_data) sizeof(tdm_output_mode)); if (!output_data->output_modes) { TDM_ERR("alloc failed"); - free(output_data->drm_modes); + free(output_data->vc4_modes); free(output_data); drmModeFreeConnector(connector); drmModeFreeEncoder(encoder); @@ -890,12 +890,12 @@ tdm_drm_display_create_output_list(tdm_drm_data *drm_data) goto failed_create; } for (j = 0; j < connector->count_modes; j++) { - output_data->drm_modes[j] = connector->modes[j]; - _tdm_drm_display_to_tdm_mode(&output_data->drm_modes[j], + output_data->vc4_modes[j] = connector->modes[j]; + _tdm_vc4_display_to_tdm_mode(&output_data->vc4_modes[j], &output_data->output_modes[j]); } - LIST_ADDTAIL(&output_data->link, &drm_data->output_list); + LIST_ADDTAIL(&output_data->link, &vc4_data->output_list); TDM_DBG("output_data(%p) connector_id(%d:%d:%d-%d) encoder_id(%d) crtc_id(%d) pipe(%d) dpms_id(%d)", output_data, output_data->connector_id, output_data->status, @@ -915,16 +915,16 @@ tdm_drm_display_create_output_list(tdm_drm_data *drm_data) break; } - TDM_DBG("output count: %d", drm_data->mode_res->count_connectors); + TDM_DBG("output count: %d", vc4_data->mode_res->count_connectors); return TDM_ERROR_NONE; failed_create: - tdm_drm_display_destroy_output_list(drm_data); + tdm_vc4_display_destroy_output_list(vc4_data); return ret; } tdm_error -drm_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps) +vc4_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps) { RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER); @@ -934,25 +934,25 @@ drm_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps) } tdm_error -drm_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps) +vc4_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps) { - return tdm_drm_pp_get_capability(bdata, caps); + return tdm_vc4_pp_get_capability(bdata, caps); } tdm_output ** -drm_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error) +vc4_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error) { - tdm_drm_data *drm_data = bdata; - tdm_drm_output_data *output_data = NULL; + tdm_vc4_data *vc4_data = bdata; + tdm_vc4_output_data *output_data = NULL; tdm_output **outputs; tdm_error ret; int i; - RETURN_VAL_IF_FAIL(drm_data, NULL); + RETURN_VAL_IF_FAIL(vc4_data, NULL); RETURN_VAL_IF_FAIL(count, NULL); *count = 0; - LIST_FOR_EACH_ENTRY(output_data, &drm_data->output_list, link) + LIST_FOR_EACH_ENTRY(output_data, &vc4_data->output_list, link) (*count)++; if (*count == 0) { @@ -961,7 +961,7 @@ drm_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error) } /* will be freed in frontend */ - outputs = calloc(*count, sizeof(tdm_drm_output_data *)); + outputs = calloc(*count, sizeof(tdm_vc4_output_data *)); if (!outputs) { TDM_ERR("failed: alloc memory"); *count = 0; @@ -970,7 +970,7 @@ drm_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error) } i = 0; - LIST_FOR_EACH_ENTRY(output_data, &drm_data->output_list, link) + LIST_FOR_EACH_ENTRY(output_data, &vc4_data->output_list, link) outputs[i++] = output_data; if (error) @@ -984,52 +984,52 @@ failed_get: } tdm_error -drm_display_get_fd(tdm_backend_data *bdata, int *fd) +vc4_display_get_fd(tdm_backend_data *bdata, int *fd) { - tdm_drm_data *drm_data = bdata; + tdm_vc4_data *vc4_data = bdata; - RETURN_VAL_IF_FAIL(drm_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(vc4_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(fd, TDM_ERROR_INVALID_PARAMETER); - *fd = drm_data->drm_fd; + *fd = vc4_data->drm_fd; return TDM_ERROR_NONE; } tdm_error -drm_display_handle_events(tdm_backend_data *bdata) +vc4_display_handle_events(tdm_backend_data *bdata) { - tdm_drm_data *drm_data = bdata; + tdm_vc4_data *vc4_data = bdata; drmEventContext ctx; - RETURN_VAL_IF_FAIL(drm_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(vc4_data, TDM_ERROR_INVALID_PARAMETER); memset(&ctx, 0, sizeof(drmEventContext)); ctx.version = DRM_EVENT_CONTEXT_VERSION; - ctx.page_flip_handler = _tdm_drm_display_cb_event; - ctx.vblank_handler = _tdm_drm_display_cb_event; + ctx.page_flip_handler = _tdm_vc4_display_cb_event; + ctx.vblank_handler = _tdm_vc4_display_cb_event; - drmHandleEvent(drm_data->drm_fd, &ctx); + drmHandleEvent(vc4_data->drm_fd, &ctx); return TDM_ERROR_NONE; } tdm_pp * -drm_display_create_pp(tdm_backend_data *bdata, tdm_error *error) +vc4_display_create_pp(tdm_backend_data *bdata, tdm_error *error) { - tdm_drm_data *drm_data = bdata; + tdm_vc4_data *vc4_data = bdata; - RETURN_VAL_IF_FAIL(drm_data, NULL); + RETURN_VAL_IF_FAIL(vc4_data, NULL); - return tdm_drm_pp_create(drm_data, error); + return tdm_vc4_pp_create(vc4_data, error); } tdm_error -drm_output_get_capability(tdm_output *output, tdm_caps_output *caps) +vc4_output_get_capability(tdm_output *output, tdm_caps_output *caps) { - tdm_drm_output_data *output_data = output; - tdm_drm_data *drm_data; + tdm_vc4_output_data *output_data = output; + tdm_vc4_data *vc4_data; drmModeConnectorPtr connector = NULL; drmModeCrtcPtr crtc = NULL; drmModeObjectPropertiesPtr props = NULL; @@ -1041,7 +1041,7 @@ drm_output_get_capability(tdm_output *output, tdm_caps_output *caps) memset(caps, 0, sizeof(tdm_caps_output)); - drm_data = output_data->drm_data; + vc4_data = output_data->vc4_data; snprintf(caps->maker, TDM_NAME_LEN, "unknown"); snprintf(caps->model, TDM_NAME_LEN, "unknown"); @@ -1051,7 +1051,7 @@ drm_output_get_capability(tdm_output *output, tdm_caps_output *caps) caps->type = output_data->connector_type; caps->type_id = output_data->connector_type_id; - connector = drmModeGetConnector(drm_data->drm_fd, output_data->connector_id); + connector = drmModeGetConnector(vc4_data->drm_fd, output_data->connector_id); RETURN_VAL_IF_FAIL(connector, TDM_ERROR_OPERATION_FAILED); caps->mode_count = connector->count_modes; @@ -1068,20 +1068,20 @@ drm_output_get_capability(tdm_output *output, tdm_caps_output *caps) caps->mmHeight = connector->mmHeight; caps->subpixel = connector->subpixel; - caps->min_w = drm_data->mode_res->min_width; - caps->min_h = drm_data->mode_res->min_height; - caps->max_w = drm_data->mode_res->max_width; - caps->max_h = drm_data->mode_res->max_height; + caps->min_w = vc4_data->mode_res->min_width; + caps->min_h = vc4_data->mode_res->min_height; + caps->max_w = vc4_data->mode_res->max_width; + caps->max_h = vc4_data->mode_res->max_height; caps->preferred_align = -1; - crtc = drmModeGetCrtc(drm_data->drm_fd, output_data->crtc_id); + crtc = drmModeGetCrtc(vc4_data->drm_fd, output_data->crtc_id); if (!crtc) { ret = TDM_ERROR_OPERATION_FAILED; TDM_ERR("get crtc failed: %m\n"); goto failed_get; } - props = drmModeObjectGetProperties(drm_data->drm_fd, output_data->crtc_id, + props = drmModeObjectGetProperties(vc4_data->drm_fd, output_data->crtc_id, DRM_MODE_OBJECT_CRTC); if (!props) { ret = TDM_ERROR_OPERATION_FAILED; @@ -1098,7 +1098,7 @@ drm_output_get_capability(tdm_output *output, tdm_caps_output *caps) } for (i = 0; i < caps->prop_count; i++) { - drmModePropertyPtr prop = drmModeGetProperty(drm_data->drm_fd, props->props[i]); + drmModePropertyPtr prop = drmModeGetProperty(vc4_data->drm_fd, props->props[i]); if (!prop) continue; snprintf(caps->props[i].name, TDM_NAME_LEN, "%s", prop->name); @@ -1122,10 +1122,10 @@ failed_get: } tdm_layer ** -drm_output_get_layers(tdm_output *output, int *count, tdm_error *error) +vc4_output_get_layers(tdm_output *output, int *count, tdm_error *error) { - tdm_drm_output_data *output_data = output; - tdm_drm_layer_data *layer_data = NULL; + tdm_vc4_output_data *output_data = output; + tdm_vc4_layer_data *layer_data = NULL; tdm_layer **layers; tdm_error ret; int i; @@ -1143,7 +1143,7 @@ drm_output_get_layers(tdm_output *output, int *count, tdm_error *error) } /* will be freed in frontend */ - layers = calloc(*count, sizeof(tdm_drm_layer_data *)); + layers = calloc(*count, sizeof(tdm_vc4_layer_data *)); if (!layers) { TDM_ERR("failed: alloc memory"); *count = 0; @@ -1166,17 +1166,17 @@ failed_get: } tdm_error -drm_output_set_property(tdm_output *output, unsigned int id, tdm_value value) +vc4_output_set_property(tdm_output *output, unsigned int id, tdm_value value) { - tdm_drm_output_data *output_data = output; - tdm_drm_data *drm_data; + tdm_vc4_output_data *output_data = output; + tdm_vc4_data *vc4_data; int ret; RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(output_data->crtc_id > 0, TDM_ERROR_INVALID_PARAMETER); - drm_data = output_data->drm_data; - ret = drmModeObjectSetProperty(drm_data->drm_fd, + vc4_data = output_data->vc4_data; + ret = drmModeObjectSetProperty(vc4_data->drm_fd, output_data->crtc_id, DRM_MODE_OBJECT_CRTC, id, value.u32); if (ret < 0) { @@ -1188,10 +1188,10 @@ drm_output_set_property(tdm_output *output, unsigned int id, tdm_value value) } tdm_error -drm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value) +vc4_output_get_property(tdm_output *output, unsigned int id, tdm_value *value) { - tdm_drm_output_data *output_data = output; - tdm_drm_data *drm_data; + tdm_vc4_output_data *output_data = output; + tdm_vc4_data *vc4_data; drmModeObjectPropertiesPtr props; int i; @@ -1199,8 +1199,8 @@ drm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value) RETURN_VAL_IF_FAIL(output_data->crtc_id > 0, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(value, TDM_ERROR_INVALID_PARAMETER); - drm_data = output_data->drm_data; - props = drmModeObjectGetProperties(drm_data->drm_fd, output_data->crtc_id, + vc4_data = output_data->vc4_data; + props = drmModeObjectGetProperties(vc4_data->drm_fd, output_data->crtc_id, DRM_MODE_OBJECT_CRTC); if (props == NULL) { TDM_ERR("get property failed: %m"); @@ -1219,26 +1219,26 @@ drm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value) } tdm_error -drm_output_wait_vblank(tdm_output *output, int interval, int sync, +vc4_output_wait_vblank(tdm_output *output, int interval, int sync, void *user_data) { - tdm_drm_output_data *output_data = output; - tdm_drm_data *drm_data; - tdm_drm_event_data *event_data; + tdm_vc4_output_data *output_data = output; + tdm_vc4_data *vc4_data; + tdm_vc4_event_data *event_data; uint target_msc; tdm_error ret; RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); - event_data = calloc(1, sizeof(tdm_drm_event_data)); + event_data = calloc(1, sizeof(tdm_vc4_event_data)); if (!event_data) { TDM_ERR("alloc failed"); return TDM_ERROR_OUT_OF_MEMORY; } - drm_data = output_data->drm_data; + vc4_data = output_data->vc4_data; - ret = _tdm_drm_display_get_cur_msc(drm_data->drm_fd, output_data->pipe, + ret = _tdm_vc4_display_get_cur_msc(vc4_data->drm_fd, output_data->pipe, &target_msc); if (ret != TDM_ERROR_NONE) goto failed_vblank; @@ -1249,7 +1249,7 @@ drm_output_wait_vblank(tdm_output *output, int interval, int sync, event_data->output_data = output_data; event_data->user_data = user_data; - ret = _tdm_drm_display_wait_vblank(drm_data->drm_fd, output_data->pipe, + ret = _tdm_vc4_display_wait_vblank(vc4_data->drm_fd, output_data->pipe, &target_msc, event_data); if (ret != TDM_ERROR_NONE) goto failed_vblank; @@ -1261,10 +1261,10 @@ failed_vblank: } tdm_error -drm_output_set_vblank_handler(tdm_output *output, +vc4_output_set_vblank_handler(tdm_output *output, tdm_output_vblank_handler func) { - tdm_drm_output_data *output_data = output; + tdm_vc4_output_data *output_data = output; RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER); @@ -1275,33 +1275,33 @@ drm_output_set_vblank_handler(tdm_output *output, } tdm_error -drm_output_commit(tdm_output *output, int sync, void *user_data) +vc4_output_commit(tdm_output *output, int sync, void *user_data) { - tdm_drm_output_data *output_data = output; - tdm_drm_data *drm_data; - tdm_drm_layer_data *layer_data = NULL; + tdm_vc4_output_data *output_data = output; + tdm_vc4_data *vc4_data; + tdm_vc4_layer_data *layer_data = NULL; tdm_error ret; int do_waitvblank = 1; RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); - drm_data = output_data->drm_data; + vc4_data = output_data->vc4_data; LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) { if (layer_data == output_data->primary_layer) { - ret = _tdm_drm_display_commit_primary_layer(layer_data, user_data, + ret = _tdm_vc4_display_commit_primary_layer(layer_data, user_data, &do_waitvblank); if (ret != TDM_ERROR_NONE) return ret; } else { - ret = _tdm_drm_display_commit_layer(layer_data); + ret = _tdm_vc4_display_commit_layer(layer_data); if (ret != TDM_ERROR_NONE) return ret; } } if (do_waitvblank == 1) { - tdm_drm_event_data *event_data = calloc(1, sizeof(tdm_drm_event_data)); + tdm_vc4_event_data *event_data = calloc(1, sizeof(tdm_vc4_event_data)); uint target_msc; if (!event_data) { @@ -1309,7 +1309,7 @@ drm_output_commit(tdm_output *output, int sync, void *user_data) return TDM_ERROR_OUT_OF_MEMORY; } - ret = _tdm_drm_display_get_cur_msc(drm_data->drm_fd, output_data->pipe, + ret = _tdm_vc4_display_get_cur_msc(vc4_data->drm_fd, output_data->pipe, &target_msc); if (ret != TDM_ERROR_NONE) { free(event_data); @@ -1322,7 +1322,7 @@ drm_output_commit(tdm_output *output, int sync, void *user_data) event_data->output_data = output_data; event_data->user_data = user_data; - ret = _tdm_drm_display_wait_vblank(drm_data->drm_fd, output_data->pipe, + ret = _tdm_vc4_display_wait_vblank(vc4_data->drm_fd, output_data->pipe, &target_msc, event_data); if (ret != TDM_ERROR_NONE) { free(event_data); @@ -1334,10 +1334,10 @@ drm_output_commit(tdm_output *output, int sync, void *user_data) } tdm_error -drm_output_set_commit_handler(tdm_output *output, +vc4_output_set_commit_handler(tdm_output *output, tdm_output_commit_handler func) { - tdm_drm_output_data *output_data = output; + tdm_vc4_output_data *output_data = output; RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER); @@ -1348,10 +1348,10 @@ drm_output_set_commit_handler(tdm_output *output, } tdm_error -drm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) +vc4_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) { - tdm_drm_output_data *output_data = output; - tdm_drm_data *drm_data; + tdm_vc4_output_data *output_data = output; + tdm_vc4_data *vc4_data; int ret; RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); @@ -1361,8 +1361,8 @@ drm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) return TDM_ERROR_OPERATION_FAILED; } - drm_data = output_data->drm_data; - ret = drmModeObjectSetProperty(drm_data->drm_fd, + vc4_data = output_data->vc4_data; + ret = drmModeObjectSetProperty(vc4_data->drm_fd, output_data->connector_id, DRM_MODE_OBJECT_CONNECTOR, output_data->dpms_prop_id, dpms_value); if (ret < 0) { @@ -1374,18 +1374,18 @@ drm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) } tdm_error -drm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value) +vc4_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value) { - tdm_drm_output_data *output_data = output; - tdm_drm_data *drm_data; + tdm_vc4_output_data *output_data = output; + tdm_vc4_data *vc4_data; drmModeObjectPropertiesPtr props; int i; RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(dpms_value, TDM_ERROR_INVALID_PARAMETER); - drm_data = output_data->drm_data; - props = drmModeObjectGetProperties(drm_data->drm_fd, output_data->connector_id, + vc4_data = output_data->vc4_data; + props = drmModeObjectGetProperties(vc4_data->drm_fd, output_data->connector_id, DRM_MODE_OBJECT_CONNECTOR); if (props == NULL) { TDM_ERR("get property failed: %m"); @@ -1404,9 +1404,9 @@ drm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value) } tdm_error -drm_output_set_mode(tdm_output *output, const tdm_output_mode *mode) +vc4_output_set_mode(tdm_output *output, const tdm_output_mode *mode) { - tdm_drm_output_data *output_data = output; + tdm_vc4_output_data *output_data = output; RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER); @@ -1418,9 +1418,9 @@ drm_output_set_mode(tdm_output *output, const tdm_output_mode *mode) } tdm_error -drm_output_get_mode(tdm_output *output, const tdm_output_mode **mode) +vc4_output_get_mode(tdm_output *output, const tdm_output_mode **mode) { - tdm_drm_output_data *output_data = output; + tdm_vc4_output_data *output_data = output; RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER); @@ -1431,11 +1431,11 @@ drm_output_get_mode(tdm_output *output, const tdm_output_mode **mode) } tdm_error -drm_output_set_status_handler(tdm_output *output, +vc4_output_set_status_handler(tdm_output *output, tdm_output_status_handler func, void *user_data) { - tdm_drm_output_data *output_data = output; + tdm_vc4_output_data *output_data = output; RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER); @@ -1447,10 +1447,10 @@ drm_output_set_status_handler(tdm_output *output, } tdm_error -drm_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps) +vc4_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps) { - tdm_drm_layer_data *layer_data = layer; - tdm_drm_data *drm_data; + tdm_vc4_layer_data *layer_data = layer; + tdm_vc4_data *vc4_data; drmModePlanePtr plane = NULL; drmModeObjectPropertiesPtr props = NULL; int i, format_count = 0; @@ -1461,8 +1461,8 @@ drm_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps) memset(caps, 0, sizeof(tdm_caps_layer)); - drm_data = layer_data->drm_data; - plane = drmModeGetPlane(drm_data->drm_fd, layer_data->plane_id); + vc4_data = layer_data->vc4_data; + plane = drmModeGetPlane(vc4_data->drm_fd, layer_data->plane_id); if (!plane) { TDM_ERR("get plane failed: %m"); ret = TDM_ERROR_OPERATION_FAILED; @@ -1485,13 +1485,13 @@ drm_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps) if (plane->formats[i] != DRM_FORMAT_XRGB8888 && plane->formats[i] != DRM_FORMAT_ARGB8888) continue; - caps->formats[i] = tdm_drm_format_to_tbm_format(plane->formats[i]); + caps->formats[i] = tdm_vc4_format_to_tbm_format(plane->formats[i]); format_count++; } caps->format_count = format_count; - props = drmModeObjectGetProperties(drm_data->drm_fd, layer_data->plane_id, + props = drmModeObjectGetProperties(vc4_data->drm_fd, layer_data->plane_id, DRM_MODE_OBJECT_PLANE); if (!props) { ret = TDM_ERROR_OPERATION_FAILED; @@ -1508,7 +1508,7 @@ drm_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps) caps->prop_count = 0; for (i = 0; i < props->count_props; i++) { - drmModePropertyPtr prop = drmModeGetProperty(drm_data->drm_fd, props->props[i]); + drmModePropertyPtr prop = drmModeGetProperty(vc4_data->drm_fd, props->props[i]); if (!prop) continue; if (!strncmp(prop->name, "type", TDM_NAME_LEN)) @@ -1535,17 +1535,17 @@ failed_get: } tdm_error -drm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value) +vc4_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value) { - tdm_drm_layer_data *layer_data = layer; - tdm_drm_data *drm_data; + tdm_vc4_layer_data *layer_data = layer; + tdm_vc4_data *vc4_data; int ret; RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(layer_data->plane_id > 0, TDM_ERROR_INVALID_PARAMETER); - drm_data = layer_data->drm_data; - ret = drmModeObjectSetProperty(drm_data->drm_fd, + vc4_data = layer_data->vc4_data; + ret = drmModeObjectSetProperty(vc4_data->drm_fd, layer_data->plane_id, DRM_MODE_OBJECT_PLANE, id, value.u32); if (ret < 0) { @@ -1557,10 +1557,10 @@ drm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value) } tdm_error -drm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value) +vc4_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value) { - tdm_drm_layer_data *layer_data = layer; - tdm_drm_data *drm_data; + tdm_vc4_layer_data *layer_data = layer; + tdm_vc4_data *vc4_data; drmModeObjectPropertiesPtr props; int i; @@ -1568,8 +1568,8 @@ drm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value) RETURN_VAL_IF_FAIL(layer_data->plane_id > 0, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(value, TDM_ERROR_INVALID_PARAMETER); - drm_data = layer_data->drm_data; - props = drmModeObjectGetProperties(drm_data->drm_fd, layer_data->plane_id, + vc4_data = layer_data->vc4_data; + props = drmModeObjectGetProperties(vc4_data->drm_fd, layer_data->plane_id, DRM_MODE_OBJECT_PLANE); if (props == NULL) { TDM_ERR("get property failed: %m"); @@ -1588,9 +1588,9 @@ drm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value) } tdm_error -drm_layer_set_info(tdm_layer *layer, tdm_info_layer *info) +vc4_layer_set_info(tdm_layer *layer, tdm_info_layer *info) { - tdm_drm_layer_data *layer_data = layer; + tdm_vc4_layer_data *layer_data = layer; RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER); @@ -1602,9 +1602,9 @@ drm_layer_set_info(tdm_layer *layer, tdm_info_layer *info) } tdm_error -drm_layer_get_info(tdm_layer *layer, tdm_info_layer *info) +vc4_layer_get_info(tdm_layer *layer, tdm_info_layer *info) { - tdm_drm_layer_data *layer_data = layer; + tdm_vc4_layer_data *layer_data = layer; RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER); @@ -1615,37 +1615,37 @@ drm_layer_get_info(tdm_layer *layer, tdm_info_layer *info) } tdm_error -drm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) +vc4_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) { - tdm_drm_layer_data *layer_data = layer; - tdm_drm_data *drm_data; - tdm_drm_display_buffer *display_buffer; + tdm_vc4_layer_data *layer_data = layer; + tdm_vc4_data *vc4_data; + tdm_vc4_display_buffer *display_buffer; tdm_error err = TDM_ERROR_NONE; int ret, i, count; RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(buffer, TDM_ERROR_INVALID_PARAMETER); - drm_data = layer_data->drm_data; + vc4_data = layer_data->vc4_data; - display_buffer = _tdm_drm_display_find_buffer(drm_data, buffer); + display_buffer = _tdm_vc4_display_find_buffer(vc4_data, buffer); if (!display_buffer) { - display_buffer = calloc(1, sizeof(tdm_drm_display_buffer)); + display_buffer = calloc(1, sizeof(tdm_vc4_display_buffer)); if (!display_buffer) { TDM_ERR("alloc failed"); return TDM_ERROR_OUT_OF_MEMORY; } display_buffer->buffer = buffer; - err = tdm_buffer_add_destroy_handler(buffer, _tdm_drm_display_cb_destroy_buffer, - drm_data); + err = tdm_buffer_add_destroy_handler(buffer, _tdm_vc4_display_cb_destroy_buffer, + vc4_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, &drm_data->buffer_list); + LIST_ADDTAIL(&display_buffer->link, &vc4_data->buffer_list); } if (display_buffer->fb_id == 0) { @@ -1669,13 +1669,13 @@ drm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) for (i = 0; i < count; i++) tbm_surface_internal_get_plane_data(buffer, i, &size, &offsets[i], &pitches[i]); - ret = drmModeAddFB2(drm_data->drm_fd, width, height, format, + ret = drmModeAddFB2(vc4_data->drm_fd, width, height, format, handles, pitches, offsets, &display_buffer->fb_id, 0); if (ret < 0) { TDM_ERR("add fb failed: %m"); return TDM_ERROR_OPERATION_FAILED; } - TDM_DBG("drm_data->drm_fd : %d, display_buffer->fb_id:%u", drm_data->drm_fd, + TDM_DBG("vc4_data->drm_fd : %d, display_buffer->fb_id:%u", vc4_data->drm_fd, display_buffer->fb_id); if (IS_RGB(format)) @@ -1691,9 +1691,9 @@ drm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) } tdm_error -drm_layer_unset_buffer(tdm_layer *layer) +vc4_layer_unset_buffer(tdm_layer *layer) { - tdm_drm_layer_data *layer_data = layer; + tdm_vc4_layer_data *layer_data = layer; RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER); diff --git a/src/tdm_drm_format.c b/src/tdm_vc4_format.c similarity index 94% rename from src/tdm_drm_format.c rename to src/tdm_vc4_format.c index eeda432..93fda10 100644 --- a/src/tdm_drm_format.c +++ b/src/tdm_vc4_format.c @@ -5,14 +5,14 @@ #include #include -#include "tdm_drm.h" +#include "tdm_vc4.h" typedef struct { tbm_format tbm_format; uint32_t drm_format; -} tbm_drm_format_data; +} tbm_vc4_format_data; -static const tbm_drm_format_data formats[] = { +static const tbm_vc4_format_data formats[] = { {TBM_FORMAT_C8, DRM_FORMAT_C8}, {TBM_FORMAT_RGB332, DRM_FORMAT_RGB332}, {TBM_FORMAT_BGR233, DRM_FORMAT_BGR233}, @@ -76,7 +76,7 @@ static const tbm_drm_format_data formats[] = { #define NUM_FORMATS (sizeof(formats) / sizeof(formats[0])) uint32_t -tdm_drm_format_to_drm_format(tbm_format format) +tdm_vc4_format_to_drm_format(tbm_format format) { int i; @@ -90,7 +90,7 @@ tdm_drm_format_to_drm_format(tbm_format format) } tbm_format -tdm_drm_format_to_tbm_format(uint32_t format) +tdm_vc4_format_to_tbm_format(uint32_t format) { int i; diff --git a/src/tdm_drm_pp.c b/src/tdm_vc4_pp.c similarity index 87% rename from src/tdm_drm_pp.c rename to src/tdm_vc4_pp.c index 97ee9de..8aba908 100644 --- a/src/tdm_drm_pp.c +++ b/src/tdm_vc4_pp.c @@ -4,18 +4,18 @@ #include -#include "tdm_drm.h" +#include "tdm_vc4.h" #include "tdm_helper.h" -typedef struct _tdm_drm_pp_buffer { +typedef struct _tdm_vc4_pp_buffer { tbm_surface_h src; tbm_surface_h dst; struct list_head link; -} tdm_drm_pp_buffer; +} tdm_vc4_pp_buffer; -typedef struct _tdm_drm_pp_data { - tdm_drm_data *drm_data; +typedef struct _tdm_vc4_pp_data { + tdm_vc4_data *vc4_data; tdm_info_pp info; @@ -25,7 +25,7 @@ typedef struct _tdm_drm_pp_data { void *done_user_data; struct list_head link; -} tdm_drm_pp_data; +} tdm_vc4_pp_data; static tbm_format pp_formats[] = { @@ -41,7 +41,7 @@ static int pp_list_init; static struct list_head pp_list; static pixman_format_code_t -_tdm_drm_pp_pixman_get_format(tbm_format tbmfmt) +_tdm_vc4_pp_pixman_get_format(tbm_format tbmfmt) { switch (tbmfmt) { case TBM_FORMAT_ARGB8888: @@ -57,7 +57,7 @@ _tdm_drm_pp_pixman_get_format(tbm_format tbmfmt) } int -_tdm_drm_pp_pixman_convert(pixman_op_t op, +_tdm_vc4_pp_pixman_convert(pixman_op_t op, unsigned char *srcbuf, unsigned char *dstbuf, pixman_format_code_t src_format, pixman_format_code_t dst_format, int sbw, int sbh, int sx, int sy, int sw, int sh, @@ -160,7 +160,7 @@ CANT_CONVERT: } static tdm_error -_tdm_drm_pp_convert(tdm_drm_pp_buffer *buffer, tdm_info_pp *info) +_tdm_vc4_pp_convert(tdm_vc4_pp_buffer *buffer, tdm_info_pp *info) { tbm_surface_info_s src_info, dst_info; pixman_format_code_t src_format, dst_format; @@ -196,9 +196,9 @@ _tdm_drm_pp_convert(tdm_drm_pp_buffer *buffer, tdm_info_pp *info) tbm_surface_map(buffer->dst, TBM_OPTION_WRITE, &dst_info); GOTO_IF_FAIL(dst_info.planes[0].ptr != NULL, fail_convert); - src_format = _tdm_drm_pp_pixman_get_format(src_info.format); + src_format = _tdm_vc4_pp_pixman_get_format(src_info.format); GOTO_IF_FAIL(src_format > 0, fail_convert); - dst_format = _tdm_drm_pp_pixman_get_format(dst_info.format); + dst_format = _tdm_vc4_pp_pixman_get_format(dst_info.format); GOTO_IF_FAIL(dst_format > 0, fail_convert); if (src_info.format == TBM_FORMAT_YUV420) { @@ -234,7 +234,7 @@ _tdm_drm_pp_convert(tdm_drm_pp_buffer *buffer, tdm_info_pp *info) goto fail_convert; } - _tdm_drm_pp_pixman_convert(PIXMAN_OP_SRC, + _tdm_vc4_pp_pixman_convert(PIXMAN_OP_SRC, src_info.planes[0].ptr, dst_info.planes[0].ptr, src_format, dst_format, sbw, src_info.height, @@ -255,7 +255,7 @@ fail_convert: } tdm_error -tdm_drm_pp_get_capability(tdm_drm_data *drm_data, tdm_caps_pp *caps) +tdm_vc4_pp_get_capability(tdm_vc4_data *vc4_data, tdm_caps_pp *caps) { int i; @@ -287,9 +287,9 @@ tdm_drm_pp_get_capability(tdm_drm_data *drm_data, tdm_caps_pp *caps) } tdm_pp * -tdm_drm_pp_create(tdm_drm_data *drm_data, tdm_error *error) +tdm_vc4_pp_create(tdm_vc4_data *vc4_data, tdm_error *error) { - tdm_drm_pp_data *pp_data = calloc(1, sizeof(tdm_drm_pp_data)); + tdm_vc4_pp_data *pp_data = calloc(1, sizeof(tdm_vc4_pp_data)); if (!pp_data) { TDM_ERR("alloc failed"); if (error) @@ -297,7 +297,7 @@ tdm_drm_pp_create(tdm_drm_data *drm_data, tdm_error *error) return NULL; } - pp_data->drm_data = drm_data; + pp_data->vc4_data = vc4_data; LIST_INITHEAD(&pp_data->pending_buffer_list); @@ -311,10 +311,10 @@ tdm_drm_pp_create(tdm_drm_data *drm_data, tdm_error *error) } void -drm_pp_destroy(tdm_pp *pp) +vc4_pp_destroy(tdm_pp *pp) { - tdm_drm_pp_data *pp_data = pp; - tdm_drm_pp_buffer *b = NULL, *bb = NULL; + tdm_vc4_pp_data *pp_data = pp; + tdm_vc4_pp_buffer *b = NULL, *bb = NULL; if (!pp_data) return; @@ -330,9 +330,9 @@ drm_pp_destroy(tdm_pp *pp) } tdm_error -drm_pp_set_info(tdm_pp *pp, tdm_info_pp *info) +vc4_pp_set_info(tdm_pp *pp, tdm_info_pp *info) { - tdm_drm_pp_data *pp_data = pp; + tdm_vc4_pp_data *pp_data = pp; RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER); @@ -343,10 +343,10 @@ drm_pp_set_info(tdm_pp *pp, tdm_info_pp *info) } tdm_error -drm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst) +vc4_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst) { - tdm_drm_pp_data *pp_data = pp; - tdm_drm_pp_buffer *buffer; + tdm_vc4_pp_data *pp_data = pp; + tdm_vc4_pp_buffer *buffer; RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(src, TDM_ERROR_INVALID_PARAMETER); @@ -358,7 +358,7 @@ drm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst) return TDM_ERROR_OPERATION_FAILED; } - buffer = calloc(1, sizeof(tdm_drm_pp_buffer)); + buffer = calloc(1, sizeof(tdm_vc4_pp_buffer)); if (!buffer) { TDM_ERR("alloc failed"); return TDM_ERROR_NONE; @@ -373,17 +373,17 @@ drm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst) } tdm_error -drm_pp_commit(tdm_pp *pp) +vc4_pp_commit(tdm_pp *pp) { - tdm_drm_pp_data *pp_data = pp; - tdm_drm_pp_buffer *b = NULL, *bb = NULL; + tdm_vc4_pp_data *pp_data = pp; + tdm_vc4_pp_buffer *b = NULL, *bb = NULL; RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER); LIST_FOR_EACH_ENTRY_SAFE(b, bb, &pp_data->pending_buffer_list, link) { LIST_DEL(&b->link); - _tdm_drm_pp_convert(b, &pp_data->info); + _tdm_vc4_pp_convert(b, &pp_data->info); if (pp_data->done_func) pp_data->done_func(pp_data, @@ -397,9 +397,9 @@ drm_pp_commit(tdm_pp *pp) } tdm_error -drm_pp_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func, void *user_data) +vc4_pp_set_done_handler(tdm_pp *pp, tdm_pp_done_handler func, void *user_data) { - tdm_drm_pp_data *pp_data = pp; + tdm_vc4_pp_data *pp_data = pp; RETURN_VAL_IF_FAIL(pp_data, TDM_ERROR_INVALID_PARAMETER); RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER); diff --git a/src/tdm_vc4_pp.h b/src/tdm_vc4_pp.h new file mode 100644 index 0000000..864eb77 --- /dev/null +++ b/src/tdm_vc4_pp.h @@ -0,0 +1,13 @@ +#ifndef _TDM_VC4_PP_H_ +#define _TDM_VC4_PP_H_ + +#include "tdm_vc4.h" + +tdm_error tdm_vc4_pp_get_capability(tdm_vc4_data *drm_data, tdm_caps_pp *caps); +tdm_pp* tdm_vc4_pp_create(tdm_vc4_data *drm_data, tdm_error *error); +void tdm_vc4_pp_handler(unsigned int prop_id, unsigned int *buf_idx, + unsigned int tv_sec, unsigned int tv_usec, void *data); +void tdm_vc4_pp_cb(int fd, unsigned int prop_id, unsigned int *buf_idx, + unsigned int tv_sec, unsigned int tv_usec, + void *user_data); +#endif /* _TDM_VC4_PP_H_ */ -- 2.7.4 From 909095e496fa07168b1c11b6ebd14f665fcbe376 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 22 Mar 2017 16:24:48 +0900 Subject: [PATCH 4/4] use %license macro to copy the COPYING file. Change-Id: I0863b6952335006065286c70d1f41200e22229d2 --- packaging/libtdm-vc4.spec | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packaging/libtdm-vc4.spec b/packaging/libtdm-vc4.spec index 9b751de..f993eec 100644 --- a/packaging/libtdm-vc4.spec +++ b/packaging/libtdm-vc4.spec @@ -28,8 +28,6 @@ make %{?_smp_mflags} %install rm -rf %{buildroot} -mkdir -p %{buildroot}/%{TZ_SYS_RO_SHARE}/license -cp -af COPYING %{buildroot}/%{TZ_SYS_RO_SHARE}/license/%{name} %make_install %post @@ -43,5 +41,5 @@ ln -s libtdm-vc4.so %{_libdir}/tdm/libtdm-default.so %files %defattr(-,root,root,-) %manifest %{name}.manifest -%{TZ_SYS_RO_SHARE}/license/%{name} +%license COPYING %{_libdir}/tdm/libtdm-vc4.so -- 2.7.4