diff options
-rw-r--r-- | common.mk | 2 | ||||
-rw-r--r-- | libexternal/external.h | 1 | ||||
-rw-r--r-- | libgralloc/ionalloc.cpp | 4 | ||||
-rw-r--r-- | libhwcomposer/hwc.cpp | 8 | ||||
-rw-r--r-- | libhwcomposer/hwc_uevents.cpp | 3 | ||||
-rw-r--r-- | libhwcomposer/hwc_utils.cpp | 18 | ||||
-rw-r--r-- | libhwcomposer/hwc_vsync.cpp | 138 | ||||
-rw-r--r-- | liboverlay/overlayMdssRot.cpp | 2 | ||||
-rw-r--r-- | liboverlay/overlayMem.h | 3 |
9 files changed, 102 insertions, 77 deletions
@@ -41,10 +41,10 @@ kernel_includes := ifeq ($(TARGET_USES_QCOM_BSP),true) # Enable QCOM Display features common_flags += -DQCOM_BSP +endif ifneq ($(call is-platform-sdk-version-at-least,18),true) common_flags += -DANDROID_JELLYBEAN_MR1=1 endif -endif ifeq ($(call is-vendor-board-platform,QCOM),true) # This check is to pick the kernel headers from the right location. # If the macro above is defined, we make the assumption that we have the kernel diff --git a/libexternal/external.h b/libexternal/external.h index d35490f9f..7ab7c3f30 100644 --- a/libexternal/external.h +++ b/libexternal/external.h @@ -58,6 +58,7 @@ public: int configureWFDDisplay(); int teardownHDMIDisplay(); int teardownWFDDisplay(); + int getHDMIIndex() { return mHdmiFbNum; } private: void setSPDInfo(const char* node, const char* property); diff --git a/libgralloc/ionalloc.cpp b/libgralloc/ionalloc.cpp index 46c7cb841..fd3abbc74 100644 --- a/libgralloc/ionalloc.cpp +++ b/libgralloc/ionalloc.cpp @@ -109,10 +109,6 @@ int IonAlloc::alloc_buffer(alloc_data& data) ioctl(mIonFd, ION_IOC_FREE, &handle_data); return err; } - memset(base, 0, ionAllocData.len); - // Clean cache after memset - clean_buffer(base, data.size, data.offset, fd_data.fd, - CACHE_CLEAN_AND_INVALIDATE); } data.base = base; diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp index e3223576b..75b9ecb5c 100644 --- a/libhwcomposer/hwc.cpp +++ b/libhwcomposer/hwc.cpp @@ -158,7 +158,6 @@ static int hwc_prepare_external(hwc_composer_device_1 *dev, hwc_display_contents_1_t *list, int dpy) { hwc_context_t* ctx = (hwc_context_t*)(dev); - Locker::Autolock _l(ctx->mExtLock); if (LIKELY(list && list->numHwLayers > 1) && ctx->dpyAttr[dpy].isActive && @@ -209,7 +208,8 @@ static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays, { int ret = 0; hwc_context_t* ctx = (hwc_context_t*)(dev); - Locker::Autolock _l(ctx->mBlankLock); + Locker::Autolock _bl(ctx->mBlankLock); + Locker::Autolock _el(ctx->mExtLock); reset(ctx, numDisplays, displays); ctx->mOverlay->configBegin(); @@ -417,7 +417,6 @@ static int hwc_set_external(hwc_context_t *ctx, { ATRACE_CALL(); int ret = 0; - Locker::Autolock _l(ctx->mExtLock); if (LIKELY(list) && ctx->dpyAttr[dpy].isActive && ctx->dpyAttr[dpy].connected) { @@ -477,7 +476,8 @@ static int hwc_set(hwc_composer_device_1 *dev, { int ret = 0; hwc_context_t* ctx = (hwc_context_t*)(dev); - Locker::Autolock _l(ctx->mBlankLock); + Locker::Autolock _bl(ctx->mBlankLock); + Locker::Autolock _el(ctx->mExtLock); for (uint32_t i = 0; i <= numDisplays; i++) { hwc_display_contents_1_t* list = displays[i]; switch(i) { diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp index 28b1849b7..abca20bb9 100644 --- a/libhwcomposer/hwc_uevents.cpp +++ b/libhwcomposer/hwc_uevents.cpp @@ -206,6 +206,7 @@ static void handle_uevent(hwc_context_t* ctx, const char* udata, int len) case EXTERNAL_PAUSE: { // pause case ALOGD("%s Received Pause event",__FUNCTION__); + Locker::Autolock _l(ctx->mExtLock); ctx->dpyAttr[dpy].isActive = true; ctx->dpyAttr[dpy].isPause = true; break; @@ -214,9 +215,11 @@ static void handle_uevent(hwc_context_t* ctx, const char* udata, int len) { // resume case ALOGD("%s Received resume event",__FUNCTION__); // treat Resume as Online event + Locker::Autolock _l(ctx->mExtLock); ctx->mExtDispConfiguring = true; ctx->dpyAttr[dpy].isActive = true; ctx->dpyAttr[dpy].isPause = false; + ctx->proc->invalidate(ctx->proc); break; } default: diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp index 90038f25d..552b526e6 100644 --- a/libhwcomposer/hwc_utils.cpp +++ b/libhwcomposer/hwc_utils.cpp @@ -478,8 +478,8 @@ void setListStats(hwc_context_t *ctx, } -static void calc_cut(float& leftCutRatio, float& topCutRatio, - float& rightCutRatio, float& bottomCutRatio, int orient) { +static void calc_cut(double& leftCutRatio, double& topCutRatio, + double& rightCutRatio, double& bottomCutRatio, int orient) { if(orient & HAL_TRANSFORM_FLIP_H) { swap(leftCutRatio, rightCutRatio); } @@ -488,7 +488,7 @@ static void calc_cut(float& leftCutRatio, float& topCutRatio, } if(orient & HAL_TRANSFORM_ROT_90) { //Anti clock swapping - float tmpCutRatio = leftCutRatio; + double tmpCutRatio = leftCutRatio; leftCutRatio = topCutRatio; topCutRatio = rightCutRatio; rightCutRatio = bottomCutRatio; @@ -553,26 +553,26 @@ void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst, int sci_w = abs(sci_r - sci_l); int sci_h = abs(sci_b - sci_t); - float leftCutRatio = 0.0f, rightCutRatio = 0.0f, topCutRatio = 0.0f, - bottomCutRatio = 0.0f; + double leftCutRatio = 0.0, rightCutRatio = 0.0, topCutRatio = 0.0, + bottomCutRatio = 0.0; if(dst_l < sci_l) { - leftCutRatio = (float)(sci_l - dst_l) / (float)dst_w; + leftCutRatio = (double)(sci_l - dst_l) / (double)dst_w; dst_l = sci_l; } if(dst_r > sci_r) { - rightCutRatio = (float)(dst_r - sci_r) / (float)dst_w; + rightCutRatio = (double)(dst_r - sci_r) / (double)dst_w; dst_r = sci_r; } if(dst_t < sci_t) { - topCutRatio = (float)(sci_t - dst_t) / (float)dst_h; + topCutRatio = (double)(sci_t - dst_t) / (double)dst_h; dst_t = sci_t; } if(dst_b > sci_b) { - bottomCutRatio = (float)(dst_b - sci_b) / (float)dst_h; + bottomCutRatio = (double)(dst_b - sci_b) / (double)dst_h; dst_b = sci_b; } diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp index 2f4475e76..e4da4f778 100644 --- a/libhwcomposer/hwc_vsync.cpp +++ b/libhwcomposer/hwc_vsync.cpp @@ -33,6 +33,7 @@ namespace qhwc { #define HWC_VSYNC_THREAD_NAME "hwcVsyncThread" +#define MAX_SYSFS_FILE_PATH 255 int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable) { @@ -49,10 +50,6 @@ int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable) static void *vsync_loop(void *param) { - const char* vsync_timestamp_fb0 = "/sys/class/graphics/fb0/vsync_event"; - const char* vsync_timestamp_fb1 = "/sys/class/graphics/fb1/vsync_event"; - int dpy = HWC_DISPLAY_PRIMARY; - hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param); char thread_name[64] = HWC_VSYNC_THREAD_NAME; @@ -61,16 +58,14 @@ static void *vsync_loop(void *param) android::PRIORITY_MORE_FAVORABLE); const int MAX_DATA = 64; - static char vdata[MAX_DATA]; - struct pollfd pfd; - - uint64_t cur_timestamp=0; - ssize_t len = -1; - int fb0_fd = -1; - int ret = 0; - bool fb1_vsync = false; + char vdata[MAX_DATA]; bool logvsync = false; + struct pollfd pfd[2]; + int fb_fd[2]; + uint64_t timestamp[2]; + int num_displays; + char property[PROPERTY_VALUE_MAX]; if(property_get("debug.hwc.fakevsync", property, NULL) > 0) { if(atoi(property) == 1) @@ -82,62 +77,91 @@ static void *vsync_loop(void *param) logvsync = true; } - /* Currently read vsync timestamp from drivers - e.g. VSYNC=41800875994 - */ - fb0_fd = open(vsync_timestamp_fb0, O_RDONLY); - pfd.fd = fb0_fd; - pfd.events = POLLPRI | POLLERR; - - if (fb0_fd < 0) { - // Make sure fb device is opened before starting this thread so this - // never happens. - ALOGE ("FATAL:%s:not able to open file:%s, %s", __FUNCTION__, - (fb1_vsync) ? vsync_timestamp_fb1 : vsync_timestamp_fb0, - strerror(errno)); - ctx->vstate.fakevsync = true; + if (ctx->mExtDisplay->getHDMIIndex() > 0) + num_displays = 2; + else + num_displays = 1; + + char vsync_node_path[MAX_SYSFS_FILE_PATH]; + for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) { + snprintf(vsync_node_path, sizeof(vsync_node_path), + "/sys/class/graphics/fb%d/vsync_event", + dpy == HWC_DISPLAY_PRIMARY ? 0 : + ctx->mExtDisplay->getHDMIIndex()); + ALOGI("%s: Reading vsync for dpy=%d from %s", __FUNCTION__, dpy, + vsync_node_path); + fb_fd[dpy] = open(vsync_node_path, O_RDONLY); + + if (fb_fd[dpy] < 0) { + // Make sure fb device is opened before starting this thread so this + // never happens. + ALOGE ("%s:not able to open vsync node for dpy=%d, %s", + __FUNCTION__, dpy, strerror(errno)); + if (dpy == HWC_DISPLAY_PRIMARY) { + ctx->vstate.fakevsync = true; + break; + } + } + + pfd[dpy].fd = fb_fd[dpy]; + if (pfd[dpy].fd >= 0) + pfd[dpy].events = POLLPRI | POLLERR; } - do { - if (LIKELY(!ctx->vstate.fakevsync)) { - int err = poll(&pfd, 1, -1); + if (LIKELY(!ctx->vstate.fakevsync)) { + do { + int err = poll(pfd, num_displays, -1); if(err > 0) { - if (pfd.revents & POLLPRI) { - len = pread(fb0_fd, vdata, MAX_DATA, 0); - if (UNLIKELY(len < 0)) { - // If the read was just interrupted - it is not a fatal - // error. Just continue in this case - ALOGE ("FATAL:%s:not able to read file:%s, %s", - __FUNCTION__, - vsync_timestamp_fb0, strerror(errno)); - continue; - } - // extract timestamp - const char *str = vdata; - if (!strncmp(str, "VSYNC=", strlen("VSYNC="))) { - cur_timestamp = strtoull(str + strlen("VSYNC="), - NULL, 0); + for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) { + if (pfd[dpy].revents & POLLPRI) { + int len = pread(pfd[dpy].fd, vdata, MAX_DATA, 0); + if (UNLIKELY(len < 0)) { + // If the read was just interrupted - it is not a + // fatal error. Just continue in this case + ALOGE ("%s:Unable to read vsync for dpy=%d :%s", + __FUNCTION__, dpy, strerror(errno)); + continue; + } + // extract timestamp + if (!strncmp(vdata, "VSYNC=", strlen("VSYNC="))) { + timestamp[dpy] = strtoull(vdata + strlen("VSYNC="), + NULL, 0); + } + // send timestamp to SurfaceFlinger + ALOGD_IF (logvsync, + "%s: timestamp %llu sent to SF for dpy=%d", + __FUNCTION__, timestamp[dpy], dpy); + ctx->proc->vsync(ctx->proc, dpy, timestamp[dpy]); } } + } else { ALOGE("%s: vsync poll failed errno: %s", __FUNCTION__, - strerror(errno)); + strerror(errno)); continue; } - } else { + } while (true); + + } else { + + //Fake vsync is used only when set explicitly through a property or when + //the vsync timestamp node cannot be opened at bootup. There is no + //fallback to fake vsync from the true vsync loop, ever, as the + //condition can easily escape detection. + //Also, fake vsync is delivered only for the primary display. + do { usleep(16666); - cur_timestamp = systemTime(); - } - // send timestamp to HAL - if(ctx->vstate.enable) { - ALOGD_IF (logvsync, "%s: timestamp %llu sent to HWC for %s", - __FUNCTION__, cur_timestamp, "fb0"); - ctx->proc->vsync(ctx->proc, dpy, cur_timestamp); - } + timestamp[HWC_DISPLAY_PRIMARY] = systemTime(); + ctx->proc->vsync(ctx->proc, HWC_DISPLAY_PRIMARY, + timestamp[HWC_DISPLAY_PRIMARY]); + + } while (true); + } - } while (true); - if(fb0_fd >= 0) - close (fb0_fd); + for (int dpy = HWC_DISPLAY_PRIMARY; dpy <= HWC_DISPLAY_EXTERNAL; dpy++ ) { + if(fb_fd[dpy] >= 0) + close (fb_fd[dpy]); + } return NULL; } diff --git a/liboverlay/overlayMdssRot.cpp b/liboverlay/overlayMdssRot.cpp index 30d7ccd97..b8a2417b2 100644 --- a/liboverlay/overlayMdssRot.cpp +++ b/liboverlay/overlayMdssRot.cpp @@ -279,7 +279,7 @@ uint32_t MdssRot::calcCompressedBufSize() { int aHeight = ovutils::align(mRotInfo.src_rect.h, 4); int rau_cnt = aWidth/64; int stride0 = (64 * 4 * rau_cnt) + rau_cnt/8; - int stride1 = (64 * 2 * rau_cnt) + rau_cnt/8; + int stride1 = ((64 * 2 * rau_cnt) + rau_cnt/8) * 2; int stride0_off = (aHeight/4); int stride1_off = (aHeight/2); diff --git a/liboverlay/overlayMem.h b/liboverlay/overlayMem.h index 5fbe91bf7..061d197c6 100644 --- a/liboverlay/overlayMem.h +++ b/liboverlay/overlayMem.h @@ -121,8 +121,9 @@ inline bool OvMem::open(uint32_t numbufs, if(isSecure) { allocFlags = GRALLOC_USAGE_PRIVATE_MM_HEAP; allocFlags |= GRALLOC_USAGE_PROTECTED; - allocFlags |= GRALLOC_USAGE_PRIVATE_UNCACHED; } + // Allocate uncached rotator buffers + allocFlags |= GRALLOC_USAGE_PRIVATE_UNCACHED; int err = 0; OVASSERT(numbufs && bufSz, "numbufs=%d bufSz=%d", numbufs, bufSz); |