summaryrefslogtreecommitdiff
Diffstat
-rw-r--r--hwc1.4/Android.mk60
-rw-r--r--hwc1.4/hwcomposer.cpp1202
-rw-r--r--hwc2/common/base/HwcLayer.cpp2
-rw-r--r--hwc2/common/base/HwcLayer.h6
-rw-r--r--hwc2/common/base/HwcModule.cpp9
-rw-r--r--hwc2/common/base/Hwcomposer.cpp14
-rw-r--r--hwc2/common/composers/GE2DComposer.cpp3
-rw-r--r--hwc2/common/composers/GE2DComposer.h6
-rw-r--r--hwc2/common/composers/IComposeDevice.cpp (renamed from hwc2/common/composers/Composers.cpp)10
-rw-r--r--hwc2/common/composers/IComposeDevice.h (renamed from hwc2/common/composers/Composers.h)17
-rw-r--r--hwc2/common/devices/PhysicalDevice.cpp25
-rw-r--r--hwc2/common/devices/PrimaryDevice.cpp2
-rw-r--r--hwc2/common/hdmi/DisplayHdmi.h2
-rw-r--r--hwc2/common/utils/Utils.cpp2
-rw-r--r--hwc2/common/utils/Utils.h5
-rw-r--r--hwc2/include/Hwcomposer.h4
-rw-r--r--hwc2/include/IComposeDeviceFactory.h (renamed from hwc2/include/IComposerFactory.h)16
-rw-r--r--hwc2/include/IComposer.h47
-rw-r--r--hwc2/include/PhysicalDevice.h17
-rw-r--r--hwc2/include/PrimaryDevice.h4
-rw-r--r--hwc2/platforms/Android.mk6
-rw-r--r--hwc2/platforms/PlatFactory.cpp6
22 files changed, 45 insertions, 1420 deletions
diff --git a/hwc1.4/hwcomposer.cpp b/hwc1.4/hwcomposer.cpp
deleted file mode 100644
index 8f50754..0000000
--- a/hwc1.4/hwcomposer.cpp
+++ b/dev/null
@@ -1,1202 +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 "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;
-}
-