summaryrefslogtreecommitdiff
authorStark Li <stark.li@amlogic.com>2016-11-25 08:59:51 (GMT)
committer Stark Li <stark.li@amlogic.com>2016-11-25 11:44:41 (GMT)
commit8008a01e2d66da19a94a8d186f375e3064adeeff (patch)
tree83a1e359a80a2c34ad848e22a6b4b1f3eb698011
parent0c9801a3d47e5b2d77a02198d5fe54d6567b4866 (diff)
downloadhwcomposer-8008a01e2d66da19a94a8d186f375e3064adeeff.zip
hwcomposer-8008a01e2d66da19a94a8d186f375e3064adeeff.tar.gz
hwcomposer-8008a01e2d66da19a94a8d186f375e3064adeeff.tar.bz2
PD#135792: change logcat E to I&W and remove old hwc2 and add hwc1.4
Change-Id: I92363ac5ae7a0ff73d70390080d755673769f6d4
Diffstat
-rw-r--r--Android.mk17
-rw-r--r--hwc1.4/Android.mk (renamed from hwc2_old/Android.mk)23
-rw-r--r--hwc1.4/hwcomposer.cpp1202
-rw-r--r--hwc2/common/base/Hwcomposer.cpp2
-rw-r--r--hwc2/common/devices/PhysicalDevice.cpp2
-rw-r--r--hwc2/platforms/PlatFactory.cpp2
-rw-r--r--hwc2_old/hwcomposer.cpp3283
7 files changed, 1223 insertions, 3308 deletions
diff --git a/Android.mk b/Android.mk
index c2d760a..00bdcb7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -15,12 +15,21 @@
LOCAL_PATH := $(call my-dir)
LOCAL_ROOT_PATH := $(call my-dir)
-USE_HWC2_CPP := true
+# USE_HWC2_CPP := true
-ifeq ($(USE_HWC2_CPP),true)
+# ifeq ($(USE_HWC2_CPP),true)
+# include $(LOCAL_PATH)/hwc2/platforms/Android.mk
+# else
+# include $(LOCAL_PATH)/hwc2_old/Android.mk
+# endif
+
+USE_HWC2 := true
+ifeq ($(USE_HWC2),true)
include $(LOCAL_PATH)/hwc2/platforms/Android.mk
else
- include $(LOCAL_PATH)/hwc2_old/Android.mk
+ include $(LOCAL_PATH)/hwc1.4/Android.mk
endif
-include $(LOCAL_ROOT_PATH)/tvp/Android.mk \ No newline at end of file
+# include $(LOCAL_PATH)/hwc2/platforms/Android.mk
+
+include $(LOCAL_ROOT_PATH)/tvp/Android.mk
diff --git a/hwc2_old/Android.mk b/hwc1.4/Android.mk
index 1c31b80..1d7cc85 100644
--- a/hwc2_old/Android.mk
+++ b/hwc1.4/Android.mk
@@ -9,22 +9,9 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_RELATIVE_PATH := hw
-
-LOCAL_SRC_FILES := hwcomposer.cpp
-LOCAL_CFLAGS := -DLOG_TAG=\"Hwcomposer\"
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- liblog \
- libEGL \
- libdl \
- libhardware \
- libutils \
- libsync \
- libfbcnf \
- libhardware_legacy
-
+LOCAL_SHARED_LIBRARIES := liblog libEGL libutils libcutils libhardware libsync libfbcnf libhardware_legacy
LOCAL_STATIC_LIBRARIES := libomxutil
+LOCAL_SRC_FILES := hwcomposer.cpp
LOCAL_KK=0
ifeq ($(GPU_TYPE),t83x)
@@ -45,8 +32,7 @@ LOCAL_C_INCLUDES += \
$(MESON_GRALLOC_DIR)
LOCAL_C_INCLUDES += system/core/libion/include/ \
- system/core/libion/kernel-headers \
- $(LOCAL_PATH)/..
+ system/core/libion/kernel-headers
ifneq ($(WITH_LIBPLAYER_MODULE),false)
LOCAL_SHARED_LIBRARIES += libamavutils_alsa
@@ -64,6 +50,7 @@ endif
endif
LOCAL_MODULE := hwcomposer.amlogic
+LOCAL_CFLAGS += -DLOG_TAG=\"hwcomposer\"
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
-include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/hwc1.4/hwcomposer.cpp b/hwc1.4/hwcomposer.cpp
new file mode 100644
index 0000000..8f50754
--- a/dev/null
+++ b/hwc1.4/hwcomposer.cpp
@@ -0,0 +1,1202 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "HWComposer"
+#include <hardware/hardware.h>
+
+#include <fcntl.h>
+#include <math.h>
+#include <poll.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <sys/resource.h>
+
+#include <EGL/egl.h>
+
+#define HWC_REMOVE_DEPRECATED_VERSIONS 1
+
+#include <cutils/compiler.h>
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+#include <cutils/properties.h>
+
+#include <utils/String8.h>
+#include <hardware/gralloc.h>
+#include <hardware/hwcomposer.h>
+#include <hardware_legacy/uevent.h>
+#include <utils/String8.h>
+
+#include <EGL/egl.h>
+#include <utils/Vector.h>
+#include <utils/Timers.h>
+#include <system/graphics.h>
+#include <sync/sync.h>
+// for private_handle_t
+#include <gralloc_priv.h>
+#include <gralloc_helper.h>
+
+#if WITH_LIBPLAYER_MODULE
+#include <Amavutils.h>
+#endif
+#include "../tvp/OmxUtil.h"
+
+#ifndef LOGD
+#define LOGD ALOGD
+#endif
+
+///Defines for debug statements - Macro LOG_TAG needs to be defined in the respective files
+#define HWC_LOGVA(str) ALOGV_IF(chk_int_prop("sys.hwc.debuglevel") >=6,"%5d %s - " str, __LINE__,__FUNCTION__);
+#define HWC_LOGVB(str,...) ALOGV_IF(chk_int_prop("sys.hwc.debuglevel") >=6,"%5d %s - " str, __LINE__, __FUNCTION__, __VA_ARGS__);
+#define HWC_LOGDA(str) ALOGD_IF(chk_int_prop("sys.hwc.debuglevel") >=5,"%5d %s - " str, __LINE__,__FUNCTION__);
+#define HWC_LOGDB(str, ...) ALOGD_IF(chk_int_prop("sys.hwc.debuglevel") >=5,"%5d %s - " str, __LINE__, __FUNCTION__, __VA_ARGS__);
+#define HWC_LOGIA(str) ALOGI_IF(chk_int_prop("sys.hwc.debuglevel") >=4,"%5d %s - " str, __LINE__, __FUNCTION__);
+#define HWC_LOGIB(str, ...) ALOGI_IF(chk_int_prop("sys.hwc.debuglevel") >=4,"%5d %s - " str, __LINE__,__FUNCTION__, __VA_ARGS__);
+#define HWC_LOGWA(str) ALOGW_IF(chk_int_prop("sys.hwc.debuglevel") >=3,"%5d %s - " str, __LINE__, __FUNCTION__);
+#define HWC_LOGWB(str, ...) ALOGW_IF(chk_int_prop("sys.hwc.debuglevel") >=3,"%5d %s - " str, __LINE__,__FUNCTION__, __VA_ARGS__);
+#define HWC_LOGEA(str) ALOGE_IF(chk_int_prop("sys.hwc.debuglevel") >=2,"%5d %s - " str, __LINE__, __FUNCTION__);
+#define HWC_LOGEB(str, ...) ALOGE_IF(chk_int_prop("sys.hwc.debuglevel") >=2,"%5d %s - " str, __LINE__,__FUNCTION__, __VA_ARGS__);
+
+#define LOG_FUNCTION_NAME HWC_LOGVA("ENTER");
+#define LOG_FUNCTION_NAME_EXIT HWC_LOGVA("EXIT");
+#define DBG_LOGA(str) ALOGI_IF(chk_int_prop("sys.hwc.debuglevel") >=4,"%10s-%5d %s - " str, HWC_BUILD_NAME, __LINE__,__FUNCTION__)
+#define DBG_LOGB(str, ...) ALOGI_IF(chk_int_prop("sys.hwc.debuglevel") >=4,"%10s-%5d %s - " str, HWC_BUILD_NAME, __LINE__,__FUNCTION__, __VA_ARGS__);
+
+#define SYSFS_AMVIDEO_CURIDX "/sys/module/amvideo/parameters/cur_dev_idx"
+#define SYSFS_DISPLAY_MODE "/sys/class/display/mode"
+#define SYSFS_FB0_FREE_SCALE "/sys/class/graphics/fb0/free_scale"
+#define SYSFS_FB1_FREE_SCALE "/sys/class/graphics/fb0/free_scale"
+#define SYSFS_VIDEO_AXIS "/sys/class/video/axis"
+#define SYSFS_VIDEOBUFUSED "/sys/class/amstream/videobufused"
+#define SYSFS_WINDOW_AXIS "/sys/class/graphics/fb0/window_axis"
+
+#define MAX_SUPPORT_DISPLAYS HWC_NUM_PHYSICAL_DISPLAY_TYPES
+
+#ifdef SINGLE_EXTERNAL_DISPLAY_USE_FB1
+#undef ENABLE_CURSOR_LAYER
+#define CHK_SKIP_DISPLAY_FB0(dispIdx) \
+ if (pdev->display_ctxs[HWC_DISPLAY_EXTERNAL].connected\
+ && dispIdx == HWC_DISPLAY_PRIMARY) {\
+ continue;\
+ }
+#else
+#define ENABLE_CURSOR_LAYER 1//cursor layer supported in hwc 1.4
+#define CHK_SKIP_DISPLAY_FB0(dispIdx) //nothing to do
+#endif
+
+#define get_display_info(ctx,disp) \
+ display_context_t * display_ctx = &(ctx->display_ctxs[disp]);\
+ framebuffer_info_t* fbinfo = &(display_ctx->fb_info);
+
+typedef struct cursor_context_t{
+ bool blank;
+ struct framebuffer_info_t cb_info;
+ void *cbuffer;
+ bool show;
+}cursor_context_t;
+
+typedef struct display_context_t{
+ bool connected;
+ struct framebuffer_info_t fb_info;
+ struct private_handle_t* fb_hnd;
+#ifdef ENABLE_CURSOR_LAYER
+ struct cursor_context_t cursor_ctx;
+#endif
+}display_context_t;
+
+struct hwc_context_1_t {
+ hwc_composer_device_1_t base;
+
+ /* our private state goes below here */
+ hwc_layer_1_t const* saved_layer;
+ unsigned saved_transform;
+ int saved_left;
+ int saved_top;
+ int saved_right;
+ int saved_bottom;
+
+ //vsync.
+ int32_t vsync_period;
+ int vsync_enable;
+ pthread_t vsync_thread;
+
+ bool blank_status;
+
+ //video buf is used flag
+ char video_buf_used[32];
+ //hdmi output mode
+ char mode[32];
+
+ const hwc_procs_t *procs;
+ pthread_t hotplug_thread;
+
+ private_module_t *gralloc_module;
+ display_context_t display_ctxs[MAX_SUPPORT_DISPLAYS];
+};
+
+typedef struct hwc_uevent_data {
+ int len;
+ char buf[1024];
+ char name[128];
+ char state[128];
+} hwc_uevent_data_t;
+
+static pthread_cond_t hwc_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t hwc_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
+ const struct timespec *request, struct timespec *remain);
+int init_display(hwc_context_1_t* context,int displayType);
+int uninit_display(hwc_context_1_t* context,int displayType);
+
+static bool chk_bool_prop(const char* prop) {
+ char val[PROPERTY_VALUE_MAX];
+
+ memset(val, 0, sizeof(val));
+ if (property_get(prop, val, "false") && strcmp(val, "true") == 0) {
+ ALOGD("prop: %s is %s",prop, val);
+ return true;
+ }
+
+ return false;
+}
+
+static int chk_int_prop(const char* prop) {
+ char val[PROPERTY_VALUE_MAX];
+
+ memset(val, 0, sizeof(val));
+ if (property_get(prop, val, "2")) {
+ //ALOGV("prop: %s is %s",prop, val);
+ return atoi(val);
+ }
+ return 0;
+}
+
+static int chk_and_dup(int fence) {
+ if (fence < 0) {
+ HWC_LOGWB("not a vliad fence %d",fence);
+ return -1;
+ }
+
+ int dup_fence = dup(fence);
+ if (dup_fence < 0) {
+ HWC_LOGWB("fence dup failed: %s", strerror(errno));
+ }
+
+ return dup_fence;
+}
+
+#if WITH_LIBPLAYER_MODULE
+static bool chk_sysfs_status(const char* sysfstr, char* lastr, int size) {
+ char val[32];
+ char *p = lastr;
+
+ memset(val, 0, sizeof(val));
+ if (amsysfs_get_sysfs_str(sysfstr, val, sizeof(val)) == 0) {
+ HWC_LOGVB("val: %s, lastr: %s",val, p);
+ if ((strcmp(val, p) != 0)) {
+ memset(p, 0, size);
+ strcpy(p, val);
+ return true;
+ }
+ }
+
+ return false;
+}
+#endif
+
+static int32_t chk_output_mode(char* curmode) {
+ int modefd = open(SYSFS_DISPLAY_MODE, O_RDONLY);
+ if (modefd < 0) {
+ HWC_LOGEB("open (%s) fail", SYSFS_DISPLAY_MODE);
+ return -1;
+ }
+
+ char outputmode[32] = {0};
+ read(modefd, outputmode, 31);
+ close(modefd);
+ modefd = -1;
+
+ //check if need update vsync.
+ if (strcmp(outputmode, curmode) == 0) {
+ HWC_LOGVB("outputmode didn't change %s", curmode);
+ return 0;
+ }
+
+ strcpy(curmode, outputmode);
+
+ int32_t period = 16666666;
+ if (strstr(outputmode, "50hz") != NULL) {
+ period = (int32_t)(1e9 / 50);
+ } else if (strstr(outputmode, "30hz") != NULL) {
+ period = (int32_t)(1e9 / 30);
+ } else if (strstr(outputmode, "25hz") != NULL) {
+ period = (int32_t)(1e9 / 25);
+ } else if ((strstr(outputmode, "24hz") != NULL) || (strstr(outputmode, "smpte") != NULL)) {
+ period = (int32_t)(1e9 / 24);
+ } else
+ HWC_LOGDB("displaymode (%s) doesn't specify HZ", curmode);
+
+ HWC_LOGVB("get new outputmode (%s) new period (%ld)", curmode, period);
+ return period;
+}
+
+static bool chk_vinfo(hwc_context_1_t* ctx, int disp) {
+ get_display_info(ctx, disp);
+ if (fbinfo != NULL && fbinfo->fd >= 0) {
+ struct fb_var_screeninfo vinfo;
+ if (ioctl(fbinfo->fd, FBIOGET_VSCREENINFO, &vinfo) == -1)
+ {
+ ALOGE("FBIOGET_VSCREENINFO error!!!");
+ return -errno;
+ }
+
+ if (vinfo.xres != fbinfo->info.xres
+ || vinfo.yres != fbinfo->info.yres
+ || vinfo.width != fbinfo->info.width
+ || vinfo.height != fbinfo->info.height) {
+ if (int(vinfo.width) <= 16 || int(vinfo.height) <= 9) {
+ // the driver doesn't return that information
+ // default to 160 dpi
+ vinfo.width = ((vinfo.xres * 25.4f)/160.0f + 0.5f);
+ vinfo.height = ((vinfo.yres * 25.4f)/160.0f + 0.5f);
+ }
+ fbinfo->xdpi = (vinfo.xres * 25.4f) / vinfo.width;
+ fbinfo->ydpi = (vinfo.yres * 25.4f) / vinfo.height;
+
+ fbinfo->info.xres = vinfo.xres;
+ fbinfo->info.yres = vinfo.yres;
+ fbinfo->info.width = vinfo.width;
+ fbinfo->info.height = vinfo.height;
+
+ return true;
+ }
+ }
+ return false;
+}
+
+static int hwc_device_open(const struct hw_module_t* module, const char* name,
+ struct hw_device_t** device);
+
+static struct hw_module_methods_t hwc_module_methods = {
+ open: hwc_device_open
+};
+
+hwc_module_t HAL_MODULE_INFO_SYM = {
+ common: {
+ tag: HARDWARE_MODULE_TAG,
+ version_major: 1,
+ version_minor: 0,
+ id: HWC_HARDWARE_MODULE_ID,
+ name: "hwcomposer module",
+ author: "Amlogic",
+ methods: &hwc_module_methods,
+ dso : NULL,
+ reserved : {0},
+ }
+ };
+
+#if 0
+static void dump_handle(private_handle_t *h) {
+ //ALOGV("\t\tformat = %d, width = %u, height = %u, stride = %u, vstride = %u",
+ // h->format, h->width, h->height, h->stride, h->vstride);
+}
+
+static void dump_layer(hwc_layer_1_t const *l) {
+ HWC_LOGVB("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, "
+ "{%d,%d,%d,%d}, {%d,%d,%d,%d}",
+ l->compositionType, l->flags, l->handle, l->transform,
+ l->blending,
+ l->sourceCrop.left,
+ l->sourceCrop.top,
+ l->sourceCrop.right,
+ l->sourceCrop.bottom,
+ l->displayFrame.left,
+ l->displayFrame.top,
+ l->displayFrame.right,
+ l->displayFrame.bottom);
+
+ if (l->handle && !(l->flags & HWC_SKIP_LAYER)) dump_handle(private_handle_t::dynamicCast(l->handle));
+}
+#endif
+
+static void hwc_overlay_compose(hwc_context_1_t *dev, hwc_layer_1_t const* l) {
+ int angle;
+ struct hwc_context_1_t* ctx = (struct hwc_context_1_t*)dev;
+
+#if WITH_LIBPLAYER_MODULE
+ static char last_val[32] = "0";
+ static char last_axis[32] = "0";
+ static char last_mode[32] = {0};
+ static char last_free_scale[32] = {0};
+ static char last_window_axis[50] = {0};
+ bool vpp_changed = false;
+ bool axis_changed = false;
+ bool mode_changed = false;
+ bool free_scale_changed = false;
+ bool window_axis_changed =false;
+
+ if (chk_bool_prop("ro.vout.dualdisplay4")) {
+ vpp_changed = chk_sysfs_status(SYSFS_AMVIDEO_CURIDX, last_val, 32);
+ }
+
+ mode_changed = chk_sysfs_status(SYSFS_DISPLAY_MODE, last_mode, 32);
+
+ free_scale_changed = chk_sysfs_status(SYSFS_FB0_FREE_SCALE, last_free_scale, 32);
+#ifdef SINGLE_EXTERNAL_DISPLAY_USE_FB1
+ if (ctx->display_ctxs[HWC_DISPLAY_EXTERNAL].connected)
+ free_scale_changed = chk_sysfs_status(SYSFS_FB1_FREE_SCALE, last_free_scale, 32);
+#endif
+
+ axis_changed = chk_sysfs_status(SYSFS_VIDEO_AXIS, last_axis, 32);
+ window_axis_changed = chk_sysfs_status(SYSFS_WINDOW_AXIS, last_window_axis, 50);
+
+ if ((ctx->saved_layer == l) &&
+ (ctx->saved_transform == l->transform) &&
+ (ctx->saved_left == l->displayFrame.left) &&
+ (ctx->saved_top == l->displayFrame.top) &&
+ (ctx->saved_right == l->displayFrame.right) &&
+ (ctx->saved_bottom == l->displayFrame.bottom) &&
+ !vpp_changed && !mode_changed && !axis_changed && !free_scale_changed && !window_axis_changed) {
+ return;
+ }
+
+ switch (l->transform) {
+ case 0:
+ angle = 0;
+ break;
+ case HAL_TRANSFORM_ROT_90:
+ angle = 90;
+ break;
+ case HAL_TRANSFORM_ROT_180:
+ angle = 180;
+ break;
+ case HAL_TRANSFORM_ROT_270:
+ angle = 270;
+ break;
+ default:
+ return;
+ }
+
+ amvideo_utils_set_virtual_position(l->displayFrame.left,
+ l->displayFrame.top,
+ l->displayFrame.right - l->displayFrame.left,
+ l->displayFrame.bottom - l->displayFrame.top,
+ angle);
+
+ /* the screen mode from Android framework should always be set to normal mode
+ * to match the relationship between the UI and video overlay window position.
+ */
+ /*set screen_mode in amvideo_utils_set_virtual_position(),pls check in libplayer*/
+ //amvideo_utils_set_screen_mode(0);
+#endif
+
+ ctx->saved_layer = l;
+ ctx->saved_transform = l->transform;
+ ctx->saved_left = l->displayFrame.left;
+ ctx->saved_top = l->displayFrame.top;
+ ctx->saved_right = l->displayFrame.right;
+ ctx->saved_bottom = l->displayFrame.bottom;
+
+#if WITH_LIBPLAYER_MODULE
+ memset(last_axis, 0, sizeof(last_axis));
+
+ if (amsysfs_get_sysfs_str(SYSFS_VIDEO_AXIS, last_axis, sizeof(last_axis)) == 0) {
+ HWC_LOGDB("****last video axis is: %s",last_axis);
+ }
+#endif
+}
+
+static void hwc_dump(hwc_composer_device_1* dev, char *buff, int buff_len) {
+ if (buff_len <= 0) return;
+
+ struct hwc_context_1_t *pdev = (struct hwc_context_1_t *)dev;
+
+ android::String8 result;
+
+ for (int i = 0; i < MAX_SUPPORT_DISPLAYS; i++) {
+ get_display_info(pdev,i);
+
+ if (display_ctx->connected) {
+ result.appendFormat(" %8s Display connected: %3s\n",
+ HWC_DISPLAY_EXTERNAL == i ? "External":"Primiary", display_ctx->connected ? "Yes" : "No");
+ result.appendFormat(" w=%u, h=%u, xdpi=%f, ydpi=%f, osdIdx=%d, vsync_period=%d, video_buf_used: %s\n",
+ fbinfo->info.xres,
+ fbinfo->info.yres,
+ fbinfo->xdpi,
+ fbinfo->ydpi,
+ fbinfo->fbIdx,
+ pdev->vsync_period,
+ pdev->video_buf_used);
+ }
+ }
+
+ //result.append(
+ // " type | handle | color | blend | format | position | size | gsc \n"
+ // "----------+----------|----------+-------+--------+---------------+---------------------\n");
+ // 8_______ | 8_______ | 8_______ | 5____ | 6_____ | [5____,5____] | [5____,5____] | 3__ \n"
+
+ result.append("\n");
+
+ strlcpy(buff, result.string(), buff_len);
+}
+
+static int hwc_blank(struct hwc_composer_device_1 *dev, int disp, int blank) {
+ struct hwc_context_1_t *pdev = (struct hwc_context_1_t *)dev;
+
+ //TODO: need impl
+ if (disp == HWC_DISPLAY_PRIMARY) pdev->blank_status = ( blank ? true : false);
+
+ return 0;
+}
+
+static int hwc_setPowerMode(struct hwc_composer_device_1*, int, int) {
+ LOG_FUNCTION_NAME
+ //TODO:
+ LOG_FUNCTION_NAME_EXIT
+ return 0;
+}
+
+static int hwc_query(struct hwc_composer_device_1* dev, int what, int *value) {
+ LOG_FUNCTION_NAME
+
+ struct hwc_context_1_t *pdev = (struct hwc_context_1_t *)dev;
+
+ switch (what) {
+ case HWC_BACKGROUND_LAYER_SUPPORTED:
+ // we support the background layer
+ value[0] = 1;
+ break;
+ case HWC_VSYNC_PERIOD:
+ // vsync period in nanosecond
+ value[0] = pdev->vsync_period;
+ break;
+ default:
+ // unsupported query
+ return -EINVAL;
+ }
+
+ LOG_FUNCTION_NAME_EXIT
+ return 0;
+}
+
+static int hwc_eventControl(struct hwc_composer_device_1* dev,
+ int,
+ int event,
+ int enabled) {
+ struct hwc_context_1_t* ctx = (struct hwc_context_1_t *)dev;
+
+ switch (event)
+ {
+ case HWC_EVENT_VSYNC:
+ ctx->vsync_enable = enabled;
+ pthread_mutex_lock(&hwc_mutex);
+ pthread_cond_signal(&hwc_cond);
+ pthread_mutex_unlock(&hwc_mutex);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int hwc_prepare(struct hwc_composer_device_1 *dev,
+ size_t numDisplays,
+ hwc_display_contents_1_t** displays) {
+ int err = 0;
+ size_t i = 0;
+ hwc_context_1_t *pdev = (hwc_context_1_t *)dev;
+ hwc_display_contents_1_t *display_content = NULL;
+
+ if (!numDisplays || !displays) return 0;
+
+ LOG_FUNCTION_NAME
+ //retireFenceFd will close in surfaceflinger, just reset it.
+ for (i = 0; i < numDisplays; i++) {
+ CHK_SKIP_DISPLAY_FB0();
+
+ display_content = displays[i];
+ if ( display_content ) {
+ display_content->retireFenceFd = -1;
+ for (size_t j=0 ; j< display_content->numHwLayers ; j++) {
+ hwc_layer_1_t* l = &display_content->hwLayers[j];
+
+#ifdef ENABLE_CURSOR_LAYER
+ if (l->flags & HWC_IS_CURSOR_LAYER) {
+ if (i == HWC_DISPLAY_PRIMARY) {
+ l->hints = HWC_HINT_CLEAR_FB;
+ HWC_LOGDA("This is a Cursor layer");
+ l->compositionType = HWC_CURSOR_OVERLAY;
+ continue;
+ } else {
+ HWC_LOGDA("This is not a primary display's Cursor layer, need to set composition type to gles");
+ // l->compositionType = HWC_FRAMEBUFFER;
+ }
+ }
+#endif
+
+ if (i == HWC_DISPLAY_PRIMARY && l->compositionType == HWC_SIDEBAND && l->sidebandStream) {
+ //TODO: we just transact SIDEBAND to OVERLAY now;
+ HWC_LOGVA("get HWC_SIDEBAND layer, just change to overlay");
+ l->hints = HWC_HINT_CLEAR_FB;
+ l->compositionType = HWC_OVERLAY;
+ continue;
+ }
+
+ if (i == HWC_DISPLAY_PRIMARY && l->handle) {
+ private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(l->handle);
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_OSD_VIDEO_OMX) {
+ l->hints = HWC_HINT_OSD_VIDEO_OMX;
+ }
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OVERLAY) {
+ l->hints = HWC_HINT_CLEAR_FB;
+ l->compositionType = HWC_OVERLAY;
+ continue;
+ }
+ }
+ }
+ }
+ }
+
+ LOG_FUNCTION_NAME_EXIT
+ return 0;
+}
+
+static int fb_post(hwc_context_1_t *pdev,
+ hwc_display_contents_1_t* contents, int display_type) {
+ int err = 0;
+ size_t i = 0;
+
+#ifdef ENABLE_CURSOR_LAYER
+ cursor_context_t * cursor_ctx = &(pdev->display_ctxs[HWC_DISPLAY_PRIMARY].cursor_ctx);
+ framebuffer_info_t* cbinfo = &(cursor_ctx->cb_info);
+ bool cursor_show = false;
+#endif
+
+ for (i = 0; i < contents->numHwLayers; i++) {
+#ifdef ENABLE_CURSOR_LAYER
+ //deal cursor layer
+ if (display_type == HWC_DISPLAY_PRIMARY && contents->hwLayers[i].flags & HWC_IS_CURSOR_LAYER) {
+ hwc_layer_1_t *layer = &(contents->hwLayers[i]);
+ if (private_handle_t::validate(layer->handle) < 0) break;
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+
+ HWC_LOGDB("This is a Sprite, hnd->stride is %d, hnd->height is %d", hnd->stride, hnd->height);
+ if (cbinfo->info.xres != (unsigned int)hnd->stride || cbinfo->info.yres != (unsigned int)hnd->height) {
+ HWC_LOGDB("disp: %d cursor need to redrew", display_type);
+ update_cursor_buffer_locked(cbinfo, hnd->stride, hnd->height);
+ cursor_ctx->cbuffer = mmap(NULL, hnd->size, PROT_READ|PROT_WRITE, MAP_SHARED, cbinfo->fd, 0);
+ if (cursor_ctx->cbuffer != MAP_FAILED) {
+ memcpy(cursor_ctx->cbuffer, hnd->base, hnd->size);
+ munmap(cursor_ctx->cbuffer, hnd->size);
+ HWC_LOGDA("setCursor ok");
+ } else {
+ HWC_LOGEA("buffer mmap fail");
+ }
+ }
+ cursor_show = true;
+ }
+#endif
+
+ //deal framebuffer target layer
+ if (contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
+ hwc_layer_1_t *layer = &(contents->hwLayers[i]);
+ if (private_handle_t::validate(layer->handle) < 0) break;
+
+ //deal with virtural display fence
+ if (display_type == HWC_DISPLAY_VIRTUAL) {
+ layer->releaseFenceFd = layer->acquireFenceFd;
+ contents->retireFenceFd = contents->outbufAcquireFenceFd;
+
+ HWC_LOGVB("HWC_DISPLAY_VIRTUAL Get release fence %d, retire fence %d, outbufAcquireFenceFd %d",
+ layer->releaseFenceFd,
+ contents->retireFenceFd, contents->outbufAcquireFenceFd);
+ continue;
+ }
+
+ get_display_info(pdev, display_type);
+ layer->releaseFenceFd = fb_post_with_fence_locked(fbinfo,layer->handle,layer->acquireFenceFd);
+
+ if (layer->releaseFenceFd >= 0) {
+ //layer->releaseFenceFd = releaseFence;
+ contents->retireFenceFd = chk_and_dup(layer->releaseFenceFd);
+
+ HWC_LOGVB("Get release fence %d, retire fence %d",
+ layer->releaseFenceFd,
+ contents->retireFenceFd);
+ } else {
+ HWC_LOGEB("No valid release_fence returned. %d ",layer->releaseFenceFd);
+ //-1 means no fence, less than -1 is some error
+ if (layer->releaseFenceFd < -1) err = layer->releaseFenceFd;
+ contents->retireFenceFd = layer->releaseFenceFd = -1;
+ }
+ }
+ }
+
+#ifdef ENABLE_CURSOR_LAYER
+ //finally we need to update cursor's blank status
+ if (display_type == HWC_DISPLAY_PRIMARY
+ && cbinfo->fd > 0 && (cursor_show != cursor_ctx->show) ) {
+ cursor_ctx->show = cursor_show;
+ HWC_LOGVB("UPDATE FB1 status to %d ",cursor_show);
+ ioctl(cbinfo->fd, FBIOBLANK, !cursor_ctx->show);
+ }
+#endif
+
+ return err;
+}
+
+
+static int hwc_set(struct hwc_composer_device_1 *dev,
+ size_t numDisplays, hwc_display_contents_1_t** displays) {
+ int err = 0;
+ size_t i = 0, j = 0;
+ hwc_context_1_t *pdev = (hwc_context_1_t *)dev;
+ hwc_display_contents_1_t *display_content = NULL;
+
+ if (!numDisplays || !displays) return 0;
+
+ LOG_FUNCTION_NAME
+ //TODO: need improve the way to set video axis.
+#if WITH_LIBPLAYER_MODULE
+ for (i = 0; i < numDisplays; i++) {
+ CHK_SKIP_DISPLAY_FB0();
+ display_content = displays[i];
+ if (display_content) {
+ for (j = 0; j < display_content->numHwLayers; j++) {
+ hwc_layer_1_t* l = &display_content->hwLayers[j];
+ if (l->compositionType == HWC_OVERLAY) {
+ hwc_overlay_compose(pdev, l);
+ }
+ }
+ }
+ }
+
+#endif
+
+ for (i=0;i<numDisplays;i++) {
+ CHK_SKIP_DISPLAY_FB0();
+ display_content = displays[i];
+ if (display_content) {
+ if (i <= HWC_DISPLAY_VIRTUAL) {
+ //physic display
+ err = fb_post(pdev,display_content,i);
+ } else {
+ HWC_LOGEB("display %d is not supported",i);
+ }
+ }
+ }
+
+ LOG_FUNCTION_NAME_EXIT
+ return err;
+}
+
+static int hwc_close(hw_device_t *device) {
+ struct hwc_context_1_t *dev = (struct hwc_context_1_t *)device;
+
+ LOG_FUNCTION_NAME
+
+ pthread_kill(dev->vsync_thread, SIGTERM);
+ pthread_join(dev->vsync_thread, NULL);
+
+ uninit_display(dev,HWC_DISPLAY_PRIMARY);
+ uninit_display(dev,HWC_DISPLAY_EXTERNAL);
+
+ if (dev) free(dev);
+
+ LOG_FUNCTION_NAME_EXIT
+ return 0;
+}
+
+//#define USE_HW_VSYNC
+#ifdef USE_HW_VSYNC
+/*
+Still have bugs, don't use it.
+*/
+int wait_next_vsync(struct hwc_context_1_t* ctx, nsecs_t* vsync_timestamp) {
+ static nsecs_t previewTime = 0;
+ nsecs_t vsyncDiff=0;
+ const nsecs_t period = ctx->vsync_period;
+ //we will delay hw vsync if missing one vsync interrupt isr.
+ int ret = 0;
+
+ if (ioctl(ctx->display_ctxs[0].fb_info.fd, FBIO_WAITFORVSYNC, &ret) == -1) {
+ HWC_LOGEB("ioctrl error %d",ctx->display_ctxs[0].fb_info.fd);
+ ret=-1;
+ } else {
+ if (ret == 1) {
+ *vsync_timestamp = systemTime(CLOCK_MONOTONIC);
+ vsyncDiff=*vsync_timestamp - previewTime;
+ if (previewTime != 0) HWC_LOGEB("wait for vsync success %lld",vsyncDiff);
+ vsyncDiff%=period;
+ if (vsyncDiff > 500000) {
+ nsecs_t sleep ;
+ sleep = (period - vsyncDiff);
+ *vsync_timestamp+=sleep;
+ struct timespec spec;
+ spec.tv_sec = *vsync_timestamp / 1000000000;
+ spec.tv_nsec = *vsync_timestamp % 1000000000;
+ clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
+ }
+ previewTime = *vsync_timestamp;
+ ret=0;
+ } else {
+ HWC_LOGEA("wait for vsync fail");
+ ret=-1;
+ }
+ }
+ return ret;
+}
+
+#else
+
+//software
+int wait_next_vsync(struct hwc_context_1_t* ctx, nsecs_t* vsync_timestamp) {
+ static nsecs_t vsync_time = 0;
+ static nsecs_t old_vsync_period = 0;
+ nsecs_t sleep;
+ nsecs_t now = systemTime(CLOCK_MONOTONIC);
+
+ //cal the last vsync time with old period
+ if (ctx->vsync_period != old_vsync_period) {
+ if (old_vsync_period > 0) {
+ vsync_time = vsync_time +
+ ((now - vsync_time) / old_vsync_period) * old_vsync_period;
+ }
+ old_vsync_period = ctx->vsync_period;
+ }
+
+ //set to next vsync time
+ vsync_time +=ctx->vsync_period;
+
+ // we missed, find where the next vsync should be
+ if (vsync_time - now < 0) {
+ vsync_time = now + (ctx->vsync_period -
+ ((now - vsync_time) % ctx->vsync_period));
+ }
+
+ struct timespec spec;
+ spec.tv_sec = vsync_time / 1000000000;
+ spec.tv_nsec = vsync_time % 1000000000;
+
+ int err;
+ do {
+ err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
+ } while (err<0 && errno == EINTR);
+ *vsync_timestamp = vsync_time;
+
+ return err;
+}
+#endif
+
+static void *hwc_vsync_thread(void *data) {
+ struct hwc_context_1_t* ctx = (struct hwc_context_1_t*)data;
+ nsecs_t timestamp;
+
+ setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY-1);
+ sleep(2);
+
+ while (true) {
+ pthread_mutex_lock(&hwc_mutex);
+ while (ctx->vsync_enable == false) {
+ pthread_cond_wait(&hwc_cond, &hwc_mutex);
+ }
+ pthread_mutex_unlock(&hwc_mutex);
+
+ if (wait_next_vsync(ctx,&timestamp) == 0) {
+ if (ctx->procs) ctx->procs->vsync(ctx->procs, 0, timestamp);
+ }
+ }
+
+ return NULL;
+}
+
+//#ifdef WITH_EXTERNAL_DISPLAY
+//#define SIMULATE_HOT_PLUG 1
+#define HDMI_UEVENT "DEVPATH=/devices/virtual/switch/hdmi_audio"
+#define HDMI_POWER_UEVENT "DEVPATH=/devices/virtual/switch/hdmi_power"
+
+static bool isMatch(hwc_uevent_data_t* ueventData, const char* matchName) {
+ bool matched = false;
+ // Consider all zero-delimited fields of the buffer.
+ const char* field = ueventData->buf;
+ const char* end = ueventData->buf + ueventData->len + 1;
+ do {
+ if (strstr(field, matchName)) {
+ HWC_LOGEB("Matched uevent message with pattern: %s", matchName);
+ matched = true;
+ }
+ //SWITCH_STATE=1, SWITCH_NAME=hdmi
+ else if (strstr(field, "SWITCH_STATE=")) {
+ strcpy(ueventData->state, field + strlen("SWITCH_STATE="));
+ }
+ else if (strstr(field, "SWITCH_NAME=")) {
+ strcpy(ueventData->name, field + strlen("SWITCH_NAME="));
+ }
+ field += strlen(field) + 1;
+ } while (field != end);
+
+ return matched;
+}
+
+static bool chk_external_conect() {
+#ifdef SIMULATE_HOT_PLUG
+ HWC_LOGDA("Simulate hot plug");
+ return chk_bool_prop("debug.connect_external");
+#else
+ //TODO:need to check hotplug callback for different device.
+ //Should consider different device.
+ return chk_bool_prop("sys.sf.hotplug");
+#endif
+}
+
+static void *hwc_hotplug_thread(void *data) {
+ struct hwc_context_1_t* ctx = (struct hwc_context_1_t*)data;
+ bool fpsChanged = false, sizeChanged = false;
+ //use uevent instead of usleep, because it has some delay
+ hwc_uevent_data_t u_data;
+ memset(&u_data, 0, sizeof(hwc_uevent_data_t));
+ int fd = uevent_init();
+
+ while (fd > 0) {
+ if (ctx->procs) {
+ fpsChanged = false;
+ sizeChanged = false;
+ u_data.len= uevent_next_event(u_data.buf, sizeof(u_data.buf) - 1);
+ if (u_data.len <= 0)
+ continue;
+
+ u_data.buf[u_data.len] = '\0';
+#if 0
+ //change@/devices/virtual/switch/hdmi ACTION=change DEVPATH=/devices/virtual/switch/hdmi
+ //SUBSYSTEM=switch SWITCH_NAME=hdmi SWITCH_STATE=0 SEQNUM=2791
+ char printBuf[1024] = {0};
+ memcpy(printBuf, u_data.buf, u_data.len);
+ for (int i = 0; i < u_data.len; i++) {
+ if (printBuf[i] == 0x0)
+ printBuf[i] = ' ';
+ }
+ HWC_LOGEB("Received uevent message: %s", printBuf);
+#endif
+ if (isMatch(&u_data, HDMI_UEVENT)) {
+ //HWC_LOGEB("HDMI switch_state: %s switch_name: %s\n", u_data.state, u_data.name);
+ if ((!strcmp(u_data.name, "hdmi_audio")) &&
+ (!strcmp(u_data.state, "1"))) {
+ // update vsync period if neccessry
+ nsecs_t newperiod = chk_output_mode(ctx->mode);
+ // check if vsync period is changed
+ if (newperiod > 0 && newperiod != ctx->vsync_period) {
+ ctx->vsync_period = newperiod;
+ fpsChanged = true;
+ }
+ sizeChanged = chk_vinfo(ctx, HWC_DISPLAY_PRIMARY);
+ if (fpsChanged || sizeChanged) {
+ ctx->procs->hotplug(ctx->procs, HWC_DISPLAY_PRIMARY, 1);
+ }
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+//#endif
+
+static void hwc_registerProcs(hwc_composer_device_1 *dev,
+ hwc_procs_t const* procs) {
+ struct hwc_context_1_t* ctx = (struct hwc_context_1_t*)dev;
+
+ if (ctx) ctx->procs = procs;
+}
+
+static int hwc_getDisplayConfigs(hwc_composer_device_1_t *dev,
+ int disp ,uint32_t *config ,size_t *numConfigs) {
+ struct hwc_context_1_t* ctx = (struct hwc_context_1_t*)dev;
+
+ if (*numConfigs == 0) return 0;
+
+ LOG_FUNCTION_NAME
+
+ get_display_info(ctx,disp);
+
+ if (disp == HWC_DISPLAY_PRIMARY) {
+ config[0] = 0;
+ *numConfigs = 1;
+ return 0;
+ } else if (disp == HWC_DISPLAY_EXTERNAL) {
+ HWC_LOGEB("hwc_getDisplayConfigs:connect = %d",display_ctx->connected);
+ if (!display_ctx->connected) return -EINVAL;
+
+ config[0] = 0;
+ *numConfigs = 1;
+ return 0;
+ }
+
+ LOG_FUNCTION_NAME_EXIT
+ return -EINVAL;
+}
+
+static int hwc_getDisplayAttributes(hwc_composer_device_1_t *dev,
+ int disp, uint32_t, const uint32_t *attributes, int32_t *values) {
+ struct hwc_context_1_t* ctx = (struct hwc_context_1_t*)dev;
+
+ LOG_FUNCTION_NAME
+
+ get_display_info(ctx,disp);
+
+ for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
+ switch (attributes[i]) {
+ case HWC_DISPLAY_VSYNC_PERIOD:
+ values[i] = ctx->vsync_period;
+ break;
+ case HWC_DISPLAY_WIDTH:
+ values[i] = fbinfo->info.xres;
+ break;
+ case HWC_DISPLAY_HEIGHT:
+ values[i] = fbinfo->info.yres;
+ break;
+ case HWC_DISPLAY_DPI_X:
+ values[i] = fbinfo->xdpi*1000;
+ break;
+ case HWC_DISPLAY_DPI_Y:
+ values[i] = fbinfo->ydpi*1000;
+ break;
+ default:
+ HWC_LOGEB("unknown display attribute %u", attributes[i]);
+ values[i] = -EINVAL;
+ break;
+ }
+ }
+
+ LOG_FUNCTION_NAME_EXIT
+
+ return 0;
+}
+
+
+static int hwc_getActiveConfig(struct hwc_composer_device_1*, int) {
+ LOG_FUNCTION_NAME
+ //TODO:
+ LOG_FUNCTION_NAME_EXIT
+ return 0;
+}
+
+static int hwc_setActiveConfig(struct hwc_composer_device_1*, int, int) {
+ LOG_FUNCTION_NAME
+ //TODO:
+ LOG_FUNCTION_NAME_EXIT
+ return 0;
+}
+
+static int hwc_setCursorPositionAsync(struct hwc_composer_device_1 *dev, int disp,
+ int x_pos, int y_pos) {
+ LOG_FUNCTION_NAME
+
+#ifdef ENABLE_CURSOR_LAYER
+ if (disp == HWC_DISPLAY_PRIMARY) {
+ int err = 0, i = 0;
+ struct fb_cursor cinfo;
+ struct hwc_context_1_t* ctx = (struct hwc_context_1_t*)dev;
+ cursor_context_t * cursor_ctx = &(ctx->display_ctxs[disp].cursor_ctx);
+ framebuffer_info_t* cbinfo = &(cursor_ctx->cb_info);
+
+ if (cbinfo->fd < 0) {
+ HWC_LOGEB("hwc_setCursorPositionAsync fd=%d", cbinfo->fd );
+ }else {
+ cinfo.hot.x = x_pos;
+ cinfo.hot.y = y_pos;
+ // if (disp == HWC_DISPLAY_PRIMARY) {
+ HWC_LOGDB("hwc_setCursorPositionAsync x_pos=%d, y_pos=%d", cinfo.hot.x, cinfo.hot.y);
+ ioctl(cbinfo->fd, FBIO_CURSOR, &cinfo);
+ /*} else if(disp == HWC_DISPLAY_EXTERNAL) {
+ // TODO:
+ HWC_LOGDA("hwc_setCursorPositionAsync external display need show cursor too! ");
+ //ioctl(cbinfo->fd, FBIO_CURSOR, &cinfo);
+ }*/
+ }
+ } else {
+ HWC_LOGEA("It is not a primary display should not come in here!");
+ }
+#endif
+
+ LOG_FUNCTION_NAME_EXIT
+ return 0;
+}
+
+
+static int hwc_device_open(const struct hw_module_t* module, const char* name,
+ struct hw_device_t** device) {
+ int ret;
+
+ if (strcmp(name, HWC_HARDWARE_COMPOSER)) return -EINVAL;
+
+ struct hwc_context_1_t *dev;
+ dev = (struct hwc_context_1_t *)malloc(sizeof(*dev));
+ memset(dev, 0, sizeof(*dev));
+
+ if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
+ (const struct hw_module_t **)&dev->gralloc_module)) {
+ HWC_LOGEA("failed to get gralloc hw module");
+ ret = -EINVAL;
+ goto err_get_module;
+ }
+
+ //init primiary display
+ //default is alwasy false,will check it in hot plug.
+ init_display(dev,HWC_DISPLAY_PRIMARY);
+
+ // willchanged to use hw vsync.
+ dev->vsync_period = chk_output_mode(dev->mode);
+
+ dev->base.common.tag = HARDWARE_DEVICE_TAG;
+ dev->base.common.version = HWC_DEVICE_API_VERSION_1_4;
+ dev->base.common.module = const_cast<hw_module_t *>(module);
+ dev->base.common.close = hwc_close;
+
+ dev->base.prepare = hwc_prepare;
+ dev->base.set = hwc_set;
+ dev->base.eventControl = hwc_eventControl;
+ //++hwc 1.4 abandon api
+ dev->base.blank = hwc_blank;
+ //--hwc 1.4 abandon api
+ dev->base.query = hwc_query;
+ dev->base.registerProcs = hwc_registerProcs;
+
+ dev->base.dump = hwc_dump;
+ dev->base.getDisplayConfigs = hwc_getDisplayConfigs;
+ dev->base.getDisplayAttributes = hwc_getDisplayAttributes;
+ //++hwc 1.4 new apis
+ dev->base.setPowerMode = hwc_setPowerMode;
+ dev->base.getActiveConfig = hwc_getActiveConfig;
+ dev->base.setActiveConfig = hwc_setActiveConfig;
+ dev->base.setCursorPositionAsync = hwc_setCursorPositionAsync;
+ //--hwc 1.4 new apis
+ dev->vsync_enable = false;
+ dev->blank_status = false;
+ *device = &dev->base.common;
+
+ ret = pthread_create(&dev->vsync_thread, NULL, hwc_vsync_thread, dev);
+ if (ret) {
+ HWC_LOGEB("failed to start vsync thread: %s", strerror(ret));
+ ret = -ret;
+ goto err_vsync;
+ }
+
+//#ifdef WITH_EXTERNAL_DISPLAY
+ //temp solution, will change to use uevnet from kernel
+ ret = pthread_create(&dev->hotplug_thread, NULL, hwc_hotplug_thread, dev);
+ if (ret) {
+ HWC_LOGEB("failed to start hotplug thread: %s", strerror(ret));
+ ret = -ret;
+ goto err_vsync;
+ }
+//#endif
+
+ return 0;
+
+err_vsync:
+ uninit_display(dev,HWC_DISPLAY_PRIMARY);
+err_get_module:
+ if (dev) free(dev);
+
+ return ret;
+}
+
+/*
+Operater of framebuffer
+*/
+int init_display(hwc_context_1_t* context,int displayType) {
+ get_display_info(context, displayType);
+
+ if (display_ctx->connected) return 0;
+
+ pthread_mutex_lock(&hwc_mutex);
+
+ if ( !display_ctx->fb_hnd ) {
+ //init information from osd.
+ fbinfo->displayType = displayType;
+ fbinfo->fbIdx = getOsdIdx(fbinfo->displayType);
+ int err = init_frame_buffer_locked(fbinfo);
+ int bufferSize = fbinfo->finfo.line_length * fbinfo->info.yres;
+ HWC_LOGDB("init_frame_buffer get fbinfo->fbIdx (%d) fbinfo->info.xres (%d) fbinfo->info.yres (%d)",fbinfo->fbIdx, fbinfo->info.xres,fbinfo->info.yres);
+ int usage = 0;
+ if (displayType > 0) usage |= GRALLOC_USAGE_EXTERNAL_DISP;
+
+ //Register the framebuffer to gralloc module
+ display_ctx->fb_hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, usage, fbinfo->fbSize, 0,
+ 0, fbinfo->fd, bufferSize, 0);
+ context->gralloc_module->base.registerBuffer(&(context->gralloc_module->base),display_ctx->fb_hnd);
+ HWC_LOGDB("init_frame_buffer get frame size %d usage %d",bufferSize,usage);
+ }
+
+ display_ctx->connected = true;
+ pthread_mutex_unlock(&hwc_mutex);
+
+#ifdef ENABLE_CURSOR_LAYER
+ if (displayType == HWC_DISPLAY_PRIMARY) {
+ // init cursor framebuffer
+ cursor_context_t* cursor_ctx = &(display_ctx->cursor_ctx);
+ cursor_ctx->show = false;
+ framebuffer_info_t* cbinfo = &(cursor_ctx->cb_info);
+ cbinfo->fd = -1;
+
+ //init information from cursor framebuffer.
+ cbinfo->fbIdx = displayType*2+1;
+ if (1 != cbinfo->fbIdx && 3 != cbinfo->fbIdx) {
+ HWC_LOGEB("invalid fb index: %d, need to check!",cbinfo->fbIdx);
+ return 0;
+ }
+ int err = init_cursor_buffer_locked(cbinfo);
+ if (err != 0) {
+ HWC_LOGEA("init_cursor_buffer_locked failed, need to check!");
+ return 0;
+ }
+ HWC_LOGDB("init_cursor_buffer get cbinfo->fbIdx (%d) cbinfo->info.xres (%d) cbinfo->info.yres (%d)",
+ cbinfo->fbIdx,
+ cbinfo->info.xres,
+ cbinfo->info.yres);
+
+ if ( cbinfo->fd >= 0) {
+ HWC_LOGDA("init_cursor_buffer success!");
+ }else{
+ HWC_LOGEA("init_cursor_buffer fail!");
+ }
+ }
+#endif
+
+
+ return 0;
+}
+
+int uninit_display(hwc_context_1_t* context, int displayType) {
+ get_display_info(context, displayType);
+
+ if (!display_ctx->connected) {
+ return 0;
+ }
+
+ pthread_mutex_lock(&hwc_mutex);
+ display_ctx->connected = false;
+ pthread_mutex_unlock(&hwc_mutex);
+
+ return 0;
+}
+
diff --git a/hwc2/common/base/Hwcomposer.cpp b/hwc2/common/base/Hwcomposer.cpp
index ca8bcc9..65040d3 100644
--- a/hwc2/common/base/Hwcomposer.cpp
+++ b/hwc2/common/base/Hwcomposer.cpp
@@ -929,7 +929,7 @@ bool Hwcomposer::initialize(private_module_t *grallocModule) {
IDisplayDevice *device = mPlatFactory->createDisplayDevice(i);
if (!device || !device->initialize()) {
DEINIT_AND_DELETE_OBJ(device);
- ETRACE("failed to create device %d", i);
+ WTRACE("failed to create device %d", i);
}
// add this device
DTRACE("HWC devices initialize device is %p at %d", device, i);
diff --git a/hwc2/common/devices/PhysicalDevice.cpp b/hwc2/common/devices/PhysicalDevice.cpp
index 451a442..b7015e8 100644
--- a/hwc2/common/devices/PhysicalDevice.cpp
+++ b/hwc2/common/devices/PhysicalDevice.cpp
@@ -731,7 +731,7 @@ int32_t PhysicalDevice::initDisplay() {
ETRACE("init_cursor_buffer_locked failed, need to check!");
return 0;
}
- ETRACE("init_cursor_buffer get cbinfo->fbIdx (%d) "
+ ITRACE("init_cursor_buffer get cbinfo->fbIdx (%d) "
"cbinfo->info.xres (%d) cbinfo->info.yres (%d)",
cbinfo->fbIdx,
cbinfo->info.xres,
diff --git a/hwc2/platforms/PlatFactory.cpp b/hwc2/platforms/PlatFactory.cpp
index 5eb0b76..f5dda2f 100644
--- a/hwc2/platforms/PlatFactory.cpp
+++ b/hwc2/platforms/PlatFactory.cpp
@@ -39,7 +39,7 @@ IDisplayDevice* PlatFactory::createDisplayDevice(int disp)
case IDisplayDevice::DEVICE_EXTERNAL:
// return new ExternalDevice(hwc, new PlatDeviceControlFactory());
default:
- ETRACE("invalid display device %d", disp);
+ WTRACE("invalid display device %d", disp);
return NULL;
}
}
diff --git a/hwc2_old/hwcomposer.cpp b/hwc2_old/hwcomposer.cpp
deleted file mode 100644
index 3bd08b7..0000000
--- a/hwc2_old/hwcomposer.cpp
+++ b/dev/null
@@ -1,3283 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "HWComposer2"
-#include <hardware/hardware.h>
-
-#include <fcntl.h>
-#include <math.h>
-#include <poll.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <inttypes.h>
-#include <stdint.h>
-
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <sys/resource.h>
-
-#define HWC_REMOVE_DEPRECATED_VERSIONS 1
-
-#include <cutils/compiler.h>
-#include <cutils/log.h>
-#include <cutils/atomic.h>
-#include <cutils/properties.h>
-
-#include <utils/String8.h>
-#include <hardware/gralloc.h>
-#include <hardware/hwcomposer2.h>
-#include <hardware_legacy/uevent.h>
-#include <utils/String8.h>
-
-#include <EGL/egl.h>
-#include <utils/Vector.h>
-#include <utils/Timers.h>
-#include <system/graphics.h>
-#include <sync/sync.h>
-// for private_handle_t
-#include <gralloc_priv.h>
-#include <gralloc_helper.h>
-
-#if WITH_LIBPLAYER_MODULE
-#include <Amavutils.h>
-#endif
-#include "tvp/OmxUtil.h"
-
-///Defines for debug statements - Macro LOG_TAG needs to be defined in the respective files
-#define HWC_LOGVA(str) ALOGV_IF(chk_int_prop("sys.hwc.debuglevel") >=6,"%5d %s - " str, __LINE__,__FUNCTION__);
-#define HWC_LOGVB(str,...) ALOGV_IF(chk_int_prop("sys.hwc.debuglevel") >=6,"%5d %s - " str, __LINE__, __FUNCTION__, __VA_ARGS__);
-#define HWC_LOGDA(str) ALOGD_IF(chk_int_prop("sys.hwc.debuglevel") >=5,"%5d %s - " str, __LINE__,__FUNCTION__);
-#define HWC_LOGDB(str, ...) ALOGD_IF(chk_int_prop("sys.hwc.debuglevel") >=5,"%5d %s - " str, __LINE__, __FUNCTION__, __VA_ARGS__);
-#define HWC_LOGIA(str) ALOGI_IF(chk_int_prop("sys.hwc.debuglevel") >=4,"%5d %s - " str, __LINE__, __FUNCTION__);
-#define HWC_LOGIB(str, ...) ALOGI_IF(chk_int_prop("sys.hwc.debuglevel") >=4,"%5d %s - " str, __LINE__,__FUNCTION__, __VA_ARGS__);
-#define HWC_LOGWA(str) ALOGW_IF(chk_int_prop("sys.hwc.debuglevel") >=3,"%5d %s - " str, __LINE__, __FUNCTION__);
-#define HWC_LOGWB(str, ...) ALOGW_IF(chk_int_prop("sys.hwc.debuglevel") >=3,"%5d %s - " str, __LINE__,__FUNCTION__, __VA_ARGS__);
-#define HWC_LOGEA(str) ALOGE_IF(chk_int_prop("sys.hwc.debuglevel") >=2,"%5d %s - " str, __LINE__, __FUNCTION__);
-#define HWC_LOGEB(str, ...) ALOGE_IF(chk_int_prop("sys.hwc.debuglevel") >=2,"%5d %s - " str, __LINE__,__FUNCTION__, __VA_ARGS__);
-
-#define LOG_FUNCTION_NAME HWC_LOGVA("ENTER");
-#define LOG_FUNCTION_NAME_EXIT HWC_LOGVA("EXIT");
-#define DBG_LOGA(str) ALOGI_IF(chk_int_prop("sys.hwc.debuglevel") >=4,"%10s-%5d %s - " str, HWC_BUILD_NAME, __LINE__,__FUNCTION__)
-#define DBG_LOGB(str, ...) ALOGI_IF(chk_int_prop("sys.hwc.debuglevel") >=4,"%10s-%5d %s - " str, HWC_BUILD_NAME, __LINE__,__FUNCTION__, __VA_ARGS__);
-
-#define SYSFS_AMVIDEO_CURIDX "/sys/module/amvideo/parameters/cur_dev_idx"
-#define SYSFS_DISPLAY_MODE "/sys/class/display/mode"
-#define SYSFS_FB0_FREE_SCALE "/sys/class/graphics/fb0/free_scale"
-#define SYSFS_FB1_FREE_SCALE "/sys/class/graphics/fb0/free_scale"
-#define SYSFS_VIDEO_AXIS "/sys/class/video/axis"
-#define SYSFS_VIDEOBUFUSED "/sys/class/amstream/videobufused"
-#define SYSFS_WINDOW_AXIS "/sys/class/graphics/fb0/window_axis"
-
-#define MAX_SUPPORT_DISPLAYS HWC_NUM_DISPLAY_TYPES
-
-#ifdef SINGLE_EXTERNAL_DISPLAY_USE_FB1
-#undef ENABLE_CURSOR_LAYER
-#define CHK_SKIP_DISPLAY_FB0(dispIdx) \
- if (pdev->displays[HWC_DISPLAY_EXTERNAL].connected\
- && dispIdx == HWC_DISPLAY_PRIMARY) {\
- continue;\
- }
-#else
-#define ENABLE_CURSOR_LAYER 1 //cursor layer supported in hwc 1.4
-#define CHK_SKIP_DISPLAY_FB0(dispIdx) //nothing to do
-#endif
-
-// hwc2
-#define isValidDisplay(dpyContext, displayId) \
- if (displayId > HWC_DISPLAY_VIRTUAL || displayId < HWC_DISPLAY_PRIMARY) \
- { \
- HWC_LOGEB("Bad Display: %d", static_cast<int32_t>(displayId)); \
- return HWC2_ERROR_BAD_DISPLAY; \
- } else { \
- if (!dpyContext || (dpyContext && !dpyContext->connected)) return HWC2_ERROR_BAD_DISPLAY; \
- }
-
-typedef struct hwc2_module {
- /**
- * Common methods of the hardware composer module. This *must* be the first member of
- * hwc_module as users of this structure will cast a hw_module_t to
- * hwc_module pointer in contexts where it's known the hw_module_t references a
- * hwc_module.
- */
- struct hw_module_t common;
-} hwc2_module_t;
-
-typedef struct cursor_context_t{
- bool blank;
- struct framebuffer_info_t cb_info;
- void *cbuffer;
- bool show;
-}cursor_context_t;
-
-
-typedef struct hwc2_hotplug_cb {
- hwc2_callback_data_t callbackData;
- void (*hotplug)(hwc2_callback_data_t callbackData, hwc2_display_t displayId, int32_t intConnected);
-} hwc2_hotplug_cb_t;
-
-
-typedef struct hwc2_refresh_cb {
- hwc2_callback_data_t callbackData;
- void (*refresh)(hwc2_callback_data_t callbackData, hwc2_display_t displayId);
-} hwc2_refresh_cb_t;
-
-
-typedef struct hwc2_vsync_cb {
- hwc2_callback_data_t callbackData;
- void (*vsync)(hwc2_callback_data_t callbackData, hwc2_display_t displayId, int64_t timestamp);
-} hwc2_vsync_cb_t;
-
-
-// layer's number.
-#define HWC2_MAX_LAYERS 32
-#define HWC2_MAX_OVERLAY_LAYERS 5
-
-typedef struct hwc_layer {
- // layer contents
- union {
- buffer_handle_t buf_hnd;
-
- /* When compositionType is HWC_SIDEBAND, this is the handle
- * of the sideband video stream to compose. */
- const native_handle_t* sideband_stream;
- };
- int32_t layer_acquirefence;
- hwc_region_t demage_region;
-
- // layer state
- hwc2_blend_mode_t blend_mode;
- hwc2_composition_t clt_cmptype;
- hwc2_composition_t dev_cmptype;
- int32_t /*android_dataspace_t*/ dataspace;
- hwc_color_t color;
- hwc_rect_t display_frame;
- float alpha;
- //native_handle_t *sideband_stream;
- hwc_frect_t source_crop;
- hwc_transform_t transform;
- hwc_region_t visible_region;
- uint32_t zorder;
-} hwc_layer_t;
-
-
-typedef struct display_context {
- struct framebuffer_info_t fb_info;
- struct private_handle_t* fb_hnd;
-#ifdef ENABLE_CURSOR_LAYER
- struct cursor_context_t cursor_ctx;
-#endif
-
- bool connected;
-
- int32_t /*android_color_mode_t*/ color_mode;
-
- // client target layer.
- buffer_handle_t clnt_tgrhnd;
- hwc_region_t clnt_tgrdmge;
- int32_t tgr_acqfence;
-
- // num of composition type changed layer.
- uint32_t num_chgtyps;
- uint32_t num_lyrreqs;
-
- // bool validated;
-
- // vsync
- bool vsync_enable;
- int32_t vsync_period;
-
- // layer
- hwc2_layer_t types_layer[HWC2_MAX_OVERLAY_LAYERS];
- hwc2_layer_t requests_layer[HWC2_MAX_OVERLAY_LAYERS];
- hwc_layer_t* hwc_layer[HWC2_MAX_LAYERS];
-
- // virtual display.
- buffer_handle_t virhnd;
- int32_t vir_relfence;
- uint32_t width;
- uint32_t height;
- android_pixel_format_t format;
-} display_context_t;
-
-
-typedef struct hwc2_context {
- hwc2_device base;
-
- /* our private state goes below here */
- hwc_layer_t const* saved_layer;
- unsigned saved_transform;
- int32_t saved_left;
- int32_t saved_top;
- int32_t saved_right;
- int32_t saved_bottom;
-
- bool blank_status;
-
- // video buf is used flag
- char video_buf_used[32];
- // hdmi output mode
- char mode[32];
-
- // vsync
- pthread_t primary_vsync_thread;
- pthread_t external_vsync_thread;
- const hwc2_vsync_cb_t vsync_cb;
-
- const hwc2_hotplug_cb_t hotplug_cb;
- const hwc2_refresh_cb_t refresh_cb;
- pthread_t hotplug_thread;
-
- private_module_t *gralloc_module;
- display_context_t displays[MAX_SUPPORT_DISPLAYS];
-}hwc2_context_t;
-
-
-typedef struct hwc_uevent_data {
- int32_t len;
- char buf[1024];
- char name[128];
- char state[128];
-} hwc_uevent_data_t;
-
-
-static pthread_cond_t hwc_cond[HWC_NUM_PHYSICAL_DISPLAY_TYPES] = {PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER};
-static pthread_mutex_t hwc_mutex[HWC_NUM_PHYSICAL_DISPLAY_TYPES] = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER};
-
-extern "C" int32_t clock_nanosleep(clockid_t clock_id, int32_t flags,
- const struct timespec *request, struct timespec *remain);
-
-static bool chk_bool_prop(const char* prop) {
- char val[PROPERTY_VALUE_MAX];
-
- memset(val, 0, sizeof(val));
- if (property_get(prop, val, "false") && strcmp(val, "true") == 0) {
- ALOGD("prop: %s is %s",prop, val);
- return true;
- }
-
- return false;
-}
-
-static int32_t chk_int_prop(const char* prop) {
- char val[PROPERTY_VALUE_MAX];
-
- memset(val, 0, sizeof(val));
- if (property_get(prop, val, "2")) {
- //ALOGV("prop: %s is %s",prop, val);
- return atoi(val);
- }
- return 0;
-}
-
-static int32_t chk_and_dup(int32_t fence) {
- if (fence < 0) {
- HWC_LOGWB("not a vliad fence %d",fence);
- return -1;
- }
-
- int32_t dup_fence = dup(fence);
- if (dup_fence < 0) {
- HWC_LOGWB("fence dup failed: %s", strerror(errno));
- }
-
- return dup_fence;
-}
-
-#if WITH_LIBPLAYER_MODULE
-static bool chk_sysfs_status(const char* sysfstr, char* lastr, int32_t size) {
- char val[32];
- char *p = lastr;
-
- memset(val, 0, sizeof(val));
- if (amsysfs_get_sysfs_str(sysfstr, val, sizeof(val)) == 0) {
- HWC_LOGVB("val: %s, lastr: %s",val, p);
- if ((strcmp(val, p) != 0)) {
- memset(p, 0, size);
- strcpy(p, val);
- return true;
- }
- }
-
- return false;
-}
-#endif
-
-static int32_t chk_output_mode(char* curmode) {
- int32_t modefd = open(SYSFS_DISPLAY_MODE, O_RDONLY);
- if (modefd < 0) {
- HWC_LOGEB("open (%s) fail", SYSFS_DISPLAY_MODE);
- return -1;
- }
-
- char outputmode[32] = {0};
- read(modefd, outputmode, 31);
- close(modefd);
- modefd = -1;
-
- //check if need update vsync.
- if (strcmp(outputmode, curmode) == 0) {
- HWC_LOGVB("outputmode didn't change %s", curmode);
- return 0;
- }
-
- strcpy(curmode, outputmode);
-
- int32_t period = 16666666;
- if (strstr(outputmode, "50hz") != NULL) {
- period = (int32_t)(1e9 / 50);
- } else if (strstr(outputmode, "30hz") != NULL) {
- period = (int32_t)(1e9 / 30);
- } else if (strstr(outputmode, "25hz") != NULL) {
- period = (int32_t)(1e9 / 25);
- } else if ((strstr(outputmode, "24hz") != NULL) || (strstr(outputmode, "smpte") != NULL)) {
- period = (int32_t)(1e9 / 24);
- } else
- HWC_LOGDB("displaymode (%s) doesn't specify HZ", curmode);
-
- HWC_LOGVB("get new outputmode (%s) new period (%ld)", curmode, period);
- return period;
-}
-
-static bool chk_vinfo(hwc2_context_t* context, int32_t disp) {
- display_context_t *dctx = &(context->displays[disp]);
- isValidDisplay(dctx, disp);
-
- struct framebuffer_info_t *fbinfo = &(dctx->fb_info);
-
- if (fbinfo != NULL && fbinfo->fd >= 0) {
- struct fb_var_screeninfo vinfo;
- if (ioctl(fbinfo->fd, FBIOGET_VSCREENINFO, &vinfo) == -1)
- {
- ALOGE("FBIOGET_VSCREENINFO error!!!");
- return -errno;
- }
-
- if (vinfo.xres != fbinfo->info.xres
- || vinfo.yres != fbinfo->info.yres
- || vinfo.width != fbinfo->info.width
- || vinfo.height != fbinfo->info.height) {
- if (int32_t(vinfo.width) <= 16 || int32_t(vinfo.height) <= 9) {
- // the driver doesn't return that information
- // default to 160 dpi
- vinfo.width = ((vinfo.xres * 25.4f)/160.0f + 0.5f);
- vinfo.height = ((vinfo.yres * 25.4f)/160.0f + 0.5f);
- }
- fbinfo->xdpi = (vinfo.xres * 25.4f) / vinfo.width;
- fbinfo->ydpi = (vinfo.yres * 25.4f) / vinfo.height;
-
- fbinfo->info.xres = vinfo.xres;
- fbinfo->info.yres = vinfo.yres;
- fbinfo->info.width = vinfo.width;
- fbinfo->info.height = vinfo.height;
-
- return true;
- }
- }
- return false;
-}
-
-/*
-Operater of framebuffer
-*/
-int32_t init_display(hwc2_context_t* context, int32_t displayId) {
- display_context_t *dctx = &(context->displays[displayId]);
-
- struct framebuffer_info_t *fbinfo = &(dctx->fb_info);
-
- if (dctx->connected) return 0;
-
- pthread_mutex_lock(&hwc_mutex[displayId]);
-
- if ( !dctx->fb_hnd ) {
- //init information from osd.
- fbinfo->displayType = displayId;
- fbinfo->fbIdx = getOsdIdx(displayId);
- int32_t err = init_frame_buffer_locked(fbinfo);
- int32_t bufferSize = fbinfo->finfo.line_length
- * fbinfo->info.yres;
- HWC_LOGDB("init_frame_buffer get fbinfo->fbIdx (%d) "
- "fbinfo->info.xres (%d) fbinfo->info.yres (%d)",
- fbinfo->fbIdx, fbinfo->info.xres,
- fbinfo->info.yres);
- int32_t usage = 0;
- if (displayId == HWC_DISPLAY_PRIMARY) {
- context->gralloc_module->fb_primary.fb_info = *(fbinfo);
- } else if (displayId == HWC_DISPLAY_EXTERNAL) {
- context->gralloc_module->fb_external.fb_info = *(fbinfo);
- usage |= GRALLOC_USAGE_EXTERNAL_DISP;
- }
-
- //Register the framebuffer to gralloc module
- dctx->fb_hnd = new private_handle_t(
- private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
- usage, fbinfo->fbSize, 0,
- 0, fbinfo->fd, bufferSize, 0);
- context->gralloc_module->base.registerBuffer(
- &(context->gralloc_module->base),
- dctx->fb_hnd);
- HWC_LOGDB("init_frame_buffer get frame size %d usage %d",
- bufferSize,usage);
-
- }
-
- dctx->connected = true;
- pthread_mutex_unlock(&hwc_mutex[displayId]);
-
-#ifdef ENABLE_CURSOR_LAYER
- // init cursor framebuffer
- cursor_context_t* cursor_ctx = &(dctx->cursor_ctx);
- cursor_ctx->show = false;
- framebuffer_info_t* cbinfo = &(cursor_ctx->cb_info);
- cbinfo->fd = -1;
-
- //init information from cursor framebuffer.
- cbinfo->fbIdx = displayId*2+1;
- if (1 != cbinfo->fbIdx && 3 != cbinfo->fbIdx) {
- HWC_LOGEB("invalid fb index: %d, need to check!",
- cbinfo->fbIdx);
- return 0;
- }
- int32_t err = init_cursor_buffer_locked(cbinfo);
- if (err != 0) {
- HWC_LOGEA("init_cursor_buffer_locked failed, need to check!");
- return 0;
- }
- HWC_LOGDB("init_cursor_buffer get cbinfo->fbIdx (%d) "
- "cbinfo->info.xres (%d) cbinfo->info.yres (%d)",
- cbinfo->fbIdx,
- cbinfo->info.xres,
- cbinfo->info.yres);
-
- if ( cbinfo->fd >= 0) {
- HWC_LOGDA("init_cursor_buffer success!");
- }else{
- HWC_LOGEA("init_cursor_buffer fail!");
- }
-#endif
-
- return 0;
-}
-
-int32_t uninit_display(hwc2_context_t* context, int32_t displayId) {
- hwc2_context_t *ctx = (hwc2_context_t*)context;
- display_context_t *dctx = &(ctx->displays[displayId]);
-
- if (!dctx->connected) return 0;
-
- pthread_mutex_lock(&hwc_mutex[displayId]);
- dctx->connected = false;
- pthread_mutex_unlock(&hwc_mutex[displayId]);
-
- return 0;
-}
-
-static void hwc2_overlay_compose(
- hwc2_context_t* context, hwc2_display_t displayId,
- hwc_layer_t const* l) {
- display_context_t *dctx = &(context->displays[displayId]);
- int32_t angle = 0;
-
-#if WITH_LIBPLAYER_MODULE
- static char last_val[32] = "0";
- static char last_axis[32] = "0";
- static char last_mode[32] = {0};
- static char last_free_scale[32] = {0};
- static char last_window_axis[50] = {0};
- bool vpp_changed = false;
- bool axis_changed = false;
- bool mode_changed = false;
- bool free_scale_changed = false;
- bool window_axis_changed =false;
-
- if (chk_bool_prop("ro.vout.dualdisplay4")) {
- vpp_changed = chk_sysfs_status(
- SYSFS_AMVIDEO_CURIDX,last_val, 32);
- }
-
- mode_changed = chk_sysfs_status(SYSFS_DISPLAY_MODE, last_mode, 32);
-
- free_scale_changed = chk_sysfs_status(SYSFS_FB0_FREE_SCALE, last_free_scale, 32);
-#ifdef SINGLE_EXTERNAL_DISPLAY_USE_FB1
- if (dctx->connected)
- free_scale_changed = chk_sysfs_status(SYSFS_FB1_FREE_SCALE, last_free_scale, 32);
-#endif
-
- axis_changed = chk_sysfs_status(SYSFS_VIDEO_AXIS, last_axis, 32);
- window_axis_changed = chk_sysfs_status(SYSFS_WINDOW_AXIS, last_window_axis, 50);
-
- if ((context->saved_layer == l)
- && (context->saved_transform == l->transform)
- && (context->saved_left == l->display_frame.left)
- && (context->saved_top == l->display_frame.top)
- && (context->saved_right == l->display_frame.right)
- && (context->saved_bottom == l->display_frame.bottom)
- && !vpp_changed
- && !mode_changed
- && !axis_changed
- && !free_scale_changed
- && !window_axis_changed) {
- return;
- }
-
- switch (l->transform) {
- case 0:
- angle = 0;
- break;
- case HAL_TRANSFORM_ROT_90:
- angle = 90;
- break;
- case HAL_TRANSFORM_ROT_180:
- angle = 180;
- break;
- case HAL_TRANSFORM_ROT_270:
- angle = 270;
- break;
- default:
- return;
- }
-
- amvideo_utils_set_virtual_position(
- l->display_frame.left,
- l->display_frame.top,
- l->display_frame.right - l->display_frame.left,
- l->display_frame.bottom - l->display_frame.top,
- angle);
-
- /* the screen mode from Android framework should always be set to normal mode
- * to match the relationship between the UI and video overlay window position.
- */
- /*set screen_mode in amvideo_utils_set_virtual_position(),pls check in libplayer*/
- //amvideo_utils_set_screen_mode(0);
-#endif
-
- context->saved_layer = l;
- context->saved_transform = l->transform;
- context->saved_left = l->display_frame.left;
- context->saved_top = l->display_frame.top;
- context->saved_right = l->display_frame.right;
- context->saved_bottom = l->display_frame.bottom;
-
-#if WITH_LIBPLAYER_MODULE
- memset(last_axis, 0, sizeof(last_axis));
-
- if (amsysfs_get_sysfs_str(SYSFS_VIDEO_AXIS, last_axis, sizeof(last_axis)) == 0) {
- HWC_LOGDB("****last video axis is: %s",last_axis);
- }
-#endif
-}
-
-static int32_t hwc2_fb_post(
- hwc2_context_t *context,
- hwc2_display_t displayId,
- int32_t* outRetireFence) {
- display_context_t *dctx = &(context->displays[displayId]);
- hwc_layer_t *hwclayer = NULL;
- int32_t err = 0, i = 0;
-
- // deal physical display's client target layer
-#if ENABLE_CURSOR_LAYER
- cursor_context_t * cursor_ctx = &(dctx->cursor_ctx);
- framebuffer_info_t* cbinfo = &(cursor_ctx->cb_info);
- bool cursor_show = false;
-
- for (uint32_t i=0; i<dctx->num_lyrreqs; i++) {
- hwc2_layer_t layer = dctx->requests_layer[i];
- hwclayer = dctx->hwc_layer[layer];
- if (hwclayer && hwclayer->dev_cmptype == HWC2_COMPOSITION_CURSOR) {
- if (private_handle_t::validate(hwclayer->buf_hnd) < 0) {
- HWC_LOGEA("invalid cursor layer handle.");
- break;
- }
- private_handle_t *hnd = (private_handle_t *)hwclayer->buf_hnd;
- HWC_LOGDB("This is a Sprite, hnd->stride is %d, hnd->height is %d", hnd->stride, hnd->height);
- if (cbinfo->info.xres != (uint32_t)hnd->stride || cbinfo->info.yres != (uint32_t)hnd->height) {
- HWC_LOGEB("disp: %d cursor need to redrew", (int32_t)displayId);
- update_cursor_buffer_locked(cbinfo, hnd->stride, hnd->height);
- cursor_ctx->cbuffer = mmap(NULL, hnd->size, PROT_READ|PROT_WRITE, MAP_SHARED, cbinfo->fd, 0);
- if (cursor_ctx->cbuffer != MAP_FAILED) {
- memcpy(cursor_ctx->cbuffer, hnd->base, hnd->size);
- munmap(cursor_ctx->cbuffer, hnd->size);
- HWC_LOGDA("setCursor ok");
- } else {
- HWC_LOGEA("buffer mmap fail");
- }
- }
- cursor_show = true;
- }
- }
-#endif
-
- if (!dctx->clnt_tgrhnd) {
- HWC_LOGEA("target handle is null.");
- *outRetireFence = -1;
- return HWC2_ERROR_NONE;
- }
- if (private_handle_t::validate(dctx->clnt_tgrhnd) < 0) {
- return HWC2_ERROR_NOT_VALIDATED;
- }
-
- *outRetireFence = fb_post_with_fence_locked(&(dctx->fb_info), dctx->clnt_tgrhnd, dctx->tgr_acqfence);
-
- if (*outRetireFence >= 0) {
- HWC_LOGDB("Get retire fence %d", *outRetireFence);
- } else {
- HWC_LOGEB("No valid retire returned. %d ", *outRetireFence);
- //-1 means no fence, less than -1 is some error
- if (*outRetireFence < -1) err = HWC2_ERROR_NOT_VALIDATED;
- *outRetireFence -1;
- }
-
-
-#if ENABLE_CURSOR_LAYER
- // finally we need to update cursor's blank status
- if (cbinfo->fd > 0 && (cursor_show != cursor_ctx->show) ) {
- cursor_ctx->show = cursor_show;
- HWC_LOGDB("UPDATE FB1 status to %d ",cursor_show);
- ioctl(cbinfo->fd, FBIOBLANK, !cursor_ctx->show);
- }
-#endif
-
- return err;
-}
-
-static int32_t hwc2_close(hw_device_t *device) {
- hwc2_context_t *dev = (hwc2_context_t *)device;
-
- LOG_FUNCTION_NAME
-
- pthread_kill(dev->primary_vsync_thread, SIGTERM);
- pthread_join(dev->primary_vsync_thread, NULL);
-
- pthread_kill(dev->external_vsync_thread, SIGTERM);
- pthread_join(dev->external_vsync_thread, NULL);
-
- uninit_display(dev, HWC_DISPLAY_PRIMARY);
- uninit_display(dev, HWC_DISPLAY_EXTERNAL);
-
- if (dev) free(dev);
-
- LOG_FUNCTION_NAME_EXIT
- return 0;
-}
-
-//#define USE_HW_VSYNC
-#ifdef USE_HW_VSYNC
-/*
-Still have bugs, don't use it.
-*/
-int32_t wait_next_vsync(hwc2_context_t* ctx, nsecs_t* vsync_timestamp) {
- static nsecs_t previewTime = 0;
- nsecs_t vsyncDiff=0;
- const nsecs_t period = ctx->vsync_period;
- //we will delay hw vsync if missing one vsync interrupt isr.
- int32_t ret = 0;
-
- if (ioctl(ctx->displays[0].fb_info.fd, FBIO_WAITFORVSYNC, &ret) == -1) {
- HWC_LOGEB("ioctrl error %d",ctx->displays[0].fb_info.fd);
- ret=-1;
- } else {
- if (ret == 1) {
- *vsync_timestamp = systemTime(CLOCK_MONOTONIC);
- vsyncDiff=*vsync_timestamp - previewTime;
- if (previewTime != 0) HWC_LOGEB("wait for vsync success %lld",vsyncDiff);
- vsyncDiff%=period;
- if (vsyncDiff > 500000) {
- nsecs_t sleep ;
- sleep = (period - vsyncDiff);
- *vsync_timestamp+=sleep;
- struct timespec spec;
- spec.tv_sec = *vsync_timestamp / 1000000000;
- spec.tv_nsec = *vsync_timestamp % 1000000000;
- clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
- }
- previewTime = *vsync_timestamp;
- ret=0;
- } else {
- HWC_LOGEA("wait for vsync fail");
- ret=-1;
- }
- }
- return ret;
-}
-#else
-//software
-int32_t wait_next_primary_vsync(hwc2_context_t* ctx, nsecs_t* vsync_timestamp) {
- display_context_t displayctx = ctx->displays[HWC_DISPLAY_PRIMARY];
- static nsecs_t vsync_time = 0;
- static nsecs_t old_vsync_period = 0;
- nsecs_t sleep;
- nsecs_t now = systemTime(CLOCK_MONOTONIC);
-
- //cal the last vsync time with old period
- if (displayctx.vsync_period != old_vsync_period) {
- if (old_vsync_period > 0) {
- vsync_time = vsync_time +
- ((now - vsync_time) / old_vsync_period) * old_vsync_period;
- }
- old_vsync_period = displayctx.vsync_period;
- }
-
- //set to next vsync time
- vsync_time += displayctx.vsync_period;
-
- // we missed, find where the next vsync should be
- if (vsync_time - now < 0) {
- vsync_time = now + (displayctx.vsync_period -
- ((now - vsync_time) % displayctx.vsync_period));
- }
-
- struct timespec spec;
- spec.tv_sec = vsync_time / 1000000000;
- spec.tv_nsec = vsync_time % 1000000000;
-
- int32_t err;
- do {
- err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
- } while (err<0 && errno == EINTR);
- *vsync_timestamp = vsync_time;
-
- return err;
-}
-
-int32_t wait_next_external_vsync(hwc2_context_t* ctx, nsecs_t* vsync_timestamp) {
- display_context_t displayctx = ctx->displays[HWC_DISPLAY_EXTERNAL];
- static nsecs_t vsync_time = 0;
- static nsecs_t old_vsync_period = 0;
- nsecs_t sleep;
- nsecs_t now = systemTime(CLOCK_MONOTONIC);
-
- //cal the last vsync time with old period
- if (displayctx.vsync_period != old_vsync_period) {
- if (old_vsync_period > 0) {
- vsync_time = vsync_time +
- ((now - vsync_time) / old_vsync_period) * old_vsync_period;
- }
- old_vsync_period = displayctx.vsync_period;
- }
-
- //set to next vsync time
- vsync_time += displayctx.vsync_period;
-
- // we missed, find where the next vsync should be
- if (vsync_time - now < 0) {
- vsync_time = now + (displayctx.vsync_period -
- ((now - vsync_time) % displayctx.vsync_period));
- }
-
- struct timespec spec;
- spec.tv_sec = vsync_time / 1000000000;
- spec.tv_nsec = vsync_time % 1000000000;
-
- int32_t err;
- do {
- err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
- } while (err<0 && errno == EINTR);
- *vsync_timestamp = vsync_time;
-
- return err;
-}
-
-#endif
-
-static void *hwc2_primary_vsync_thread(void *data) {
- uint32_t displayId = HWC_DISPLAY_PRIMARY;
- hwc2_context_t* ctx = (hwc2_context_t*)data;
- display_context_t *dctx = &(ctx->displays[displayId]);
- nsecs_t timestamp;
-
- setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY - 1);
- sleep(2);
-
- while (true) {
- pthread_mutex_lock(&hwc_mutex[displayId]);
- while (!dctx->vsync_enable) {
- pthread_cond_wait(&hwc_cond[displayId],
- &hwc_mutex[displayId]);
- }
- pthread_mutex_unlock(&hwc_mutex[displayId]);
-
- if (wait_next_primary_vsync(ctx, &timestamp) == 0) {
- if (ctx->vsync_cb.vsync)
- ctx->vsync_cb.vsync(ctx->vsync_cb.callbackData,
- displayId, timestamp);
- }
- }
-
- return NULL;
-}
-
-static void *hwc2_external_vsync_thread(void *data) {
- uint32_t displayId = HWC_DISPLAY_EXTERNAL;
- hwc2_context_t* ctx = (hwc2_context_t*)data;
- display_context_t *dctx = &(ctx->displays[displayId]);
- int64_t timestamp;
-
- setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY-1);
- sleep(2);
-
- while (true) {
- pthread_mutex_lock(&hwc_mutex[displayId]);
- while (!dctx->vsync_enable) {
- pthread_cond_wait(&hwc_cond[displayId],
- &hwc_mutex[displayId]);
- }
- pthread_mutex_unlock(&hwc_mutex[displayId]);
-
- if (wait_next_external_vsync(ctx, &timestamp) == 0) {
- if (dctx->connected && ctx->vsync_cb.vsync)
- ctx->vsync_cb.vsync(ctx->vsync_cb.callbackData,
- displayId, timestamp);
- }
- }
-
- return NULL;
-}
-
-//#define SIMULATE_HOT_PLUG 1
-#define HDMI_UEVENT "DEVPATH=/devices/virtual/switch/hdmi_audio"
-#define HDMI_POWER_UEVENT "DEVPATH=/devices/virtual/switch/hdmi_power"
-
-static bool isMatch(hwc_uevent_data_t* ueventData, const char* matchName) {
- bool matched = false;
- // Consider all zero-delimited fields of the buffer.
- const char* field = ueventData->buf;
- const char* end = ueventData->buf + ueventData->len + 1;
- do {
- if (!strcmp(field, matchName)) {
- HWC_LOGEB("Matched uevent message with pattern: %s", matchName);
- matched = true;
- }
- //SWITCH_STATE=1, SWITCH_NAME=hdmi
- else if (strstr(field, "SWITCH_STATE=")) {
- strcpy(ueventData->state, field + strlen("SWITCH_STATE="));
- }
- else if (strstr(field, "SWITCH_NAME=")) {
- strcpy(ueventData->name, field + strlen("SWITCH_NAME="));
- }
- field += strlen(field) + 1;
- } while (field != end);
-
- return matched;
-}
-
-#define HOTPLUG_UEVENT_DEBUG
-static void *hwc2_hotplug_thread(void *data) {
- hwc2_context_t* ctx = (hwc2_context_t*)data;
- display_context_t *dctx = &(ctx->displays[HWC_DISPLAY_PRIMARY]);
- bool fpsChanged = false, sizeChanged = false;
- //use uevent instead of usleep, because it has some delay
- hwc_uevent_data_t u_data;
- memset(&u_data, 0, sizeof(hwc_uevent_data_t));
- int32_t fd = uevent_init();
-
- while (fd > 0) {
- fpsChanged = false;
- sizeChanged = false;
- u_data.len= uevent_next_event(u_data.buf, sizeof(u_data.buf) - 1);
- if (u_data.len <= 0)
- continue;
-
- u_data.buf[u_data.len] = '\0';
-
-#ifdef HOTPLUG_UEVENT_DEBUG
- //change@/devices/virtual/switch/hdmi ACTION=change DEVPATH=/devices/virtual/switch/hdmi
- //SUBSYSTEM=switch SWITCH_NAME=hdmi SWITCH_STATE=0 SEQNUM=2791
- char printBuf[1024] = {0};
- memcpy(printBuf, u_data.buf, u_data.len);
- for (int32_t i = 0; i < u_data.len; i++) {
- if (printBuf[i] == 0x0)
- printBuf[i] = ' ';
- }
- HWC_LOGEB("Received uevent message: %s", printBuf);
-#endif
- if (isMatch(&u_data, HDMI_UEVENT)) {
- HWC_LOGEB("HDMI switch_state: %s switch_name: %s\n", u_data.state, u_data.name);
- if ((!strcmp(u_data.name, "hdmi_audio")) &&
- (!strcmp(u_data.state, "1"))) {
- // update vsync period if neccessry
- nsecs_t newperiod = chk_output_mode(ctx->mode);
- // check if vsync period is changed
- if (newperiod > 0 && newperiod != dctx->vsync_period) {
- dctx->vsync_period = newperiod;
- fpsChanged = true;
- }
- sizeChanged = chk_vinfo(ctx, HWC_DISPLAY_PRIMARY);
- if (fpsChanged || sizeChanged) {
- if (ctx->hotplug_cb.hotplug) {
- ctx->hotplug_cb.hotplug(
- ctx->hotplug_cb.callbackData,
- HWC_DISPLAY_PRIMARY, 1);
- }
- }
- }
- }
- }
-
- return NULL;
-}
-
-/*
- * Device Functions
- *
- * All of these functions take as their first parameter a device pointer, so
- * this parameter is omitted from the described parameter lists.
- */
-
-/* createVirtualDisplay(..., width, height, format, outDisplay)
- * Descriptor: HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY
- * Must be provided by all HWC2 devices
- *
- * Creates a new virtual display with the given width and height. The format
- * passed into this function is the default format requested by the consumer of
- * the virtual display output buffers. If a different format will be returned by
- * the device, it should be returned in this parameter so it can be set properly
- * when handing the buffers to the consumer.
- *
- * The display will be assumed to be on from the time the first frame is
- * presented until the display is destroyed.
- *
- * Parameters:
- * width - width in pixels
- * height - height in pixels
- * format - prior to the call, the default output buffer format selected by
- * the consumer; after the call, the format the device will produce
- * outDisplay - the newly-created virtual display; pointer will be non-NULL
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_UNSUPPORTED - the width or height is too large for the device to
- * be able to create a virtual display
- * HWC2_ERROR_NO_RESOURCES - the device is unable to create a new virtual
- * display at this time
- */
-hwc2_error_t createVirtualDisplay(
- hwc2_device_t* device, uint32_t width,
- uint32_t height, android_pixel_format_t* format,
- hwc2_display_t* outDisplay) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *vctx = &(ctx->displays[HWC_DISPLAY_VIRTUAL]);
-
- if (width > 1920 && height > 1080) {
- return HWC2_ERROR_UNSUPPORTED;
- }
-
- vctx->vir_relfence = -1;
- vctx->width = width;
- vctx->height = height;
- vctx->format = *format;
- vctx->connected = true;
-
- *outDisplay = HWC_DISPLAY_VIRTUAL;
-
- // TODO:
- return HWC2_ERROR_NONE;
-}
-
-/* destroyVirtualDisplay(..., display)
- * Descriptor: HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY
- * Must be provided by all HWC2 devices
- *
- * Destroys a virtual display. After this call all resources consumed by this
- * display may be freed by the device and any operations performed on this
- * display should fail.
- *
- * Parameters:
- * display - the virtual display to destroy
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_BAD_PARAMETER - the display handle which was passed in does not
- * refer to a virtual display
- */
-hwc2_error_t destroyVirtualDisplay(
- hwc2_device_t* device, hwc2_display_t display) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *vctx = &(ctx->displays[HWC_DISPLAY_VIRTUAL]);
-
- if (display != HWC_DISPLAY_VIRTUAL) {
- return HWC2_ERROR_BAD_PARAMETER;
- }
- vctx->connected = false;
- vctx->vir_relfence = -1;
- vctx->width = 0;
- vctx->height = 0;
- vctx->format = (android_pixel_format)0;
-
- // TODO:
- return HWC2_ERROR_NONE;
-}
-
-/* dump(..., outSize, outBuffer)
- * Descriptor: HWC2_FUNCTION_DUMP
- * Must be provided by all HWC2 devices
- *
- * Retrieves implementation-defined debug information, which will be displayed
- * during, for example, `dumpsys SurfaceFlinger`.
- *
- * If called with outBuffer == NULL, the device should store a copy of the
- * desired output and return its length in bytes in outSize. If the device
- * already has a stored copy, that copy should be purged and replaced with a
- * fresh copy.
- *
- * If called with outBuffer != NULL, the device should copy its stored version
- * of the output into outBuffer and store how many bytes of data it copied into
- * outSize. Prior to this call, the client will have populated outSize with the
- * maximum number of bytes outBuffer can hold. The device must not write more
- * than this amount into outBuffer. If the device does not currently have a
- * stored copy, then it should return 0 in outSize.
- *
- * Any data written into outBuffer need not be null-terminated.
- *
- * Parameters:
- * outSize - if outBuffer was NULL, the number of bytes needed to copy the
- * device's stored output; if outBuffer was not NULL, the number of bytes
- * written into it, which must not exceed the value stored in outSize
- * prior to the call; pointer will be non-NULL
- * outBuffer - the buffer to write the dump output into; may be NULL as
- * described above; data written into this buffer need not be
- * null-terminated
- */
-void dump(hwc2_device_t* device,
- uint32_t* outSize,
- char* outBuffer) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- int32_t numHwLayers;
-
- android::String8 result;
- if (NULL == outBuffer) {
- *outSize = 4096;
- } else {
- using namespace android;
- result.appendFormat("Hardware Composer state (version major: %d, minor: %d):\n",
- ctx->base.common.module->version_major, ctx->base.common.module->version_minor);
- for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) {
- display_context_t *dctx = &(ctx->displays[i]);
- framebuffer_info_t *fbinfo = &(dctx->fb_info);
- if (!dctx->connected)
- continue;
-
- result.appendFormat(" Display[%zd] configurations (* current):\n", i);
- result.appendFormat(" %ux%u, xdpi=%f, ydpi=%f, refresh=%" PRId64 "\n",
- fbinfo->info.xres, fbinfo->info.yres,
- fbinfo->xdpi, fbinfo->ydpi, dctx->vsync_period);
-
- for (i=0; i<HWC2_MAX_LAYERS; i++) {
- if (NULL != dctx->hwc_layer[i])
- numHwLayers++;
- }
-
- result.appendFormat(
- " numHwLayers=%zu\n",numHwLayers);
- result.append(
- " type | handle | tr | blnd | source crop (l,t,r,b) | frame \n"
- "-----------+----------+----+------+--------------------------------+------------------------\n");
- for (i=0; i<HWC2_MAX_LAYERS; i++) {
- const hwc_layer_t *hwclayer = dctx->hwc_layer[i];
- if (hwclayer) {
- int32_t type = (int32_t)hwclayer->dev_cmptype;
-
- static char const* compositionTypeName[] = {
- "UNKNOWN",
- "GLES",
- "HWC",
- "SOLID",
- "HWC_CURSOR",
- "SIDEBAND"};
- result.appendFormat(
- " %9s | %08" PRIxPTR " | %02x | %04x |%7.1f,%7.1f,%7.1f,%7.1f |%5d,%5d,%5d,%5d \n",
- compositionTypeName[type],
- intptr_t(hwclayer->buf_hnd), hwclayer->transform, hwclayer->blend_mode,
- hwclayer->source_crop.left, hwclayer->source_crop.top,
- hwclayer->source_crop.right, hwclayer->source_crop.bottom,
- hwclayer->display_frame.left, hwclayer->display_frame.top,
- hwclayer->display_frame.right, hwclayer->display_frame.bottom);
- }
- }
- }
- *outSize = 4096;
- strcpy(outBuffer, result.string());
- }
-}
-
-/* getMaxVirtualDisplayCount(...)
- * Descriptor: HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT
- * Must be provided by all HWC2 devices
- *
- * Returns the maximum number of virtual displays supported by this device
- * (which may be 0). The client will not attempt to create more than this many
- * virtual displays on this device. This number must not change for the lifetime
- * of the device.
- */
-uint32_t getMaxVirtualDisplayCount(
- hwc2_device_t* device) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
-
- // TODO:
- // we only support one virtual display for now.
- return 1;
-}
-
-/* registerCallback(..., descriptor, callbackData, pointer)
- * Descriptor: HWC2_FUNCTION_REGISTER_CALLBACK
- * Must be provided by all HWC2 devices
- *
- * Provides a callback for the device to call. All callbacks take a callbackData
- * item as the first parameter, so this value should be stored with the callback
- * for later use. The callbackData may differ from one callback to another. If
- * this function is called multiple times with the same descriptor, later
- * callbacks replace earlier ones.
- *
- * Parameters:
- * descriptor - which callback should be set
- * callBackdata - opaque data which must be passed back through the callback
- * pointer - a non-NULL function pointer corresponding to the descriptor
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_PARAMETER - descriptor was invalid
- */
-hwc2_error_t registerCallback(
- hwc2_device_t* device,
- hwc2_callback_descriptor_t descriptor,
- hwc2_callback_data_t callbackData,
- hwc2_function_pointer_t pointer) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
-
- switch (descriptor) {
- // callback functions
- case HWC2_CALLBACK_HOTPLUG:
- {
- hwc2_hotplug_cb_t cb = ctx->hotplug_cb;
- cb.callbackData = callbackData;
- cb.hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);
-
- if (cb.hotplug) {
- HWC_LOGEA("First primary hotplug!");
- cb.hotplug(cb.callbackData,
- HWC_DISPLAY_PRIMARY, 1);
- }
- break;
- }
- case HWC2_CALLBACK_REFRESH:
- {
- hwc2_refresh_cb_t cb = ctx->refresh_cb;
- cb.callbackData = callbackData;
- cb.refresh = reinterpret_cast<HWC2_PFN_REFRESH>(pointer);
- break;
- }
- case HWC2_CALLBACK_VSYNC:
- {
- hwc2_vsync_cb_t cb = ctx->vsync_cb;
- cb.callbackData = callbackData;
- cb.vsync = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
- break;
- }
- case HWC2_CALLBACK_INVALID:
- default:
- ALOGE("registerCallback bad parameter: %d", descriptor);
- return HWC2_ERROR_BAD_PARAMETER;
- }
-
- return HWC2_ERROR_NONE;
-}
-
-/*
- * Display Functions
- *
- * All of these functions take as their first two parameters a device pointer
- * and a display handle, so these parameters are omitted from the described
- * parameter lists.
- */
-
-/* acceptDisplayChanges(...)
- * Descriptor: HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES
- * Must be provided by all HWC2 devices
- *
- * Accepts the changes required by the device from the previous validateDisplay
- * call (which may be queried using getChangedCompositionTypes) and revalidates
- * the display. This function is equivalent to requesting the changed types from
- * getChangedCompositionTypes, setting those types on the corresponding layers,
- * and then calling validateDisplay again.
- *
- * After this call it must be valid to present this display. Calling this after
- * validateDisplay returns 0 changes must succeed with HWC2_ERROR_NONE, but
- * should have no other effect.
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_NOT_VALIDATED - validateDisplay has not been called
- */
-hwc2_error_t acceptDisplayChanges(
- hwc2_device_t* device, hwc2_display_t display) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- // HWC2_ERROR_NOT_VALIDATED
-
- return HWC2_ERROR_NONE;
-
-}
-
-/* createLayer(..., outLayer)
- * Descriptor: HWC2_FUNCTION_CREATE_LAYER
- * Must be provided by all HWC2 devices
- *
- * Creates a new layer on the given display.
- *
- * Parameters:
- * outLayer - the handle of the new layer; pointer will be non-NULL
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_NO_RESOURCES - the device was unable to create this layer
- */
-hwc2_error_t createLayer(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_layer_t* outLayer) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = NULL;
- uint32_t i = 0;
-
- hwclayer = (hwc_layer_t *)malloc(sizeof(hwc_layer_t));
- if (NULL == hwclayer) return HWC2_ERROR_NO_RESOURCES;
- memset(hwclayer, 0, sizeof(hwc_layer_t));
- hwclayer->layer_acquirefence = -1;
-
- for (i=0; i<HWC2_MAX_LAYERS; i++) {
- if (NULL == dctx->hwc_layer[i]) {
- dctx->hwc_layer[i] = hwclayer;
- break;
- }
- }
- if (i > HWC2_MAX_LAYERS) return HWC2_ERROR_NO_RESOURCES;
-
- *outLayer = (hwc2_layer_t)i;
- return HWC2_ERROR_NONE;
-}
-
-/* destroyLayer(..., layer)
- * Descriptor: HWC2_FUNCTION_DESTROY_LAYER
- * Must be provided by all HWC2 devices
- *
- * Destroys the given layer.
- *
- * Parameters:
- * layer - the handle of the layer to destroy
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in
- */
-hwc2_error_t destroyLayer(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_layer_t layer) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- if (NULL != dctx->hwc_layer[layer]) {
- free(dctx->hwc_layer[layer]);
- dctx->hwc_layer[layer] = NULL;
- return HWC2_ERROR_NONE;
- } else {
- return HWC2_ERROR_BAD_LAYER;
- }
-}
-
-/* getActiveConfig(..., outConfig)
- * Descriptor: HWC2_FUNCTION_GET_ACTIVE_CONFIG
- * Must be provided by all HWC2 devices
- *
- * Retrieves which display configuration is currently active.
- *
- * If no display configuration is currently active, this function must return
- * HWC2_ERROR_BAD_CONFIG and place no configuration handle in outConfig. It is
- * the responsibility of the client to call setActiveConfig with a valid
- * configuration before attempting to present anything on the display.
- *
- * Parameters:
- * outConfig - the currently active display configuration; pointer will be
- * non-NULL
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_BAD_CONFIG - no configuration is currently active
- */
-hwc2_error_t getActiveConfig(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_config_t* outConfig) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- return HWC2_ERROR_NONE;
-}
-
-/* getChangedCompositionTypes(..., outNumElements, outLayers, outTypes)
- * Descriptor: HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES
- * Must be provided by all HWC2 devices
- *
- * Retrieves the layers for which the device requires a different composition
- * type than had been set prior to the last call to validateDisplay. The client
- * will either update its state with these types and call acceptDisplayChanges,
- * or will set new types and attempt to validate the display again.
- *
- * outLayers and outTypes may be NULL to retrieve the number of elements which
- * will be returned. The number of elements returned must be the same as the
- * value returned in outNumTypes from the last call to validateDisplay.
- *
- * Parameters:
- * outNumElements - if outLayers or outTypes were NULL, the number of layers
- * and types which would have been returned; if both were non-NULL, the
- * number of elements returned in outLayers and outTypes, which must not
- * exceed the value stored in outNumElements prior to the call; pointer
- * will be non-NULL
- * outLayers - an array of layer handles
- * outTypes - an array of composition types, each corresponding to an element
- * of outLayers
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_NOT_VALIDATED - validateDisplay has not been called for this
- * display
- */
-hwc2_error_t getChangedCompositionTypes(
- hwc2_device_t* device, hwc2_display_t display,
- uint32_t* outNumElements, hwc2_layer_t* outLayers,
- hwc2_composition_t* outTypes) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = NULL;
- hwc2_layer_t layer;
- uint32_t num_type = 0;
- // if (!dctx->validated) return HWC2_ERROR_NOT_VALIDATED;
-
- // if outLayers or outTypes were NULL, the number of layers and types which would have been returned.
- if (NULL == outLayers || NULL == outTypes) {
- /* for (uint32_t i=0; i<HWC2_MAX_LAYERS; i++) {
- hwclayer = dctx->hwc_layer[i];
- if (hwclayer && hwclayer->dev_cmptype
- && hwclayer->dev_cmptype != hwclayer->clt_cmptype) {
- num_type++;
- continue;
- }
- } */
- *outNumElements = dctx->num_chgtyps;
- } else {
- for (uint32_t i=0; i<dctx->num_chgtyps; i++) {
- hwc2_layer_t layer = dctx->types_layer[i];
- hwclayer = dctx->hwc_layer[layer];
-
- if (hwclayer && hwclayer->dev_cmptype
- && hwclayer->dev_cmptype != hwclayer->clt_cmptype) {
- HWC_LOGDB("composition type is changed: %d -> %d", hwclayer->clt_cmptype, hwclayer->dev_cmptype);
- outLayers[num_type] = layer;
- outTypes[num_type] = hwclayer->dev_cmptype;
- num_type++;
- continue;
- }
- }
-
- if (num_type > 0) {
- if (dctx->num_chgtyps == num_type) {
- HWC_LOGDB("There are %d layers type has changed.", num_type);
- *outNumElements = num_type;
- } else {
- HWC_LOGEB("outNumElements:%d is not same as outNumTypes: %d.",
- num_type, dctx->num_chgtyps);
- }
- } else {
- HWC_LOGDA("No layers compositon type changed.");
- }
- }
-
- return HWC2_ERROR_NONE;
-}
-
-/* getClientTargetSupport(..., width, height, format, dataspace)
- * Descriptor: HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT
- * Must be provided by all HWC2 devices
- *
- * Returns whether a client target with the given properties can be handled by
- * the device.
- *
- * The valid formats can be found in android_pixel_format_t in
- * <system/graphics.h>.
- *
- * For more about dataspaces, see setLayerDataspace.
- *
- * This function must return true for a client target with width and height
- * equal to the active display configuration dimensions,
- * HAL_PIXEL_FORMAT_RGBA_8888, and HAL_DATASPACE_UNKNOWN. It is not required to
- * return true for any other configuration.
- *
- * Parameters:
- * width - client target width in pixels
- * height - client target height in pixels
- * format - client target format
- * dataspace - client target dataspace, as described in setLayerDataspace
- *
- * Returns HWC2_ERROR_NONE if the given configuration is supported or one of the
- * following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_UNSUPPORTED - the given configuration is not supported
- */
-hwc2_error_t getClientTargetSupport(
- hwc2_device_t* device, hwc2_display_t display, uint32_t width,
- uint32_t height, android_pixel_format_t format,
- android_dataspace_t dataspace) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- struct framebuffer_info_t *fbinfo = &(dctx->fb_info);
-
- if (width == fbinfo->info.xres
- && height == fbinfo->info.yres
- && format == HAL_PIXEL_FORMAT_RGBA_8888
- && dataspace == HAL_DATASPACE_UNKNOWN) {
- return HWC2_ERROR_NONE;
- }
-
- HWC_LOGEB("fbinfo: [%d x %d], client: [%d x %d]"
- "format: %d, dataspace: %d",
- fbinfo->info.xres,
- fbinfo->info.yres,
- width, height, format, dataspace);
-
- // TODO: ?
- return HWC2_ERROR_UNSUPPORTED;
-}
-
-/* getColorModes(..., outNumModes, outModes)
- * Descriptor: HWC2_FUNCTION_GET_COLOR_MODES
- * Must be provided by all HWC2 devices
- *
- * Returns the color modes supported on this display.
- *
- * The valid color modes can be found in android_color_mode_t in
- * <system/graphics.h>. All HWC2 devices must support at least
- * HAL_COLOR_MODE_NATIVE.
- *
- * outNumModes may be NULL to retrieve the number of modes which will be
- * returned.
- *
- * Parameters:
- * outNumModes - if outModes was NULL, the number of modes which would have
- * been returned; if outModes was not NULL, the number of modes returned,
- * which must not exceed the value stored in outNumModes prior to the
- * call; pointer will be non-NULL
- * outModes - an array of color modes
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- */
-hwc2_error_t getColorModes(
- hwc2_device_t* device, hwc2_display_t display,
- uint32_t* outNumModes, int32_t* /*android_color_mode_t*/ outModes) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- // TODO: ?
- return HWC2_ERROR_NONE;
-}
-
-/* getDisplayAttribute(..., config, attribute, outValue)
- * Descriptor: HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE
- * Must be provided by all HWC2 devices
- *
- * Returns a display attribute value for a particular display configuration.
- *
- * Any attribute which is not supported or for which the value is unknown by the
- * device must return a value of -1.
- *
- * Parameters:
- * config - the display configuration for which to return attribute values
- * attribute - the attribute to query
- * outValue - the value of the attribute; the pointer will be non-NULL
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_BAD_CONFIG - config does not name a valid configuration for this
- * display
- */
-hwc2_error_t getDisplayAttribute(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_config_t config, hwc2_attribute_t attribute, int32_t* outValue) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- struct framebuffer_info_t *fbinfo = &(dctx->fb_info);
-
- // TODO: HWC2_ERROR_BAD_CONFIG?
- switch (attribute) {
- case HWC2_ATTRIBUTE_VSYNC_PERIOD:
- *outValue = dctx->vsync_period;
- break;
- case HWC2_ATTRIBUTE_WIDTH:
- *outValue = fbinfo->info.xres;
- break;
- case HWC2_ATTRIBUTE_HEIGHT:
- *outValue = fbinfo->info.yres;
- break;
- case HWC2_ATTRIBUTE_DPI_X:
- *outValue = fbinfo->xdpi*1000;
- break;
- case HWC2_ATTRIBUTE_DPI_Y:
- *outValue = fbinfo->ydpi*1000;
- break;
- default:
- HWC_LOGEB("unknown display attribute %u", attribute);
- *outValue = -1;
- break;
- }
-
- return HWC2_ERROR_NONE;
-}
-
-/* getDisplayConfigs(..., outNumConfigs, outConfigs)
- * Descriptor: HWC2_FUNCTION_GET_DISPLAY_CONFIGS
- * Must be provided by all HWC2 devices
- *
- * Returns handles for all of the valid display configurations on this display.
- *
- * outConfigs may be NULL to retrieve the number of elements which will be
- * returned.
- *
- * Parameters:
- * outNumConfigs - if outConfigs was NULL, the number of configurations which
- * would have been returned; if outConfigs was not NULL, the number of
- * configurations returned, which must not exceed the value stored in
- * outNumConfigs prior to the call; pointer will be non-NULL
- * outConfigs - an array of configuration handles
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- */
-hwc2_error_t getDisplayConfigs(
- hwc2_device_t* device, hwc2_display_t display,
- uint32_t* outNumConfigs, hwc2_config_t* outConfigs) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- if (display == HWC_DISPLAY_PRIMARY) {
- if (NULL != outConfigs) outConfigs[0] = 0;
- *outNumConfigs = 1;
- } else if (display == HWC_DISPLAY_EXTERNAL) {
- HWC_LOGEB("getDisplayConfigs:connect = %d", dctx->connected);
- //if (!dctx->connected) return HWC2_ERROR_BAD_DISPLAY;
- if (NULL != outConfigs) outConfigs[0] = 0;
- *outNumConfigs = 1;
- }
-
- return HWC2_ERROR_NONE;
-}
-
-/* getDisplayName(..., outSize, outName)
- * Descriptor: HWC2_FUNCTION_GET_DISPLAY_NAME
- * Must be provided by all HWC2 devices
- *
- * Returns a human-readable version of the display's name.
- *
- * outName may be NULL to retrieve the length of the name.
- *
- * Parameters:
- * outSize - if outName was NULL, the number of bytes needed to return the
- * name if outName was not NULL, the number of bytes written into it,
- * which must not exceed the value stored in outSize prior to the call;
- * pointer will be non-NULL
- * outName - the display's name
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- */
-hwc2_error_t getDisplayName(
- hwc2_device_t* device, hwc2_display_t display,
- uint32_t* outSize, char* outName) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- android::String8 pmyName = android::String8("Primary Display");
- android::String8 extName = android::String8("EXTERNAL Display");
- android::String8 virName = android::String8("Virtual Display");
-
- switch (display) {
- case HWC_DISPLAY_PRIMARY:
- if (NULL != outName) strcpy(outName, pmyName.string());
- *outSize = pmyName.size()+1;
- break;
- case HWC_DISPLAY_EXTERNAL:
- if (NULL != outName) strcpy(outName, extName.string());
- *outSize = extName.size()+1;
- break;
- case HWC_DISPLAY_VIRTUAL:
- if (NULL != outName) strcpy(outName, virName.string());
- *outSize = virName.size()+1;
- break;
- default:
- HWC_LOGEB("invalidate display %d", (int32_t)display);
- break;
- }
-
- return HWC2_ERROR_NONE;
-}
-
-/* getDisplayRequests(..., outDisplayRequests, outNumElements, outLayers,
- * outLayerRequests)
- * Descriptor: HWC2_FUNCTION_GET_DISPLAY_REQUESTS
- * Must be provided by all HWC2 devices
- *
- * Returns the display requests and the layer requests required for the last
- * validated configuration.
- *
- * Display requests provide information about how the client should handle the
- * client target. Layer requests provide information about how the client
- * should handle an individual layer.
- *
- * If outLayers or outLayerRequests is NULL, the required number of layers and
- * requests must be returned in outNumElements, but this number may also be
- * obtained from validateDisplay as outNumRequests (outNumElements must be equal
- * to the value returned in outNumRequests from the last call to
- * validateDisplay).
- *
- * Parameters:
- * outDisplayRequests - the display requests for the current validated state
- * outNumElements - if outLayers or outLayerRequests were NULL, the number of
- * elements which would have been returned, which must be equal to the
- * value returned in outNumRequests from the last validateDisplay call on
- * this display; if both were not NULL, the number of elements in
- * outLayers and outLayerRequests, which must not exceed the value stored
- * in outNumElements prior to the call; pointer will be non-NULL
- * outLayers - an array of layers which all have at least one request
- * outLayerRequests - the requests corresponding to each element of outLayers
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_NOT_VALIDATED - validateDisplay has not been called for this
- * display
- */
-hwc2_error_t getDisplayRequests(
- hwc2_device_t* device,
- hwc2_display_t display,
- hwc2_display_request_t* outDisplayRequests,
- uint32_t* outNumElements,
- hwc2_layer_t* outLayers,
- hwc2_layer_request_t* outLayerRequests) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = NULL;
- hwc2_layer_t layer;
- uint32_t num_requests = 0;
-
- //if (!dctx->validated) return HWC2_ERROR_NOT_VALIDATED;
-
- // if outLayers or outTypes were NULL, the number of layers and types which would have been returned.
- if (NULL == outLayers || NULL == outLayerRequests) {
- /*for (uint32_t i=0; i<HWC2_MAX_LAYERS; i++) {
- hwclayer = dctx->hwc_layer[i];
- if (hwclayer && hwclayer->dev_cmptype && hwclayer->dev_cmptype != HWC2_COMPOSITION_CLIENT) {
- num_requests++;
- }
- }*/
- *outNumElements = dctx->num_lyrreqs;
- } else {
- for (uint32_t i=0; i<dctx->num_lyrreqs; i++) {
- hwc2_layer_t layer = dctx->requests_layer[i];
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
- outLayers[num_requests] = layer;
- if (hwclayer && hwclayer->dev_cmptype != HWC2_COMPOSITION_CLIENT) {
- outLayerRequests[num_requests] =
- (hwc2_layer_request_t)HWC2_LAYER_REQUEST_CLEAR_CLIENT_TARGET;
- }
- num_requests++;
- }
-
- if (num_requests > 0) {
- if (dctx->num_lyrreqs == num_requests) {
- HWC_LOGDB("There are %d layer requests.", num_requests);
- *outNumElements = num_requests;
- } else {
- HWC_LOGEB("outNumElements:%d is not same as outNumTypes: %d.",
- num_requests, dctx->num_lyrreqs);
- }
- } else {
- HWC_LOGDA("No layer requests.");
- }
- // dctx->num_lyrreqs = 0;
- }
-
- return HWC2_ERROR_NONE;
-}
-
-/* getDisplayType(..., outType)
- * Descriptor: HWC2_FUNCTION_GET_DISPLAY_TYPE
- * Must be provided by all HWC2 devices
- *
- * Returns whether the given display is a physical or virtual display.
- *
- * Parameters:
- * outType - the type of the display; pointer will be non-NULL
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- */
-hwc2_error_t getDisplayType(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_display_type_t* outType) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- switch (display) {
- case HWC_DISPLAY_PRIMARY:
- *outType = HWC2_DISPLAY_TYPE_PHYSICAL;
- break;
- case HWC_DISPLAY_EXTERNAL:
- *outType = HWC2_DISPLAY_TYPE_PHYSICAL;
- break;
- case HWC_DISPLAY_VIRTUAL:
- *outType = HWC2_DISPLAY_TYPE_VIRTUAL;
- break;
- default:
- *outType = HWC2_DISPLAY_TYPE_INVALID;
- HWC_LOGEB("invalidate display %d", (int32_t)display);
- break;
- }
-
- return HWC2_ERROR_NONE;
-}
-
-/* getDozeSupport(..., outSupport)
- * Descriptor: HWC2_FUNCTION_GET_DOZE_SUPPORT
- * Must be provided by all HWC2 devices
- *
- * Returns whether the given display supports HWC2_POWER_MODE_DOZE and
- * HWC2_POWER_MODE_DOZE_SUSPEND. DOZE_SUSPEND may not provide any benefit over
- * DOZE (see the definition of hwc2_power_mode_t for more information), but if
- * both DOZE and DOZE_SUSPEND are no different from HWC2_POWER_MODE_ON, the
- * device should not claim support.
- *
- * Parameters:
- * outSupport - whether the display supports doze modes (1 for yes, 0 for no);
- * pointer will be non-NULL
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- */
-hwc2_error_t getDozeSupport(
- hwc2_device_t* device, hwc2_display_t display,
- int32_t* outSupport) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- // TODO: we do not support Doze for now.
- *outSupport = 0;
-
- return HWC2_ERROR_NONE;
-}
-
-/* getHdrCapabilities(..., outNumTypes, outTypes, outMaxLuminance,
- * outMaxAverageLuminance, outMinLuminance)
- * Descriptor: HWC2_FUNCTION_GET_HDR_CAPABILITIES
- * Must be provided by all HWC2 devices
- *
- * Returns the high dynamic range (HDR) capabilities of the given display, which
- * are invariant with regard to the active configuration.
- *
- * Displays which are not HDR-capable must return no types in outTypes and set
- * outNumTypes to 0.
- *
- * If outTypes is NULL, the required number of HDR types must be returned in
- * outNumTypes.
- *
- * Parameters:
- * outNumTypes - if outTypes was NULL, the number of types which would have
- * been returned; if it was not NULL, the number of types stored in
- * outTypes, which must not exceed the value stored in outNumTypes prior
- * to the call; pointer will be non-NULL
- * outTypes - an array of HDR types, may have 0 elements if the display is not
- * HDR-capable
- * outMaxLuminance - the desired content maximum luminance for this display in
- * cd/m^2; pointer will be non-NULL
- * outMaxAverageLuminance - the desired content maximum frame-average
- * luminance for this display in cd/m^2; pointer will be non-NULL
- * outMinLuminance - the desired content minimum luminance for this display in
- * cd/m^2; pointer will be non-NULL
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- */
-hwc2_error_t getHdrCapabilities(
- hwc2_device_t* device, hwc2_display_t display,
- uint32_t* outNumTypes, int32_t* /*android_hdr_t*/ outTypes,
- float* outMaxLuminance, float* outMaxAverageLuminance,
- float* outMinLuminance) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- // TODO: currently not support Hdr Capabilityies on aml platform???
- *outNumTypes = 0;
-
- return HWC2_ERROR_NONE;
-
-}
-
-/* getReleaseFences(..., outNumElements, outLayers, outFences)
- * Descriptor: HWC2_FUNCTION_GET_RELEASE_FENCES
- * Must be provided by all HWC2 devices
- *
- * Retrieves the release fences for device layers on this display which will
- * receive new buffer contents this frame.
- *
- * A release fence is a file descriptor referring to a sync fence object which
- * will be signaled after the device has finished reading from the buffer
- * presented in the prior frame. This indicates that it is safe to start writing
- * to the buffer again. If a given layer's fence is not returned from this
- * function, it will be assumed that the buffer presented on the previous frame
- * is ready to be written.
- *
- * The fences returned by this function should be unique for each layer (even if
- * they point to the same underlying sync object), and ownership of the fences
- * is transferred to the client, which is responsible for closing them.
- *
- * If outLayers or outFences is NULL, the required number of layers and fences
- * must be returned in outNumElements.
- *
- * Parameters:
- * outNumElements - if outLayers or outFences were NULL, the number of
- * elements which would have been returned; if both were not NULL, the
- * number of elements in outLayers and outFences, which must not exceed
- * the value stored in outNumElements prior to the call; pointer will be
- * non-NULL
- * outLayers - an array of layer handles
- * outFences - an array of sync fence file descriptors as described above,
- * each corresponding to an element of outLayers
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- */
-hwc2_error_t getReleaseFences(
- hwc2_device_t* device, hwc2_display_t display,
- uint32_t* outNumElements, hwc2_layer_t* outLayers,
- int32_t* outFences) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = NULL;
- hwc2_layer_t layer;
- uint32_t num_layer = 0;
-
- /*for (uint32_t i=0; i<HWC2_MAX_LAYERS; i++) {
- hwclayer = dctx->hwc_layer[i];
- if (hwclayer->layer_acquirefence > -1) {
- if (NULL == outLayers || NULL == outFences) {
- num_layer++;
- } else {
- outLayers[num_layer] = i;
- outFences[num_layer++] = hwclayer->layer_acquirefence;
- }
- }
- }*/
-
- /*if (display == HWC_DISPLAY_VIRTUAL) {
- if (NULL == outLayers || NULL == outFences) {
- HWC_LOGEA("No layer have set buffer yet.", dctx->tgr_acqfence);
- } else {
- HWC_LOGEA("No layer have set buffer yet.");
- }
- }*/
-
- if (NULL == outLayers || NULL == outFences) {
- for (uint32_t i=0; i<HWC2_MAX_LAYERS; i++) {
- hwclayer = dctx->hwc_layer[i];
- if (hwclayer && hwclayer->layer_acquirefence > -1) num_layer++;
- }
- } else {
- for (uint32_t i=0; i<HWC2_MAX_LAYERS; i++) {
- hwclayer = dctx->hwc_layer[i];
- if (hwclayer && hwclayer->layer_acquirefence > -1) {
- outLayers[num_layer] = i;
- outFences[num_layer++] = hwclayer->layer_acquirefence;
- hwclayer->layer_acquirefence = -1;
- }
- }
- }
-
- if (num_layer > 0) {
- HWC_LOGDB("There are %d layer requests.", num_layer);
- *outNumElements = num_layer;
- } else {
- HWC_LOGDA("No layer have set buffer yet.");
- }
-
- return HWC2_ERROR_NONE;
-}
-
-/* presentDisplay(..., outRetireFence)
- * Descriptor: HWC2_FUNCTION_PRESENT_DISPLAY
- * Must be provided by all HWC2 devices
- *
- * Presents the current display contents on the screen (or in the case of
- * virtual displays, into the output buffer).
- *
- * Prior to calling this function, the display must be successfully validated
- * with validateDisplay. Note that setLayerBuffer and setLayerSurfaceDamage
- * specifically do not count as layer state, so if there are no other changes
- * to the layer state (or to the buffer's properties as described in
- * setLayerBuffer), then it is safe to call this function without first
- * validating the display.
- *
- * If this call succeeds, outRetireFence will be populated with a file
- * descriptor referring to a retire sync fence object. For physical displays,
- * this fence will be signaled when the result of composition of the prior frame
- * is no longer necessary (because it has been copied or replaced by this
- * frame). For virtual displays, this fence will be signaled when writes to the
- * output buffer have completed and it is safe to read from it.
- *
- * Parameters:
- * outRetireFence - a sync fence file descriptor as described above; pointer
- * will be non-NULL
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_NO_RESOURCES - no valid output buffer has been set for a virtual
- * display
- * HWC2_ERROR_NOT_VALIDATED - validateDisplay has not successfully been called
- * for this display
- */
-int32_t presentDisplay(
- hwc2_device_t* device, hwc2_display_t display,
- int32_t* outRetireFence) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- int32_t err = HWC2_ERROR_NONE;
-
- if (display == HWC_DISPLAY_VIRTUAL) {
- // deal virtual display.
- if (dctx->connected) {
- if (!dctx->virhnd) {
- HWC_LOGEA("virtual display handle is null.");
- *outRetireFence = -1;
- return HWC2_ERROR_NO_RESOURCES;
- }
- if (private_handle_t::validate(dctx->virhnd) < 0)
- return HWC2_ERROR_NO_RESOURCES;
-
- if (dctx->tgr_acqfence) {
- sync_wait(dctx->tgr_acqfence, 500);
- close(dctx->tgr_acqfence);
- dctx->tgr_acqfence = -1;
- }
- *outRetireFence = dctx->vir_relfence;
- }
- } else {
- // deal with physical display.
- hwc_layer_t *hwclayer = NULL;
-
- // TODO: need improve the way to set video axis.
-#if WITH_LIBPLAYER_MODULE
- for (uint32_t i=0; i<dctx->num_lyrreqs; i++) {
- hwc2_layer_t layer = dctx->requests_layer[i];
- hwclayer = dctx->hwc_layer[layer];
- if (hwclayer && hwclayer->dev_cmptype == HWC2_COMPOSITION_DEVICE) {
- hwc2_overlay_compose(ctx, display, hwclayer);
- }
- }
-#endif
- err = hwc2_fb_post(ctx, display, outRetireFence);
- }
- // reset num_chgtyps & num_lyrreqs to 0.
- dctx->num_chgtyps = 0;
- dctx->num_lyrreqs = 0;
-
- // reset validated to false.
- // dctx->validated = false;
- return err;
-}
-
-/* setActiveConfig(..., config)
- * Descriptor: HWC2_FUNCTION_SET_ACTIVE_CONFIG
- * Must be provided by all HWC2 devices
- *
- * Sets the active configuration for this display. Upon returning, the given
- * display configuration should be active and remain so until either this
- * function is called again or the display is disconnected.
- *
- * Parameters:
- * config - the new display configuration
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_BAD_CONFIG - the configuration handle passed in is not valid for
- * this display
- */
-hwc2_error_t setActiveConfig(
- hwc2_device_t* device,
- hwc2_display_t display,
- hwc2_config_t config) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- // TODO:
- return HWC2_ERROR_NONE;
-}
-
-/* setClientTarget(..., target, acquireFence, dataspace, damage)
- * Descriptor: HWC2_FUNCTION_SET_CLIENT_TARGET
- * Must be provided by all HWC2 devices
- *
- * Sets the buffer handle which will receive the output of client composition.
- * Layers marked as HWC2_COMPOSITION_CLIENT will be composited into this buffer
- * prior to the call to presentDisplay, and layers not marked as
- * HWC2_COMPOSITION_CLIENT should be composited with this buffer by the device.
- *
- * The buffer handle provided may be null if no layers are being composited by
- * the client. This must not result in an error (unless an invalid display
- * handle is also provided).
- *
- * Also provides a file descriptor referring to an acquire sync fence object,
- * which will be signaled when it is safe to read from the client target buffer.
- * If it is already safe to read from this buffer, -1 may be passed instead.
- * The device must ensure that it is safe for the client to close this file
- * descriptor at any point after this function is called.
- *
- * For more about dataspaces, see setLayerDataspace.
- *
- * The damage parameter describes a surface damage region as defined in the
- * description of setLayerSurfaceDamage.
- *
- * Will be called before presentDisplay if any of the layers are marked as
- * HWC2_COMPOSITION_CLIENT. If no layers are so marked, then it is not
- * necessary to call this function. It is not necessary to call validateDisplay
- * after changing the target through this function.
- *
- * Parameters:
- * target - the new target buffer
- * acquireFence - a sync fence file descriptor as described above
- * dataspace - the dataspace of the buffer, as described in setLayerDataspace
- * damage - the surface damage region
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_BAD_PARAMETER - the new target handle was invalid
- */
-hwc2_error_t setClientTarget(
- hwc2_device_t* device, hwc2_display_t display,
- buffer_handle_t target, int32_t acquireFence,
- android_dataspace_t dataspace, hwc_region_t damage) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- if (target && private_handle_t::validate(target) < 0) {
- return HWC2_ERROR_BAD_PARAMETER;
- }
-
- if (NULL != target) {
- dctx->clnt_tgrhnd = target;
- dctx->clnt_tgrdmge = damage;
- if (-1 != acquireFence) {
- dctx->tgr_acqfence = acquireFence;
- // wait acquireFence to be signaled, wait 5s.
- // sync_wait(acquireFence, 5000);
- }
- // TODO: HWC2_ERROR_BAD_PARAMETER && dataspace && damage.
- } else {
- HWC_LOGDA("client target is null!, no need to update this frame.");
- }
-
- return HWC2_ERROR_NONE;
-}
-
-/* setColorMode(..., mode)
- * Descriptor: HWC2_FUNCTION_SET_COLOR_MODE
- * Must be provided by all HWC2 devices
- *
- * Sets the color mode of the given display.
- *
- * Upon returning from this function, the color mode change must have fully
- * taken effect.
- *
- * The valid color modes can be found in android_color_mode_t in
- * <system/graphics.h>. All HWC2 devices must support at least
- * HAL_COLOR_MODE_NATIVE, and displays are assumed to be in this mode upon
- * hotplug.
- *
- * Parameters:
- * mode - the mode to set
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_BAD_PARAMETER - mode is not a valid color mode
- * HWC2_ERROR_UNSUPPORTED - mode is not supported on this display
- */
-hwc2_error_t setColorMode(
- hwc2_device_t* device, hwc2_display_t display,
- int32_t /*android_color_mode_t*/ mode) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- // TODO: return HWC2_ERROR_BAD_PARAMETER && HWC2_ERROR_UNSUPPORTED;
- dctx->color_mode = mode;
- return HWC2_ERROR_NONE;
-}
-
-/* setColorTransform(..., matrix, hint)
- * Descriptor: HWC2_FUNCTION_SET_COLOR_TRANSFORM
- * Must be provided by all HWC2 devices
- *
- * Sets a color transform which will be applied after composition.
- *
- * If hint is not HAL_COLOR_TRANSFORM_ARBITRARY, then the device may use the
- * hint to apply the desired color transform instead of using the color matrix
- * directly.
- *
- * If the device is not capable of either using the hint or the matrix to apply
- * the desired color transform, it should force all layers to client composition
- * during validateDisplay.
- *
- * The matrix provided is an affine color transformation of the following form:
- *
- * |r.r r.g r.b 0|
- * |g.r g.g g.b 0|
- * |b.r b.g b.b 0|
- * |Tr Tg Tb 1|
- *
- * This matrix will be provided in row-major form: {r.r, r.g, r.b, 0, g.r, ...}.
- *
- * Given a matrix of this form and an input color [R_in, G_in, B_in], the output
- * color [R_out, G_out, B_out] will be:
- *
- * R_out = R_in * r.r + G_in * g.r + B_in * b.r + Tr
- * G_out = R_in * r.g + G_in * g.g + B_in * b.g + Tg
- * B_out = R_in * r.b + G_in * g.b + B_in * b.b + Tb
- *
- * Parameters:
- * matrix - a 4x4 transform matrix (16 floats) as described above
- * hint - a hint value which may be used instead of the given matrix unless it
- * is HAL_COLOR_TRANSFORM_ARBITRARY
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_BAD_PARAMETER - hint is not a valid color transform hint
- */
-hwc2_error_t setColorTransform(
- hwc2_device_t* device, hwc2_display_t display,
- const float* matrix, int32_t /*android_color_transform_t*/ hint) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- // TODO: return HWC2_ERROR_BAD_PARAMETER;
-
- return HWC2_ERROR_NONE;
-}
-
-/* setOutputBuffer(..., buffer, releaseFence)
- * Descriptor: HWC2_FUNCTION_SET_OUTPUT_BUFFER
- * Must be provided by all HWC2 devices
- *
- * Sets the output buffer for a virtual display. That is, the buffer to which
- * the composition result will be written.
- *
- * Also provides a file descriptor referring to a release sync fence object,
- * which will be signaled when it is safe to write to the output buffer. If it
- * is already safe to write to the output buffer, -1 may be passed instead. The
- * device must ensure that it is safe for the client to close this file
- * descriptor at any point after this function is called.
- *
- * Must be called at least once before presentDisplay, but does not have any
- * interaction with layer state or display validation.
- *
- * Parameters:
- * buffer - the new output buffer
- * releaseFence - a sync fence file descriptor as described above
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_BAD_PARAMETER - the new output buffer handle was invalid
- * HWC2_ERROR_UNSUPPORTED - display does not refer to a virtual display
- */
-hwc2_error_t setOutputBuffer(
- hwc2_device_t* device, hwc2_display_t display,
- buffer_handle_t buffer, int32_t releaseFence) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *vctx = &(ctx->displays[HWC_DISPLAY_VIRTUAL]);
-
- if (display != HWC_DISPLAY_VIRTUAL) {
- HWC_LOGEB("Should be a virtual display: %d", (int32_t)display);
- return HWC2_ERROR_UNSUPPORTED;
- }
-
- if (vctx->connected) {
- if (buffer && private_handle_t::validate(buffer) < 0) {
- HWC_LOGEA("buffer handle is invalid");
- return HWC2_ERROR_BAD_PARAMETER;
- }
-
- if (NULL != buffer) {
- vctx->virhnd = buffer;
- vctx->vir_relfence = releaseFence;
- } else {
- HWC_LOGDA("Virtual Display output buffer target is null!, no need to update this frame.");
- }
- }
- // TODO: do something?
- return HWC2_ERROR_NONE;
-}
-
-/* setPowerMode(..., mode)
- * Descriptor: HWC2_FUNCTION_SET_POWER_MODE
- * Must be provided by all HWC2 devices
- *
- * Sets the power mode of the given display. The transition must be complete
- * when this function returns. It is valid to call this function multiple times
- * with the same power mode.
- *
- * All displays must support HWC2_POWER_MODE_ON and HWC2_POWER_MODE_OFF. Whether
- * a display supports HWC2_POWER_MODE_DOZE or HWC2_POWER_MODE_DOZE_SUSPEND may
- * be queried using getDozeSupport.
- *
- * Parameters:
- * mode - the new power mode
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_BAD_PARAMETER - mode was not a valid power mode
- * HWC2_ERROR_UNSUPPORTED - mode was a valid power mode, but is not supported
- * on this display
- */
-hwc2_error_t setPowerMode(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_power_mode_t mode) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- if (mode < HWC2_POWER_MODE_OFF || mode > HWC2_POWER_MODE_ON) {
- HWC_LOGEB("setPowerMode bad parameter: %d", mode);
- return HWC2_ERROR_BAD_PARAMETER;
- }
-
- return HWC2_ERROR_NONE;
-}
-
-/* setVsyncEnabled(..., enabled)
- * Descriptor: HWC2_FUNCTION_SET_VSYNC_ENABLED
- * Must be provided by all HWC2 devices
- *
- * Enables or disables the vsync signal for the given display. Virtual displays
- * never generate vsync callbacks, and any attempt to enable vsync for a virtual
- * display though this function must return HWC2_ERROR_NONE and have no other
- * effect.
- *
- * Parameters:
- * enabled - whether to enable or disable vsync
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_BAD_PARAMETER - enabled was an invalid value
- */
-hwc2_error_t setVsyncEnabled(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_vsync_t enabled) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- if (HWC_DISPLAY_VIRTUAL == display)
- return HWC2_ERROR_NONE;
-
- switch (enabled) {
- case HWC2_VSYNC_ENABLE:
- dctx->vsync_enable = true;
- break;
- case HWC2_VSYNC_DISABLE:
- dctx->vsync_enable = false;
- break;
- case HWC2_VSYNC_INVALID:
- default:
- ALOGE("setVsyncEnabled bad parameter: %d", enabled);
- return HWC2_ERROR_BAD_PARAMETER;
- }
-
- pthread_mutex_lock(&hwc_mutex[display]);
- pthread_cond_signal(&hwc_cond[display]);
- pthread_mutex_unlock(&hwc_mutex[display]);
-
- return HWC2_ERROR_NONE;
-}
-
-/* validateDisplay(..., outNumTypes, outNumRequests)
- * Descriptor: HWC2_FUNCTION_VALIDATE_DISPLAY
- * Must be provided by all HWC2 devices
- *
- * Instructs the device to inspect all of the layer state and determine if
- * there are any composition type changes necessary before presenting the
- * display. Permitted changes are described in the definition of
- * hwc2_composition_t above.
- *
- * Also returns the number of layer requests required
- * by the given layer configuration.
- *
- * Parameters:
- * outNumTypes - the number of composition type changes required by the
- * device; if greater than 0, the client must either set and validate new
- * types, or call acceptDisplayChanges to accept the changes returned by
- * getChangedCompositionTypes; must be the same as the number of changes
- * returned by getChangedCompositionTypes (see the declaration of that
- * function for more information); pointer will be non-NULL
- * outNumRequests - the number of layer requests required by this layer
- * configuration; must be equal to the number of layer requests returned
- * by getDisplayRequests (see the declaration of that function for
- * more information); pointer will be non-NULL
- *
- * Returns HWC2_ERROR_NONE if no changes are necessary and it is safe to present
- * the display using the current layer state. Otherwise returns one of the
- * following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_HAS_CHANGES - outNumTypes was greater than 0 (see parameter list
- * for more information)
- */
-hwc2_error_t validateDisplay(
- hwc2_device_t* device, hwc2_display_t display,
- uint32_t* outNumTypes, uint32_t* outNumRequests) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = NULL;
- uint32_t num_type = 0, num_requests = 0;
-
- for (uint32_t i=0; i<HWC2_MAX_LAYERS; i++) {
- hwclayer = dctx->hwc_layer[i];
- if (hwclayer) {
- if (display != HWC_DISPLAY_VIRTUAL) {
- // Physical Display.
- if (hwclayer->clt_cmptype == HWC2_COMPOSITION_DEVICE) {
- // video overlay.
- if (hwclayer->buf_hnd) {
- private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(hwclayer->buf_hnd);
- if (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OVERLAY) {
- hwclayer->dev_cmptype = HWC2_COMPOSITION_DEVICE;
- //dctx->types_layer[num_type] = i;
- dctx->requests_layer[num_requests] = i;
- //num_type++; num_requests++;
- num_requests++;
- continue;
- }
- }
-
- // change all other device type to client.
- hwclayer->dev_cmptype = HWC2_COMPOSITION_CLIENT;
- dctx->types_layer[num_type] = i;
- num_type++;
- continue;
- }
-
- // cursor layer.
-#if ENABLE_CURSOR_LAYER
- if (hwclayer->clt_cmptype == HWC2_COMPOSITION_CURSOR) {
- HWC_LOGDA("This is a Cursor layer!");
- if (display == HWC_DISPLAY_VIRTUAL && dctx->virhnd
- && private_handle_t::validate(dctx->virhnd) >=0) {
- hwclayer->dev_cmptype = HWC2_COMPOSITION_CLIENT;
- dctx->types_layer[num_type] = i;
- num_type++;
- } else {
- hwclayer->dev_cmptype = HWC2_COMPOSITION_CURSOR;
- dctx->requests_layer[num_requests] = i;
- num_requests++;
- }
- continue;
- }
-#endif
-
- // sideband stream.
- if (hwclayer->clt_cmptype == HWC2_COMPOSITION_SIDEBAND && hwclayer->sideband_stream) {
- // TODO: we just transact SIDEBAND to OVERLAY for now;
- HWC_LOGDA("get HWC_SIDEBAND layer, just change to overlay");
- hwclayer->dev_cmptype = HWC2_COMPOSITION_DEVICE;
- dctx->types_layer[num_type] = i;
- dctx->requests_layer[num_requests] = i;
- num_type++; num_requests++;
- continue;
- }
-
- // TODO: solid color.
- if (hwclayer->clt_cmptype == HWC2_COMPOSITION_SOLID_COLOR) {
- HWC_LOGDA("This is a Solid Color layer!");
- hwclayer->dev_cmptype = HWC2_COMPOSITION_SOLID_COLOR;
- dctx->requests_layer[num_requests] = i;
- num_requests++;
- continue;
- }
- } else {
- // Virtual Display.
- if (dctx->virhnd && private_handle_t::validate(dctx->virhnd) >=0) {
- if (hwclayer->clt_cmptype != HWC2_COMPOSITION_CLIENT) {
- // change all other device type to client.
- hwclayer->dev_cmptype = HWC2_COMPOSITION_CLIENT;
- dctx->types_layer[num_type] = i;
- num_type++;
- continue;
- }
- }
- }
- }
- }
-
- if (num_requests > 0) {
- HWC_LOGDB("There are %d layer requests.", num_requests);
- *outNumRequests = dctx->num_lyrreqs = num_requests;
- }
-
- // mark the validate function is called.(???)
- // dctx->validated = true;
- if (num_type > 0) {
- HWC_LOGDB("there are %d layer types has changed.", num_type);
- *outNumTypes = dctx->num_chgtyps= num_type;
- return HWC2_ERROR_HAS_CHANGES;
- }
-
- return HWC2_ERROR_NONE;
-}
-
-/*
- * Layer Functions
- *
- * These are functions which operate on layers, but which do not modify state
- * that must be validated before use. See also 'Layer State Functions' below.
- *
- * All of these functions take as their first three parameters a device pointer,
- * a display handle for the display which contains the layer, and a layer
- * handle, so these parameters are omitted from the described parameter lists.
- */
-
-/* setCursorPosition(..., x, y)
- * Descriptor: HWC2_FUNCTION_SET_CURSOR_POSITION
- * Must be provided by all HWC2 devices
- *
- * Asynchonously sets the position of a cursor layer.
- *
- * Prior to validateDisplay, a layer may be marked as HWC2_COMPOSITION_CURSOR.
- * If validation succeeds (i.e., the device does not request a composition
- * change for that layer), then once a buffer has been set for the layer and it
- * has been presented, its position may be set by this function at any time
- * between presentDisplay and any subsequent validateDisplay calls for this
- * display.
- *
- * Once validateDisplay is called, this function will not be called again until
- * the validate/present sequence is completed.
- *
- * May be called from any thread so long as it is not interleaved with the
- * validate/present sequence as described above.
- *
- * Parameters:
- * x - the new x coordinate (in pixels from the left of the screen)
- * y - the new y coordinate (in pixels from the top of the screen)
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
- * HWC2_ERROR_BAD_LAYER - the layer is invalid or is not currently marked as
- * HWC2_COMPOSITION_CURSOR
- * HWC2_ERROR_NOT_VALIDATED - the device is currently in the middle of the
- * validate/present sequence
- */
-hwc2_error_t setCursorPosition(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_layer_t layer, int32_t x, int32_t y) {
-#if ENABLE_CURSOR_LAYER
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
- struct cursor_context_t *cursor_ctx = &(dctx->cursor_ctx);
- struct framebuffer_info_t *cbinfo = &(cursor_ctx->cb_info);
- struct fb_cursor cinfo;
-
- // Bad layer.
- if (NULL == hwclayer)
- return HWC2_ERROR_BAD_LAYER;
-
- if (HWC2_COMPOSITION_CURSOR != hwclayer->clt_cmptype)
- return HWC2_ERROR_BAD_LAYER;
-
- // TODO: ...HWC2_ERROR_NOT_VALIDATED?
-
- if (cbinfo->fd < 0) {
- HWC_LOGEB("hwc_setCursorPositionAsync fd=%d", cbinfo->fd );
- }else {
- cinfo.hot.x = x;
- cinfo.hot.y = y;
- if (display == HWC_DISPLAY_PRIMARY) {
- HWC_LOGDB("hwc_setCursorPositionAsync x_pos=%d, y_pos=%d", cinfo.hot.x, cinfo.hot.y);
- ioctl(cbinfo->fd, FBIO_CURSOR, &cinfo);
- } else if(display == HWC_DISPLAY_EXTERNAL) {
- // TODO:
- HWC_LOGDA("hwc_setCursorPositionAsync external display need show cursor too! ");
- //ioctl(cbinfo->fd, FBIO_CURSOR, &cinfo);
- }
- }
-#endif
- return HWC2_ERROR_NONE;
-}
-
-/* setLayerBuffer(..., buffer, acquireFence)
- * Descriptor: HWC2_FUNCTION_SET_LAYER_BUFFER
- * Must be provided by all HWC2 devices
- *
- * Sets the buffer handle to be displayed for this layer. If the buffer
- * properties set at allocation time (width, height, format, and usage) have not
- * changed since the previous frame, it is not necessary to call validateDisplay
- * before calling presentDisplay unless new state needs to be validated in the
- * interim.
- *
- * Also provides a file descriptor referring to an acquire sync fence object,
- * which will be signaled when it is safe to read from the given buffer. If it
- * is already safe to read from the buffer, -1 may be passed instead. The
- * device must ensure that it is safe for the client to close this file
- * descriptor at any point after this function is called.
- *
- * This function must return HWC2_ERROR_NONE and have no other effect if called
- * for a layer with a composition type of HWC2_COMPOSITION_SOLID_COLOR (because
- * it has no buffer) or HWC2_COMPOSITION_SIDEBAND or HWC2_COMPOSITION_CLIENT
- * (because synchronization and buffer updates for these layers are handled
- * elsewhere).
- *
- * Parameters:
- * buffer - the buffer handle to set
- * acquireFence - a sync fence file descriptor as described above
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in
- * HWC2_ERROR_BAD_PARAMETER - the buffer handle passed in was invalid
- */
-hwc2_error_t setLayerBuffer(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_layer_t layer, buffer_handle_t buffer,
- int32_t acquireFence) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
-
- // Bad layer.
- if (NULL == hwclayer)
- return HWC2_ERROR_BAD_LAYER;
-
- // Bad parameter
- if (buffer && private_handle_t::validate(buffer) < 0)
- return HWC2_ERROR_BAD_PARAMETER;
-
- if (NULL != buffer) {
- hwclayer->buf_hnd = buffer;
- if (-1 != acquireFence) {
- hwclayer->layer_acquirefence = acquireFence;
- // wait acquireFence to be signaled, wait 5s.
- // sync_wait(acquireFence, 5000);
- }
- } else {
- HWC_LOGDA("Layer buffer is null! no need to update this layer.");
- }
-
- return HWC2_ERROR_NONE;
-}
-
-/* setLayerSurfaceDamage(..., damage)
- * Descriptor: HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE
- * Must be provided by all HWC2 devices
- *
- * Provides the region of the source buffer which has been modified since the
- * last frame. This region does not need to be validated before calling
- * presentDisplay.
- *
- * Once set through this function, the damage region remains the same until a
- * subsequent call to this function.
- *
- * If damage.numRects > 0, then it may be assumed that any portion of the source
- * buffer not covered by one of the rects has not been modified this frame. If
- * damage.numRects == 0, then the whole source buffer must be treated as if it
- * has been modified.
- *
- * If the layer's contents are not modified relative to the prior frame, damage
- * will contain exactly one empty rect([0, 0, 0, 0]).
- *
- * The damage rects are relative to the pre-transformed buffer, and their origin
- * is the top-left corner. They will not exceed the dimensions of the latched
- * buffer.
- *
- * Parameters:
- * damage - the new surface damage region
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in
- */
-hwc2_error_t setLayerSurfaceDamage(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_layer_t layer, hwc_region_t damage) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
-
- // Bad layer.
- if (NULL == hwclayer)
- return HWC2_ERROR_BAD_LAYER;
-
- // TODO: still have some work to do here.
- hwclayer->demage_region = damage;
- return HWC2_ERROR_NONE;
-}
-
-/*
- * Layer State Functions
- *
- * These functions modify the state of a given layer. They do not take effect
- * until the display configuration is successfully validated with
- * validateDisplay and the display contents are presented with presentDisplay.
- *
- * All of these functions take as their first three parameters a device pointer,
- * a display handle for the display which contains the layer, and a layer
- * handle, so these parameters are omitted from the described parameter lists.
- */
-
-/* setLayerBlendMode(..., mode)
- * Descriptor: HWC2_FUNCTION_SET_LAYER_BLEND_MODE
- * Must be provided by all HWC2 devices
- *
- * Sets the blend mode of the given layer.
- *
- * Parameters:
- * mode - the new blend mode
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in
- * HWC2_ERROR_BAD_PARAMETER - an invalid blend mode was passed in
- */
-hwc2_error_t setLayerBlendMode(
- hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer,
- hwc2_blend_mode_t mode) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
-
- // Bad layer.
- if (NULL == hwclayer)
- return HWC2_ERROR_BAD_LAYER;
-
- if (mode < HWC2_BLEND_MODE_INVALID
- || mode > HWC2_BLEND_MODE_COVERAGE)
- return HWC2_ERROR_BAD_PARAMETER;
-
- hwclayer->blend_mode= mode;
- return HWC2_ERROR_NONE;
-}
-
-/* setLayerColor(..., color)
- * Descriptor: HWC2_FUNCTION_SET_LAYER_COLOR
- * Must be provided by all HWC2 devices
- *
- * Sets the color of the given layer. If the composition type of the layer is
- * not HWC2_COMPOSITION_SOLID_COLOR, this call must return HWC2_ERROR_NONE and
- * have no other effect.
- *
- * Parameters:
- * color - the new color
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in
- */
-hwc2_error_t setLayerColor(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_layer_t layer, hwc_color_t color) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
-
- // Bad layer.
- if (NULL == hwclayer)
- return HWC2_ERROR_BAD_LAYER;
-
- hwclayer->color = color;
- return HWC2_ERROR_NONE;
-}
-
-/* setLayerCompositionType(..., type)
- * Descriptor: HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE
- * Must be provided by all HWC2 devices
- *
- * Sets the desired composition type of the given layer. During validateDisplay,
- * the device may request changes to the composition types of any of the layers
- * as described in the definition of hwc2_composition_t above.
- *
- * Parameters:
- * type - the new composition type
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in
- * HWC2_ERROR_BAD_PARAMETER - an invalid composition type was passed in
- * HWC2_ERROR_UNSUPPORTED - a valid composition type was passed in, but it is
- * not supported by this device
- */
-hwc2_error_t setLayerCompositionType(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_layer_t layer, hwc2_composition_t type) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
-
- // Bad layer.
- if (NULL == hwclayer)
- return HWC2_ERROR_BAD_LAYER;
-
- // Bad parameter.
- if (type < HWC2_COMPOSITION_INVALID
- || type > HWC2_COMPOSITION_SIDEBAND)
- return HWC2_ERROR_BAD_PARAMETER;
-
- // Do not support solid color for now.
- if (type == HWC2_COMPOSITION_SOLID_COLOR)
- return HWC2_ERROR_UNSUPPORTED;
-
- hwclayer->clt_cmptype = type;
- return HWC2_ERROR_NONE;
-}
-
-/* setLayerDataspace(..., dataspace)
- * Descriptor: HWC2_FUNCTION_SET_LAYER_DATASPACE
- * Must be provided by all HWC2 devices
- *
- * Sets the dataspace that the current buffer on this layer is in.
- *
- * The dataspace provides more information about how to interpret the buffer
- * contents, such as the encoding standard and color transform.
- *
- * See the values of android_dataspace_t in <system/graphics.h> for more
- * information.
- *
- * Parameters:
- * dataspace - the new dataspace
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in
- */
-hwc2_error_t setLayerDataspace(
- hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer,
- int32_t /*android_dataspace_t*/ dataspace) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
-
- // Bad layer.
- if (NULL == hwclayer)
- return HWC2_ERROR_BAD_LAYER;
-
- hwclayer->dataspace = dataspace;
- return HWC2_ERROR_NONE;
-}
-
-/* setLayerDisplayFrame(..., frame)
- * Descriptor: HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME
- * Must be provided by all HWC2 devices
- *
- * Sets the display frame (the portion of the display covered by a layer) of the
- * given layer. This frame will not exceed the display dimensions.
- *
- * Parameters:
- * frame - the new display frame
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in
- */
-hwc2_error_t setLayerDisplayFrame(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_layer_t layer, hwc_rect_t frame) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
-
- // Bad layer.
- if (NULL == hwclayer)
- return HWC2_ERROR_BAD_LAYER;
-
- hwclayer->display_frame = frame;
- return HWC2_ERROR_NONE;
-}
-
-/* setLayerPlaneAlpha(..., alpha)
- * Descriptor: HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA
- * Must be provided by all HWC2 devices
- *
- * Sets an alpha value (a floating point value in the range [0.0, 1.0]) which
- * will be applied to the whole layer. It can be conceptualized as a
- * preprocessing step which applies the following function:
- * if (blendMode == HWC2_BLEND_MODE_PREMULTIPLIED)
- * out.rgb = in.rgb * planeAlpha
- * out.a = in.a * planeAlpha
- *
- * If the device does not support this operation on a layer which is marked
- * HWC2_COMPOSITION_DEVICE, it must request a composition type change to
- * HWC2_COMPOSITION_CLIENT upon the next validateDisplay call.
- *
- * Parameters:
- * alpha - the plane alpha value to apply
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in
- */
-hwc2_error_t setLayerPlaneAlpha(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_layer_t layer, float alpha) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
-
- // Bad layer.
- if (NULL == hwclayer)
- return HWC2_ERROR_BAD_LAYER;
-
- hwclayer->alpha = alpha;
- return HWC2_ERROR_NONE;
-}
-
-/* setLayerSidebandStream(..., stream)
- * Descriptor: HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM
- * Provided by HWC2 devices which support HWC2_CAPABILITY_SIDEBAND_STREAM
- *
- * Sets the sideband stream for this layer. If the composition type of the given
- * layer is not HWC2_COMPOSITION_SIDEBAND, this call must return HWC2_ERROR_NONE
- * and have no other effect.
- *
- * Parameters:
- * stream - the new sideband stream
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in
- * HWC2_ERROR_BAD_PARAMETER - an invalid sideband stream was passed in
- */
-hwc2_error_t setLayerSidebandStream(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_layer_t layer, const native_handle_t* stream) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
-
- // Bad layer.
- if (NULL == hwclayer)
- return HWC2_ERROR_BAD_LAYER;
-
- // Bad parameter.
- if (NULL == stream)
- return HWC2_ERROR_BAD_PARAMETER;
-
- hwclayer->sideband_stream = stream;
- return HWC2_ERROR_NONE;
-}
-
-/* setLayerSourceCrop(..., crop)
- * Descriptor: HWC2_FUNCTION_SET_LAYER_SOURCE_CROP
- * Must be provided by all HWC2 devices
- *
- * Sets the source crop (the portion of the source buffer which will fill the
- * display frame) of the given layer. This crop rectangle will not exceed the
- * dimensions of the latched buffer.
- *
- * If the device is not capable of supporting a true float source crop (i.e., it
- * will truncate or round the floats to integers), it should set this layer to
- * HWC2_COMPOSITION_CLIENT when crop is non-integral for the most accurate
- * rendering.
- *
- * If the device cannot support float source crops, but still wants to handle
- * the layer, it should use the following code (or similar) to convert to
- * an integer crop:
- * intCrop.left = (int) ceilf(crop.left);
- * intCrop.top = (int) ceilf(crop.top);
- * intCrop.right = (int) floorf(crop.right);
- * intCrop.bottom = (int) floorf(crop.bottom);
- *
- * Parameters:
- * crop - the new source crop
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in
- */
-hwc2_error_t setLayerSourceCrop(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_layer_t layer, hwc_frect_t crop) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
-
- // Bad layer.
- if (NULL == hwclayer)
- return HWC2_ERROR_BAD_LAYER;
-
- // TODO: still have some work to do.
- hwclayer->source_crop = crop;
- return HWC2_ERROR_NONE;
-}
-
-/* setLayerTransform(..., transform)
- * Descriptor: HWC2_FUNCTION_SET_LAYER_TRANSFORM
- * Must be provided by all HWC2 devices
- *
- * Sets the transform (rotation/flip) of the given layer.
- *
- * Parameters:
- * transform - the new transform
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in
- * HWC2_ERROR_BAD_PARAMETER - an invalid transform was passed in
- */
-hwc2_error_t setLayerTransform(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_layer_t layer, hwc_transform_t transform) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
-
- // Bad layer.
- if (NULL == hwclayer)
- return HWC2_ERROR_BAD_LAYER;
-
- // Bad parameter.
- if (transform < 0 || transform > HWC_TRANSFORM_ROT_270) {
- return HWC2_ERROR_BAD_PARAMETER;
- }
-
- hwclayer->transform = transform;
- return HWC2_ERROR_NONE;
-
-}
-
-/* setLayerVisibleRegion(..., visible)
- * Descriptor: HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION
- * Must be provided by all HWC2 devices
- *
- * Specifies the portion of the layer that is visible, including portions under
- * translucent areas of other layers. The region is in screen space, and will
- * not exceed the dimensions of the screen.
- *
- * Parameters:
- * visible - the new visible region, in screen space
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in
- */
-hwc2_error_t setLayerVisibleRegion(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_layer_t layer, hwc_region_t visible) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
-
- // Bad layer.
- if (NULL == hwclayer)
- return HWC2_ERROR_BAD_LAYER;
-
- hwclayer->visible_region = visible;
- return HWC2_ERROR_NONE;
-}
-
-/* setLayerZOrder(..., z)
- * Descriptor: HWC2_FUNCTION_SET_LAYER_Z_ORDER
- * Must be provided by all HWC2 devices
- *
- * Sets the desired Z order (height) of the given layer. A layer with a greater
- * Z value occludes a layer with a lesser Z value.
- *
- * Parameters:
- * z - the new Z order
- *
- * Returns HWC2_ERROR_NONE or one of the following errors:
- * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in
- */
-hwc2_error_t setLayerZOrder(
- hwc2_device_t* device, hwc2_display_t display,
- hwc2_layer_t layer, uint32_t z) {
- hwc2_context_t *ctx = (hwc2_context_t*)device;
- display_context_t *dctx = &(ctx->displays[display]);
- isValidDisplay(dctx, display);
-
- hwc_layer_t *hwclayer = dctx->hwc_layer[layer];
-
- // Bad layer.
- if (NULL == hwclayer)
- return HWC2_ERROR_BAD_LAYER;
-
- hwclayer->zorder = z;
- return HWC2_ERROR_NONE;
-}
-
-/* getCapabilities(..., outCount, outCapabilities)
- *
- * Provides a list of capabilities (described in the definition of
- * hwc2_capability_t above) supported by this device. This list must
- * not change after the device has been loaded.
- *
- * Parameters:
- * outCount - if outCapabilities was NULL, the number of capabilities
- * which would have been returned; if outCapabilities was not NULL,
- * the number of capabilities returned, which must not exceed the
- * value stored in outCount prior to the call
- * outCapabilities - a list of capabilities supported by this device; may
- * be NULL, in which case this function must write into outCount the
- * number of capabilities which would have been written into
- * outCapabilities
- */
-void hwc2_getCapabilities(struct hwc2_device* device, uint32_t* outCount,
- int32_t* /*hwc2_capability_t*/ outCapabilities) {
- if (NULL == outCapabilities) {
- *outCount = 1;
- } else {
- *outCount = 1;
- outCapabilities[0] = HWC2_CAPABILITY_SIDEBAND_STREAM;
- }
-}
-
-hwc2_function_pointer_t hwc2_getFunction(struct hwc2_device* device,
- int32_t /*hwc2_function_descriptor_t*/ descriptor) {
- switch (descriptor) {
- // Device functions
- case HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY:
- return reinterpret_cast<hwc2_function_pointer_t>(createVirtualDisplay);
- case HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY:
- return reinterpret_cast<hwc2_function_pointer_t>(destroyVirtualDisplay);
- case HWC2_FUNCTION_DUMP:
- return reinterpret_cast<hwc2_function_pointer_t>(dump);
- case HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT:
- return reinterpret_cast<hwc2_function_pointer_t>(getMaxVirtualDisplayCount);
- case HWC2_FUNCTION_REGISTER_CALLBACK:
- return reinterpret_cast<hwc2_function_pointer_t>(registerCallback);
-
- // Display functions
- case HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES:
- return reinterpret_cast<hwc2_function_pointer_t>(acceptDisplayChanges);
- case HWC2_FUNCTION_CREATE_LAYER:
- return reinterpret_cast<hwc2_function_pointer_t>(createLayer);
- case HWC2_FUNCTION_DESTROY_LAYER:
- return reinterpret_cast<hwc2_function_pointer_t>(destroyLayer);
- case HWC2_FUNCTION_GET_ACTIVE_CONFIG:
- return reinterpret_cast<hwc2_function_pointer_t>(getActiveConfig);
- case HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES:
- return reinterpret_cast<hwc2_function_pointer_t>(getChangedCompositionTypes);
- case HWC2_FUNCTION_GET_COLOR_MODES:
- return reinterpret_cast<hwc2_function_pointer_t>(getColorModes);
- case HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE:
- return reinterpret_cast<hwc2_function_pointer_t>(getDisplayAttribute);
- case HWC2_FUNCTION_GET_DISPLAY_CONFIGS:
- return reinterpret_cast<hwc2_function_pointer_t>(getDisplayConfigs);
- case HWC2_FUNCTION_GET_DISPLAY_NAME:
- return reinterpret_cast<hwc2_function_pointer_t>(getDisplayName);
- case HWC2_FUNCTION_GET_DISPLAY_REQUESTS:
- return reinterpret_cast<hwc2_function_pointer_t>(getDisplayRequests);
- case HWC2_FUNCTION_GET_DISPLAY_TYPE:
- return reinterpret_cast<hwc2_function_pointer_t>(getDisplayType);
- case HWC2_FUNCTION_GET_DOZE_SUPPORT:
- return reinterpret_cast<hwc2_function_pointer_t>(getDozeSupport);
- case HWC2_FUNCTION_GET_HDR_CAPABILITIES:
- return reinterpret_cast<hwc2_function_pointer_t>(getHdrCapabilities);
- case HWC2_FUNCTION_GET_RELEASE_FENCES:
- return reinterpret_cast<hwc2_function_pointer_t>(getReleaseFences);
- case HWC2_FUNCTION_PRESENT_DISPLAY:
- return reinterpret_cast<hwc2_function_pointer_t>(presentDisplay);
- case HWC2_FUNCTION_SET_ACTIVE_CONFIG:
- return reinterpret_cast<hwc2_function_pointer_t>(setActiveConfig);
- case HWC2_FUNCTION_SET_CLIENT_TARGET:
- return reinterpret_cast<hwc2_function_pointer_t>(setClientTarget);
- case HWC2_FUNCTION_SET_COLOR_MODE:
- return reinterpret_cast<hwc2_function_pointer_t>(setColorMode);
- case HWC2_FUNCTION_SET_COLOR_TRANSFORM:
- return reinterpret_cast<hwc2_function_pointer_t>(setColorTransform);
- case HWC2_FUNCTION_SET_OUTPUT_BUFFER:
- return reinterpret_cast<hwc2_function_pointer_t>(setOutputBuffer);
- case HWC2_FUNCTION_SET_POWER_MODE:
- return reinterpret_cast<hwc2_function_pointer_t>(setPowerMode);
- case HWC2_FUNCTION_SET_VSYNC_ENABLED:
- return reinterpret_cast<hwc2_function_pointer_t>(setVsyncEnabled);
- case HWC2_FUNCTION_VALIDATE_DISPLAY:
- return reinterpret_cast<hwc2_function_pointer_t>(validateDisplay);
-
- // Layer functions
- case HWC2_FUNCTION_SET_CURSOR_POSITION:
- return reinterpret_cast<hwc2_function_pointer_t>(setCursorPosition);
- case HWC2_FUNCTION_SET_LAYER_BUFFER:
- return reinterpret_cast<hwc2_function_pointer_t>(setLayerBuffer);
- case HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE:
- return reinterpret_cast<hwc2_function_pointer_t>(setLayerSurfaceDamage);
-
- // Layer state functions
- case HWC2_FUNCTION_SET_LAYER_BLEND_MODE:
- return reinterpret_cast<hwc2_function_pointer_t>(setLayerBlendMode);
- case HWC2_FUNCTION_SET_LAYER_COLOR:
- return reinterpret_cast<hwc2_function_pointer_t>(setLayerColor);
- case HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE:
- return reinterpret_cast<hwc2_function_pointer_t>(setLayerCompositionType);
- case HWC2_FUNCTION_SET_LAYER_DATASPACE:
- return reinterpret_cast<hwc2_function_pointer_t>(setLayerDataspace);
- case HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME:
- return reinterpret_cast<hwc2_function_pointer_t>(setLayerDisplayFrame);
- case HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA:
- return reinterpret_cast<hwc2_function_pointer_t>(setLayerPlaneAlpha);
- case HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM:
- return reinterpret_cast<hwc2_function_pointer_t>(setLayerSidebandStream);
- case HWC2_FUNCTION_SET_LAYER_SOURCE_CROP:
- return reinterpret_cast<hwc2_function_pointer_t>(setLayerSourceCrop);
- case HWC2_FUNCTION_SET_LAYER_TRANSFORM:
- return reinterpret_cast<hwc2_function_pointer_t>(setLayerTransform);
- case HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION:
- return reinterpret_cast<hwc2_function_pointer_t>(setLayerVisibleRegion);
- case HWC2_FUNCTION_SET_LAYER_Z_ORDER:
- return reinterpret_cast<hwc2_function_pointer_t>(setLayerZOrder);
- default:
- ALOGE("getFunction: Unknown function descriptor: %d", descriptor);
- return NULL;
- }
-}
-
-static int32_t hwc2_device_open(const struct hw_module_t* module, const char* name,
- struct hw_device_t** device) {
- int32_t ret;
-
- if (strcmp(name, HWC_HARDWARE_COMPOSER)) return -EINVAL;
-
- hwc2_context_t *dev;
- dev = (hwc2_context_t *)malloc(sizeof(*dev));
- memset(dev, 0, sizeof(*dev));
-
- if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
- (const struct hw_module_t **)&dev->gralloc_module)) {
- HWC_LOGEA("failed to get gralloc hw module");
- ret = -EINVAL;
- goto err_get_module;
- }
-
- //init primiary display
- //default is alwasy false,will check it in hot plug.
- init_display(dev, HWC_DISPLAY_PRIMARY);
-
- // willchanged to use hw vsync.
- dev->displays[HWC_DISPLAY_PRIMARY].vsync_period = chk_output_mode(dev->mode);
-
- dev->base.common.tag = HARDWARE_DEVICE_TAG;
- dev->base.common.version = HWC_DEVICE_API_VERSION_2_0;
- dev->base.common.module = const_cast<hw_module_t *>(module);
- dev->base.common.close = hwc2_close;
-
- dev->base.getFunction = hwc2_getFunction;
- dev->base.getCapabilities = hwc2_getCapabilities;
-
- dev->displays[HWC_DISPLAY_PRIMARY].vsync_enable = false;
- dev->displays[HWC_DISPLAY_EXTERNAL].vsync_enable = false;
- dev->blank_status = false;
- *device = &dev->base.common;
-
- ret = pthread_create(&dev->primary_vsync_thread, NULL, hwc2_primary_vsync_thread, dev);
- if (ret) {
- HWC_LOGEB("failed to start primary vsync thread: %s", strerror(ret));
- ret = -ret;
- goto err_vsync;
- }
-
- ret = pthread_create(&dev->external_vsync_thread, NULL, hwc2_external_vsync_thread, dev);
- if (ret) {
- HWC_LOGEB("failed to start external vsync thread: %s", strerror(ret));
- ret = -ret;
- goto err_vsync;
- }
-
- //temp solution, will change to use uevnet from kernel
- ret = pthread_create(&dev->hotplug_thread, NULL, hwc2_hotplug_thread, dev);
- if (ret) {
- HWC_LOGEB("failed to start hotplug thread: %s", strerror(ret));
- ret = -ret;
- goto err_vsync;
- }
- return 0;
-
-err_vsync:
- uninit_display(dev,HWC_DISPLAY_PRIMARY);
-err_get_module:
- if (dev) free(dev);
- return ret;
-}
-
-static struct hw_module_methods_t hwc2_module_methods = {
- .open = hwc2_device_open
-};
-
-hwc2_module_t HAL_MODULE_INFO_SYM = {
- .common = {
- .tag = HARDWARE_MODULE_TAG,
- .version_major = 2,
- .version_minor = 0,
- .id = HWC_HARDWARE_MODULE_ID,
- .name = "hwcomposer2 module",
- .author = "Amlogic",
- .methods = &hwc2_module_methods,
- .dso = NULL,
- .reserved = {0},
- }
- };
-