summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common.mk2
-rw-r--r--libexternal/external.h1
-rw-r--r--libgralloc/ionalloc.cpp4
-rw-r--r--libhwcomposer/hwc.cpp8
-rw-r--r--libhwcomposer/hwc_uevents.cpp3
-rw-r--r--libhwcomposer/hwc_utils.cpp18
-rw-r--r--libhwcomposer/hwc_vsync.cpp138
-rw-r--r--liboverlay/overlayMdssRot.cpp2
-rw-r--r--liboverlay/overlayMem.h3
9 files changed, 102 insertions, 77 deletions
diff --git a/common.mk b/common.mk
index 02867d715..aea5cf5b5 100644
--- a/common.mk
+++ b/common.mk
@@ -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);