Merge "gralloc: Fix NV12_ENCODEABLE allocation"
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index 2a4b1c5..65c78f7 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -341,6 +341,13 @@
__FUNCTION__, value);
}
break;
+ case COPYBIT_FG_LAYER:
+ if(value == COPYBIT_ENABLE) {
+ ctx->mFlags |= MDP_IS_FG;
+ } else if (value == COPYBIT_DISABLE) {
+ ctx->mFlags &= ~MDP_IS_FG;
+ }
+ break ;
default:
status = -EINVAL;
break;
diff --git a/libcopybit/copybit.h b/libcopybit/copybit.h
index 0f4332f..878eca4 100644
--- a/libcopybit/copybit.h
+++ b/libcopybit/copybit.h
@@ -77,6 +77,7 @@
COPYBIT_FRAMEBUFFER_WIDTH = 7,
/* FB height */
COPYBIT_FRAMEBUFFER_HEIGHT = 8,
+ COPYBIT_FG_LAYER = 9,
};
/* values for copybit_set_parameter(COPYBIT_TRANSFORM) */
diff --git a/libexternal/Android.mk b/libexternal/Android.mk
index f723113..3df6984 100644
--- a/libexternal/Android.mk
+++ b/libexternal/Android.mk
@@ -6,7 +6,7 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
-LOCAL_SHARED_LIBRARIES := $(common_libs) liboverlay
+LOCAL_SHARED_LIBRARIES := $(common_libs) liboverlay libqdutils
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdexternal\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := external.cpp
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index b247dfb..89d63e9 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -34,6 +34,7 @@
#include "external.h"
#include "overlayUtils.h"
#include "overlay.h"
+#include "mdp_version.h"
using namespace android;
@@ -65,6 +66,11 @@
return 0;
}
+void ExternalDisplay::getAttributes(int& width, int& height) {
+ int fps = 0;
+ getAttrForMode(width, height, fps);
+}
+
int ExternalDisplay::teardown() {
closeFrameBuffer();
resetInfo();
@@ -564,15 +570,38 @@
return ret;
}
+
void ExternalDisplay::setAttributes() {
int width = 0, height = 0, fps = 0;
getAttrForMode(width, height, fps);
-
ALOGD("ExtDisplay setting xres = %d, yres = %d", width, height);
- mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = width;
- mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = height;
- mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period =
- 1000000000l / fps;
+ if(mHwcContext) {
+ // Always set dpyAttr res to mVInfo res
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = width;
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = height;
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].mDownScaleMode = false;
+ if(!qdutils::MDPVersion::getInstance().is8x26()) {
+ int priW = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
+ int priH = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
+ // if primary resolution is more than the hdmi resolution
+ // configure dpy attr to primary resolution and set
+ // downscale mode
+ if((priW * priH) > (width * height)) {
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = priW;
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = priH;
+ // HDMI is always in landscape, so always assign the higher
+ // dimension to hdmi's xres
+ if(priH > priW) {
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = priH;
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = priW;
+ }
+ // Set External Display MDP Downscale mode indicator
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].mDownScaleMode =true;
+ }
+ }
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period =
+ 1000000000l / fps;
+ }
}
void ExternalDisplay::getAttrForMode(int& width, int& height, int& fps) {
diff --git a/libexternal/external.h b/libexternal/external.h
index 2fbb027..1a3602d 100644
--- a/libexternal/external.h
+++ b/libexternal/external.h
@@ -45,6 +45,7 @@
void setActionSafeDimension(int w, int h);
bool isCEUnderscanSupported() { return mUnderscanSupported; }
int configure();
+ void getAttributes(int& width, int& height);
int teardown();
bool isConnected() {
return mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].connected;
diff --git a/libgenlock/Android.mk b/libgenlock/Android.mk
deleted file mode 100644
index 96e8b4e..0000000
--- a/libgenlock/Android.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(LOCAL_PATH)/../common.mk
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libgenlock
-LOCAL_MODULE_TAGS := optional
-LOCAL_C_INCLUDES := $(common_includes)
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgenlock\"
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES := genlock.cpp
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libgenlock/genlock.cpp b/libgenlock/genlock.cpp
deleted file mode 100644
index c606ecc..0000000
--- a/libgenlock/genlock.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <cutils/log.h>
-#include <cutils/native_handle.h>
-#include <gralloc_priv.h>
-#include <linux/genlock.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-#include "genlock.h"
-
-#define GENLOCK_DEVICE "/dev/genlock"
-
-namespace {
-/* Internal function to map the userspace locks to the kernel lock types */
- int get_kernel_lock_type(genlock_lock_type lockType)
- {
- int kLockType = 0;
-#ifdef USE_GENLOCK
- // If the user sets both a read and write lock, higher preference is
- // given to the write lock.
- if (lockType & GENLOCK_WRITE_LOCK) {
- kLockType = GENLOCK_WRLOCK;
- } else if (lockType & GENLOCK_READ_LOCK) {
- kLockType = GENLOCK_RDLOCK;
- } else {
- ALOGE("%s: invalid lockType (lockType = %d)",
- __FUNCTION__, lockType);
- return -1;
- }
-#endif
- return kLockType;
- }
-
- /* Internal function to perform the actual lock/unlock operations */
- genlock_status_t perform_lock_unlock_operation(native_handle_t *buffer_handle,
- int lockType, int timeout,
- int flags)
- {
-#ifdef USE_GENLOCK
- if (private_handle_t::validate(buffer_handle)) {
- ALOGE("%s: handle is invalid", __FUNCTION__);
- return GENLOCK_FAILURE;
- }
-
- private_handle_t *hnd = reinterpret_cast<private_handle_t*>
- (buffer_handle);
- if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
- if (hnd->genlockPrivFd < 0) {
- ALOGE("%s: the lock has not been created,"
- "or has not been attached", __FUNCTION__);
- return GENLOCK_FAILURE;
- }
-
- genlock_lock lock;
- lock.op = lockType;
- lock.flags = flags;
- lock.timeout = timeout;
- lock.fd = hnd->genlockHandle;
-
-#ifdef GENLOCK_IOC_DREADLOCK
- if (ioctl(hnd->genlockPrivFd, GENLOCK_IOC_DREADLOCK, &lock)) {
- ALOGE("%s: GENLOCK_IOC_DREADLOCK failed (lockType0x%x,"
- "err=%s fd=%d)", __FUNCTION__,
- lockType, strerror(errno), hnd->fd);
- if (ETIMEDOUT == errno)
- return GENLOCK_TIMEDOUT;
-
- return GENLOCK_FAILURE;
- }
-#else
- // depreciated
- if (ioctl(hnd->genlockPrivFd, GENLOCK_IOC_LOCK, &lock)) {
- ALOGE("%s: GENLOCK_IOC_LOCK failed (lockType0x%x, err=%s fd=%d)"
- ,__FUNCTION__, lockType, strerror(errno), hnd->fd);
- if (ETIMEDOUT == errno)
- return GENLOCK_TIMEDOUT;
-
- return GENLOCK_FAILURE;
- }
-#endif
- }
-#endif
- return GENLOCK_NO_ERROR;
- }
-
- /* Internal function to close the fd and release the handle */
- void close_genlock_fd_and_handle(int& fd, int& handle)
- {
- if (fd >=0 ) {
- close(fd);
- fd = -1;
- }
-
- if (handle >= 0) {
- close(handle);
- handle = -1;
- }
- }
-}
-/*
- * Create a genlock lock. The genlock lock file descriptor and the lock
- * handle are stored in the buffer_handle.
- *
- * @param: handle of the buffer
- * @return error status.
- */
-genlock_status_t genlock_create_lock(native_handle_t *buffer_handle)
-{
- genlock_status_t ret = GENLOCK_NO_ERROR;
-#ifdef USE_GENLOCK
- if (private_handle_t::validate(buffer_handle)) {
- ALOGE("%s: handle is invalid", __FUNCTION__);
- return GENLOCK_FAILURE;
- }
-
- private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
- if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
- // Open the genlock device
- int fd = open(GENLOCK_DEVICE, O_RDWR);
- if (fd < 0) {
- ALOGE("%s: open genlock device failed (err=%s)", __FUNCTION__,
- strerror(errno));
- return GENLOCK_FAILURE;
- }
-
- // Create a new lock
- genlock_lock lock;
- if (ioctl(fd, GENLOCK_IOC_NEW, NULL)) {
- ALOGE("%s: GENLOCK_IOC_NEW failed (error=%s)", __FUNCTION__,
- strerror(errno));
- close_genlock_fd_and_handle(fd, lock.fd);
- ret = GENLOCK_FAILURE;
- }
-
- // Export the lock for other processes to be able to use it.
- if (GENLOCK_FAILURE != ret) {
- if (ioctl(fd, GENLOCK_IOC_EXPORT, &lock)) {
- ALOGE("%s: GENLOCK_IOC_EXPORT failed (error=%s)", __FUNCTION__,
- strerror(errno));
- close_genlock_fd_and_handle(fd, lock.fd);
- ret = GENLOCK_FAILURE;
- }
- }
-
- // Store the lock params in the handle.
- hnd->genlockPrivFd = fd;
- hnd->genlockHandle = lock.fd;
- } else {
- hnd->genlockHandle = 0;
- }
-#endif
- return ret;
-}
-
-
-/*
- * Release a genlock lock associated with the handle.
- *
- * @param: handle of the buffer
- * @return error status.
- */
-genlock_status_t genlock_release_lock(native_handle_t *buffer_handle)
-{
- genlock_status_t ret = GENLOCK_NO_ERROR;
-#ifdef USE_GENLOCK
- if (private_handle_t::validate(buffer_handle)) {
- ALOGE("%s: handle is invalid", __FUNCTION__);
- return GENLOCK_FAILURE;
- }
-
- private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
- if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
- if (hnd->genlockPrivFd < 0) {
- ALOGE("%s: the lock is invalid", __FUNCTION__);
- return GENLOCK_FAILURE;
- }
-
- // Close the fd and reset the parameters.
- close_genlock_fd_and_handle(hnd->genlockPrivFd, hnd->genlockHandle);
- }
-#endif
- return ret;
-}
-
-
-/*
- * Attach a lock to the buffer handle passed via an IPC.
- *
- * @param: handle of the buffer
- * @return error status.
- */
-genlock_status_t genlock_attach_lock(native_handle_t *buffer_handle)
-{
- genlock_status_t ret = GENLOCK_NO_ERROR;
-#ifdef USE_GENLOCK
- if (private_handle_t::validate(buffer_handle)) {
- ALOGE("%s: handle is invalid", __FUNCTION__);
- return GENLOCK_FAILURE;
- }
-
- private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
- if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
- // Open the genlock device
- int fd = open(GENLOCK_DEVICE, O_RDWR);
- if (fd < 0) {
- ALOGE("%s: open genlock device failed (err=%s)", __FUNCTION__,
- strerror(errno));
- return GENLOCK_FAILURE;
- }
-
- // Attach the local handle to an existing lock
- genlock_lock lock;
- lock.fd = hnd->genlockHandle;
- if (ioctl(fd, GENLOCK_IOC_ATTACH, &lock)) {
- ALOGE("%s: GENLOCK_IOC_ATTACH failed (err=%s)", __FUNCTION__,
- strerror(errno));
- close_genlock_fd_and_handle(fd, lock.fd);
- ret = GENLOCK_FAILURE;
- }
-
- // Store the relavant information in the handle
- hnd->genlockPrivFd = fd;
- }
-#endif
- return ret;
-}
-
-/*
- * Lock the buffer specified by the buffer handle. The lock held by the buffer
- * is specified by the lockType. This function will block if a write lock is
- * requested on the buffer which has previously been locked for a read or write
- * operation. A buffer can be locked by multiple clients for read. An optional
- * timeout value can be specified. By default, there is no timeout.
- *
- * @param: handle of the buffer
- * @param: type of lock to be acquired by the buffer.
- * @param: timeout value in ms. GENLOCK_MAX_TIMEOUT is the maximum timeout value.
- * @return error status.
- */
-genlock_status_t genlock_lock_buffer(native_handle_t *buffer_handle,
- genlock_lock_type_t lockType,
- int timeout)
-{
- genlock_status_t ret = GENLOCK_NO_ERROR;
-#ifdef USE_GENLOCK
- // Translate the locktype
- int kLockType = get_kernel_lock_type(lockType);
- if (-1 == kLockType) {
- ALOGE("%s: invalid lockType", __FUNCTION__);
- return GENLOCK_FAILURE;
- }
-
- if (0 == timeout) {
- ALOGW("%s: trying to lock a buffer with timeout = 0", __FUNCTION__);
- }
- // Call the private function to perform the lock operation specified.
- ret = perform_lock_unlock_operation(buffer_handle, kLockType, timeout, 0);
-#endif
- return ret;
-}
-
-
-/*
- * Unlocks a buffer that has previously been locked by the client.
- *
- * @param: handle of the buffer to be unlocked.
- * @return: error status.
- */
-genlock_status_t genlock_unlock_buffer(native_handle_t *buffer_handle)
-{
- genlock_status_t ret = GENLOCK_NO_ERROR;
-#ifdef USE_GENLOCK
- // Do the unlock operation by setting the unlock flag. Timeout is always
- // 0 in this case.
- ret = perform_lock_unlock_operation(buffer_handle, GENLOCK_UNLOCK, 0, 0);
-#endif
- return ret;
-}
-
-/*
- * Blocks the calling process until the lock held on the handle is unlocked.
- *
- * @param: handle of the buffer
- * @param: timeout value for the wait.
- * return: error status.
- */
-genlock_status_t genlock_wait(native_handle_t *buffer_handle, int timeout) {
-#ifdef USE_GENLOCK
- if (private_handle_t::validate(buffer_handle)) {
- ALOGE("%s: handle is invalid", __FUNCTION__);
- return GENLOCK_FAILURE;
- }
-
- private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
- if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
- if (hnd->genlockPrivFd < 0) {
- ALOGE("%s: the lock is invalid", __FUNCTION__);
- return GENLOCK_FAILURE;
- }
-
- if (0 == timeout)
- ALOGW("%s: timeout = 0", __FUNCTION__);
-
- genlock_lock lock;
- lock.fd = hnd->genlockHandle;
- lock.timeout = timeout;
- if (ioctl(hnd->genlockPrivFd, GENLOCK_IOC_WAIT, &lock)) {
- ALOGE("%s: GENLOCK_IOC_WAIT failed (err=%s)", __FUNCTION__,
- strerror(errno));
- return GENLOCK_FAILURE;
- }
- }
-#endif
- return GENLOCK_NO_ERROR;
-}
-
-/*
- * Convert a write lock that we own to a read lock
- *
- * @param: handle of the buffer
- * @param: timeout value for the wait.
- * return: error status.
- */
-genlock_status_t genlock_write_to_read(native_handle_t *buffer_handle,
- int timeout) {
- genlock_status_t ret = GENLOCK_NO_ERROR;
-#ifdef USE_GENLOCK
- if (0 == timeout) {
- ALOGW("%s: trying to lock a buffer with timeout = 0", __FUNCTION__);
- }
- // Call the private function to perform the lock operation specified.
-#ifdef GENLOCK_IOC_DREADLOCK
- ret = perform_lock_unlock_operation(buffer_handle, GENLOCK_RDLOCK, timeout,
- GENLOCK_WRITE_TO_READ);
-#else
- // depreciated
- ret = perform_lock_unlock_operation(buffer_handle, GENLOCK_RDLOCK,
- timeout, 0);
-#endif
-#endif
- return ret;
-}
diff --git a/libgenlock/genlock.h b/libgenlock/genlock.h
deleted file mode 100644
index 222f2a7..0000000
--- a/libgenlock/genlock.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef INCLUDE_LIBGENLOCK
-#define INCLUDE_LIBGENLOCK
-
-#include <cutils/native_handle.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
- /* Genlock lock types */
- typedef enum genlock_lock_type{
- GENLOCK_READ_LOCK = 1<<0, // Read lock
- GENLOCK_WRITE_LOCK = 1<<1, // Write lock
- }genlock_lock_type_t;
-
- /* Genlock return values */
- typedef enum genlock_status{
- GENLOCK_NO_ERROR = 0,
- GENLOCK_TIMEDOUT,
- GENLOCK_FAILURE,
- } genlock_status_t;
-
- /* Genlock defines */
-#define GENLOCK_MAX_TIMEOUT 1000 // Max 1s timeout
-
- /*
- * Create a genlock lock. The genlock lock file descriptor and the lock
- * handle are stored in the buffer_handle.
- *
- * @param: handle of the buffer
- * @return error status.
- */
- genlock_status_t genlock_create_lock(native_handle_t *buffer_handle);
-
-
- /*
- * Release a genlock lock associated with the handle.
- *
- * @param: handle of the buffer
- * @return error status.
- */
- genlock_status_t genlock_release_lock(native_handle_t *buffer_handle);
-
- /*
- * Attach a lock to the buffer handle passed via an IPC.
- *
- * @param: handle of the buffer
- * @return error status.
- */
- genlock_status_t genlock_attach_lock(native_handle_t *buffer_handle);
-
- /*
- * Lock the buffer specified by the buffer handle. The lock held by the
- * buffer is specified by the lockType. This function will block if a write
- * lock is requested on the buffer which has previously been locked for a
- * read or write operation. A buffer can be locked by multiple clients for
- * read. An optional timeout value can be specified.
- * By default, there is no timeout.
- *
- * @param: handle of the buffer
- * @param: type of lock to be acquired by the buffer.
- * @param: timeout value in ms. GENLOCK_MAX_TIMEOUT is the maximum timeout
- * value.
- * @return error status.
- */
- genlock_status_t genlock_lock_buffer(native_handle_t *buffer_handle,
- genlock_lock_type_t lockType,
- int timeout);
-
- /*
- * Unlocks a buffer that has previously been locked by the client.
- *
- * @param: handle of the buffer to be unlocked.
- * @return: error status.
- */
- genlock_status_t genlock_unlock_buffer(native_handle_t *buffer_handle);
-
- /*
- * Blocks the calling process until the lock held on the handle is unlocked.
- *
- * @param: handle of the buffer
- * @param: timeout value for the wait.
- * return: error status.
- */
- genlock_status_t genlock_wait(native_handle_t *buffer_handle, int timeout);
-
- /*
- * Convert a write lock that we own to a read lock
- *
- * @param: handle of the buffer
- * @param: timeout value for the wait.
- * return: error status.
- */
- genlock_status_t genlock_write_to_read(native_handle_t *buffer_handle,
- int timeout);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 1f757bc..1b3e934 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -109,11 +109,17 @@
#ifndef MDSS_TARGET
flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
#else
- if (usage & (GRALLOC_USAGE_HW_TEXTURE |
- GRALLOC_USAGE_HW_VIDEO_ENCODER))
+ // Per the camera spec ITU 709 format should be set only for
+ // video encoding.
+ // It should be set to ITU 601 full range format for any other
+ // camera buffer
+ //
+ if (usage & GRALLOC_USAGE_HW_CAMERA_MASK) {
+ if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
flags |= private_handle_t::PRIV_FLAGS_ITU_R_709;
- else if (usage & GRALLOC_USAGE_HW_CAMERA_ZSL)
+ else
flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
+ }
#endif
} else {
flags |= private_handle_t::PRIV_FLAGS_ITU_R_601;
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 558cc29..f90420f 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -118,6 +118,8 @@
ctx->mFBUpdate[i]->reset();
if(ctx->mCopyBit[i])
ctx->mCopyBit[i]->reset();
+ if(ctx->mLayerRotMap[i])
+ ctx->mLayerRotMap[i]->reset();
}
ctx->mAD->reset();
@@ -258,6 +260,7 @@
ctx->mBlankLock.lock();
//Will be unlocked at the end of set
ctx->mExtLock.lock();
+ ctx->mSecureLock.lock();
reset(ctx, numDisplays, displays);
ctx->mOverlay->configBegin();
@@ -612,6 +615,7 @@
MDPComp::resetIdleFallBack();
ctx->mVideoTransFlag = false;
//Was locked at the beginning of prepare
+ ctx->mSecureLock.unlock();
ctx->mExtLock.unlock();
ctx->mBlankLock.unlock();
return ret;
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index a701eb6..068e28a 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -291,7 +291,7 @@
list->hwLayers[i].acquireFenceFd = -1;
}
retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]),
- renderBuffer, dpy);
+ renderBuffer, dpy, !i);
copybitLayerCount++;
if(retVal < 0) {
ALOGE("%s : drawLayerUsingCopybit failed", __FUNCTION__);
@@ -307,7 +307,7 @@
}
int CopyBit::drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
- private_handle_t *renderBuffer, int dpy)
+ private_handle_t *renderBuffer, int dpy, bool isFG)
{
hwc_context_t* ctx = (hwc_context_t*)(dev);
int err = 0, acquireFd;
@@ -411,7 +411,7 @@
dtdy < 1/copybitsMinScale){
// The requested scale is out of the range the hardware
// can support.
- ALOGE("%s:%d::Need to scale twice dsdx=%f, dtdy=%f,copybitsMaxScale=%f,\
+ ALOGD("%s:%d::Need to scale twice dsdx=%f, dtdy=%f,copybitsMaxScale=%f,\
copybitsMinScale=%f,screen_w=%d,screen_h=%d \
src_crop_width=%d src_crop_height=%d",__FUNCTION__,__LINE__,
dsdx,dtdy,copybitsMaxScale,1/copybitsMinScale,screen_w,screen_h,
@@ -436,7 +436,7 @@
tmp_w = (tmp_w/2)*2;
tmp_h = (tmp_h/2)*2;
}
- ALOGE("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h);
+ ALOGD("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h);
int usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
int format = fbHandle->format;
@@ -504,6 +504,9 @@
copybit->set_parameter(copybit, COPYBIT_DITHER,
(dst.format == HAL_PIXEL_FORMAT_RGB_565)?
COPYBIT_ENABLE : COPYBIT_DISABLE);
+ copybit->set_parameter(copybit, COPYBIT_FG_LAYER, isFG ?
+ COPYBIT_ENABLE : COPYBIT_DISABLE);
+
copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,
COPYBIT_ENABLE);
copybit->set_sync(copybit, acquireFd);
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 31de9ee..03fe950 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -49,7 +49,7 @@
struct copybit_device_t *mEngine;
// Helper functions for copybit composition
int drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
- private_handle_t *renderBuffer, int dpy);
+ private_handle_t *renderBuffer, int dpy, bool isFG);
bool canUseCopybitForYUV (hwc_context_t *ctx);
bool canUseCopybitForRGB (hwc_context_t *ctx,
hwc_display_contents_1_t *list, int dpy);
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index ba3b5d2..a0f5faa 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -26,10 +26,12 @@
#include "hwc_fbupdate.h"
#include "mdp_version.h"
#include "external.h"
+#include "virtual.h"
using namespace qdutils;
using namespace overlay;
using overlay::Rotator;
+using namespace overlay::utils;
namespace qhwc {
@@ -110,51 +112,46 @@
hwc_rect_t sourceCrop = layer->sourceCrop;
hwc_rect_t displayFrame = layer->displayFrame;
int transform = layer->transform;
- int fbWidth = ctx->dpyAttr[mDpy].xres;
- int fbHeight = ctx->dpyAttr[mDpy].yres;
int rotFlags = ovutils::ROT_FLAGS_NONE;
ovutils::eTransform orient =
static_cast<ovutils::eTransform>(transform);
- if(mDpy && ctx->mExtOrientation) {
- // If there is a external orientation set, use that
- transform = ctx->mExtOrientation;
- orient = static_cast<ovutils::eTransform >(ctx->mExtOrientation);
- }
+ // use ext orientation if any
+ int extOrient = ctx->mExtOrientation;
+ if(ctx->mBufferMirrorMode)
+ extOrient = getMirrorModeOrientation(ctx);
// Do not use getNonWormholeRegion() function to calculate the
// sourceCrop during animation on external display and
// Dont do wormhole calculation when extorientation is set on External
+ // Dont do wormhole calculation when extDownscale is enabled on External
if(ctx->listStats[mDpy].isDisplayAnimating && mDpy) {
sourceCrop = layer->displayFrame;
displayFrame = sourceCrop;
- } else if((!mDpy || (mDpy && !ctx->mExtOrientation))
- && extOnlyLayerIndex == -1) {
+ } else if((!mDpy ||
+ (mDpy && !extOrient
+ && !ctx->dpyAttr[mDpy].mDownScaleMode))
+ && (extOnlyLayerIndex == -1)) {
if(!qdutils::MDPVersion::getInstance().is8x26()) {
getNonWormholeRegion(list, sourceCrop);
displayFrame = sourceCrop;
}
}
- ovutils::Dim dpos(displayFrame.left,
- displayFrame.top,
- displayFrame.right - displayFrame.left,
- displayFrame.bottom - displayFrame.top);
-
if(mDpy && !qdutils::MDPVersion::getInstance().is8x26()) {
- // Get Aspect Ratio for external
- getAspectRatioPosition(ctx, mDpy, ctx->mExtOrientation, dpos.x,
- dpos.y, dpos.w, dpos.h);
+ if(extOrient || ctx->dpyAttr[mDpy].mDownScaleMode) {
+ calcExtDisplayPosition(ctx, mDpy, sourceCrop, displayFrame);
+ // If there is a external orientation set, use that
+ if(extOrient) {
+ transform = extOrient;
+ orient = static_cast<ovutils::eTransform >(extOrient);
+ }
+ }
// Calculate the actionsafe dimensions for External(dpy = 1 or 2)
- getActionSafePosition(ctx, mDpy, dpos.x, dpos.y, dpos.w, dpos.h);
- // Convert dim to hwc_rect_t
- displayFrame.left = dpos.x;
- displayFrame.top = dpos.y;
- displayFrame.right = dpos.w + displayFrame.left;
- displayFrame.bottom = dpos.h + displayFrame.top;
+ getActionSafePosition(ctx, mDpy, displayFrame);
}
setMdpFlags(layer, mdpFlags, 0, transform);
// For External use rotator if there is a rotation value set
- if(mDpy && (ctx->mExtOrientation & HWC_TRANSFORM_ROT_90)) {
+ if(mDpy && (extOrient & HWC_TRANSFORM_ROT_90)) {
mRot = ctx->mRotMgr->getNext();
if(mRot == NULL) return -1;
//Configure rotator for pre-rotation
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 5c0ad4d..e97d769 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -123,20 +123,24 @@
sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
}
- long idle_timeout = DEFAULT_IDLE_TIME;
- if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
- if(atoi(property) != 0)
- idle_timeout = atoi(property);
- }
+ if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
+ // Idle invalidation is not necessary on command mode panels
+ long idle_timeout = DEFAULT_IDLE_TIME;
+ if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
+ if(atoi(property) != 0)
+ idle_timeout = atoi(property);
+ }
- //create Idle Invalidator only when not disabled through property
- if(idle_timeout != -1)
- idleInvalidator = IdleInvalidator::getInstance();
+ //create Idle Invalidator only when not disabled through property
+ if(idle_timeout != -1)
+ idleInvalidator = IdleInvalidator::getInstance();
- if(idleInvalidator == NULL) {
- ALOGE("%s: failed to instantiate idleInvalidator object", __FUNCTION__);
- } else {
- idleInvalidator->init(timeout_handler, ctx, idle_timeout);
+ if(idleInvalidator == NULL) {
+ ALOGE("%s: failed to instantiate idleInvalidator object",
+ __FUNCTION__);
+ } else {
+ idleInvalidator->init(timeout_handler, ctx, idle_timeout);
+ }
}
return true;
}
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index b27a88c..5d7d4d3 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -64,6 +64,9 @@
case IQService::EXTERNAL_ORIENTATION:
setExtOrientation(value);
break;
+ case IQService::BUFFER_MIRRORMODE:
+ setBufferMirrorMode(value);
+ break;
default:
return NO_ERROR;
}
@@ -71,6 +74,7 @@
}
void QClient::securing(uint32_t startEnd) {
+ Locker::Autolock _sl(mHwcContext->mSecureLock);
//The only way to make this class in this process subscribe to media
//player's death.
IMediaDeathNotifier::getMediaPlayerService();
@@ -84,6 +88,7 @@
}
void QClient::unsecuring(uint32_t startEnd) {
+ Locker::Autolock _sl(mHwcContext->mSecureLock);
mHwcContext->mSecuring = startEnd;
//We're done unsecuring
if(startEnd == IQService::END)
@@ -93,6 +98,7 @@
}
void QClient::MPDeathNotifier::died() {
+ Locker::Autolock _sl(mHwcContext->mSecureLock);
ALOGD_IF(QCLIENT_DEBUG, "Media Player died");
mHwcContext->mSecuring = false;
mHwcContext->mSecureMode = false;
@@ -115,4 +121,8 @@
mHwcContext->mExtOrientation = orientation;
}
+void QClient::setBufferMirrorMode(uint32_t enable) {
+ mHwcContext->mBufferMirrorMode = enable;
+}
+
}
diff --git a/libhwcomposer/hwc_qclient.h b/libhwcomposer/hwc_qclient.h
index 4cbabef..848d8d2 100644
--- a/libhwcomposer/hwc_qclient.h
+++ b/libhwcomposer/hwc_qclient.h
@@ -61,6 +61,7 @@
void unsecuring(uint32_t startEnd);
android::status_t screenRefresh();
void setExtOrientation(uint32_t orientation);
+ void setBufferMirrorMode(uint32_t enable);
hwc_context_t *mHwcContext;
const android::sp<android::IMediaDeathNotifier> mMPDeathNotifier;
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 0e2eb2e..fa3c15f 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -159,6 +159,9 @@
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = false;
ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = false;
ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected = false;
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].mDownScaleMode= false;
+ ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].mDownScaleMode = false;
+ ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].mDownScaleMode = false;
ctx->mMDPComp[HWC_DISPLAY_PRIMARY] =
MDPComp::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
@@ -193,6 +196,8 @@
ctx->mPrevDestVideo.right = ctx->mPrevDestVideo.bottom = 0;
ctx->mPrevTransformVideo = 0;
+ ctx->mBufferMirrorMode = false;
+
ALOGI("Initializing Qualcomm Hardware Composer");
ALOGI("MDP version: %d", ctx->mMDP.version);
}
@@ -262,8 +267,11 @@
}
/* Calculates the destination position based on the action safe rectangle */
-void getActionSafePosition(hwc_context_t *ctx, int dpy, uint32_t& x,
- uint32_t& y, uint32_t& w, uint32_t& h) {
+void getActionSafePosition(hwc_context_t *ctx, int dpy, hwc_rect_t& rect) {
+ // Position
+ int x = rect.left, y = rect.top;
+ int w = rect.right - rect.left;
+ int h = rect.bottom - rect.top;
// if external supports underscan, do nothing
// it will be taken care in the driver
@@ -291,7 +299,11 @@
float fbHeight = ctx->dpyAttr[dpy].yres;
// Since external is rotated 90, need to swap width/height
- if(ctx->mExtOrientation & HWC_TRANSFORM_ROT_90)
+ int extOrient = ctx->mExtOrientation;
+ if(ctx->mBufferMirrorMode)
+ extOrient = getMirrorModeOrientation(ctx);
+
+ if(extOrient & HWC_TRANSFORM_ROT_90)
swap(fbWidth, fbHeight);
float asX = 0;
@@ -317,40 +329,245 @@
w = (wRatio * asW);
h = (hRatio * asH);
+ // Convert it back to hwc_rect_t
+ rect.left = x;
+ rect.top = y;
+ rect.right = w + rect.left;
+ rect.bottom = h + rect.top;
+
return;
}
-/* Calculates the aspect ratio for external based on the primary */
-void getAspectRatioPosition(hwc_context_t *ctx, int dpy, int orientation,
- uint32_t& x, uint32_t& y, uint32_t& w, uint32_t& h) {
- int fbWidth = ctx->dpyAttr[dpy].xres;
- int fbHeight = ctx->dpyAttr[dpy].yres;
+/* Calculates the aspect ratio for based on src & dest */
+void getAspectRatioPosition(int destWidth, int destHeight, int srcWidth,
+ int srcHeight, hwc_rect_t& rect) {
+ int x =0, y =0;
- switch(orientation) {
- case HAL_TRANSFORM_ROT_90:
- case HAL_TRANSFORM_ROT_270:
- y = 0;
- h = fbHeight;
- if (ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres <
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres) {
- // Portrait primary panel
- w = (ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres *
- fbHeight/ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres);
- } else {
- //Landscape primary panel
- w = (ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres *
- fbHeight/ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres);
- }
- x = (fbWidth - w)/2;
- break;
- default:
- //Do nothing
- break;
- }
- ALOGD_IF(HWC_UTILS_DEBUG, "%s: Position: x = %d, y = %d w = %d h = %d",
- __FUNCTION__, x, y, w ,h);
+ if (srcWidth * destHeight > destWidth * srcHeight) {
+ srcHeight = destWidth * srcHeight / srcWidth;
+ srcWidth = destWidth;
+ } else if (srcWidth * destHeight < destWidth * srcHeight) {
+ srcWidth = destHeight * srcWidth / srcHeight;
+ srcHeight = destHeight;
+ } else {
+ srcWidth = destWidth;
+ srcHeight = destHeight;
+ }
+ if (srcWidth > destWidth) srcWidth = destWidth;
+ if (srcHeight > destHeight) srcHeight = destHeight;
+ x = (destWidth - srcWidth) / 2;
+ y = (destHeight - srcHeight) / 2;
+ ALOGD_IF(HWC_UTILS_DEBUG, "%s: AS Position: x = %d, y = %d w = %d h = %d",
+ __FUNCTION__, x, y, srcWidth , srcHeight);
+ // Convert it back to hwc_rect_t
+ rect.left = x;
+ rect.top = y;
+ rect.right = srcWidth + rect.left;
+ rect.bottom = srcHeight + rect.top;
}
+// This function gets the destination position for Seconday display
+// based on the position and aspect ratio with orientation
+void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
+ hwc_rect_t& inRect, hwc_rect_t& outRect) {
+ // Physical display resolution
+ float fbWidth = ctx->dpyAttr[dpy].xres;
+ float fbHeight = ctx->dpyAttr[dpy].yres;
+ //display position(x,y,w,h) in correct aspectratio after rotation
+ int xPos = 0;
+ int yPos = 0;
+ float width = fbWidth;
+ float height = fbHeight;
+ // Width/Height used for calculation, after rotation
+ float actualWidth = fbWidth;
+ float actualHeight = fbHeight;
+
+ float wRatio = 1.0;
+ float hRatio = 1.0;
+ float xRatio = 1.0;
+ float yRatio = 1.0;
+ hwc_rect_t rect = {0, 0, (int)fbWidth, (int)fbHeight};
+
+ Dim inPos(inRect.left, inRect.top, inRect.right - inRect.left,
+ inRect.bottom - inRect.top);
+ Dim outPos(outRect.left, outRect.top, outRect.right - outRect.left,
+ outRect.bottom - outRect.top);
+
+ Whf whf(fbWidth, fbHeight, 0);
+ eTransform extorient = static_cast<eTransform>(extOrientation);
+ // To calculate the destination co-ordinates in the new orientation
+ preRotateSource(extorient, whf, inPos);
+
+ if(extOrientation & HAL_TRANSFORM_ROT_90) {
+ // Swap width/height for input position
+ swapWidthHeight(actualWidth, actualHeight);
+ getAspectRatioPosition(fbWidth, fbHeight, (int)actualWidth,
+ (int)actualHeight, rect);
+ xPos = rect.left;
+ yPos = rect.top;
+ width = rect.right - rect.left;
+ height = rect.bottom - rect.top;
+ }
+
+ //Calculate the position...
+ xRatio = inPos.x/actualWidth;
+ yRatio = inPos.y/actualHeight;
+ wRatio = inPos.w/actualWidth;
+ hRatio = inPos.h/actualHeight;
+
+ outPos.x = (xRatio * width) + xPos;
+ outPos.y = (yRatio * height) + yPos;
+ outPos.w = wRatio * width;
+ outPos.h = hRatio * height;
+ ALOGD_IF(HWC_UTILS_DEBUG, "%s: Calculated AspectRatio Position: x = %d,"
+ "y = %d w = %d h = %d", __FUNCTION__, outPos.x, outPos.y,
+ outPos.w, outPos.h);
+
+ // For sidesync, the dest fb will be in portrait orientation, and the crop
+ // will be updated to avoid the black side bands, and it will be upscaled
+ // to fit the dest RB, so recalculate
+ // the position based on the new width and height
+ if ((extOrientation & HWC_TRANSFORM_ROT_90) &&
+ isOrientationPortrait(ctx)) {
+ hwc_rect_t r;
+ //Calculate the position
+ xRatio = (outPos.x - xPos)/width;
+ // GetaspectRatio -- tricky to get the correct aspect ratio
+ // But we need to do this.
+ getAspectRatioPosition(width, height, width, height, r);
+ xPos = r.left;
+ yPos = r.top;
+ float tempWidth = r.right - r.left;
+ float tempHeight = r.bottom - r.top;
+ yRatio = yPos/height;
+ wRatio = outPos.w/width;
+ hRatio = tempHeight/height;
+
+ //Map the coordinates back to Framebuffer domain
+ outPos.x = (xRatio * fbWidth);
+ outPos.y = (yRatio * fbHeight);
+ outPos.w = wRatio * fbWidth;
+ outPos.h = hRatio * fbHeight;
+
+ ALOGD_IF(HWC_UTILS_DEBUG, "%s: Calculated AspectRatio for device in"
+ "portrait: x = %d,y = %d w = %d h = %d", __FUNCTION__,
+ outPos.x, outPos.y,
+ outPos.w, outPos.h);
+ }
+ if(ctx->dpyAttr[dpy].mDownScaleMode) {
+ int extW, extH;
+ if(dpy == HWC_DISPLAY_EXTERNAL)
+ ctx->mExtDisplay->getAttributes(extW, extH);
+ else
+ ctx->mVirtualDisplay->getAttributes(extW, extH);
+ fbWidth = ctx->dpyAttr[dpy].xres;
+ fbHeight = ctx->dpyAttr[dpy].yres;
+ //Calculate the position...
+ xRatio = outPos.x/fbWidth;
+ yRatio = outPos.y/fbHeight;
+ wRatio = outPos.w/fbWidth;
+ hRatio = outPos.h/fbHeight;
+
+ outPos.x = xRatio * extW;
+ outPos.y = yRatio * extH;
+ outPos.w = wRatio * extW;
+ outPos.h = hRatio * extH;
+ }
+ // Convert Dim to hwc_rect_t
+ outRect.left = outPos.x;
+ outRect.top = outPos.y;
+ outRect.right = outPos.x + outPos.w;
+ outRect.bottom = outPos.y + outPos.h;
+
+ return;
+}
+
+bool isPrimaryPortrait(hwc_context_t *ctx) {
+ int fbWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
+ int fbHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
+ if(fbWidth < fbHeight) {
+ return true;
+ }
+ return false;
+}
+
+bool isOrientationPortrait(hwc_context_t *ctx) {
+ if(isPrimaryPortrait(ctx)) {
+ return !(ctx->deviceOrientation & 0x1);
+ }
+ return (ctx->deviceOrientation & 0x1);
+}
+
+void calcExtDisplayPosition(hwc_context_t *ctx, int dpy,
+ hwc_rect_t& sourceCrop,
+ hwc_rect_t& displayFrame) {
+ // Swap width and height when there is a 90deg transform
+ int extOrient = ctx->mExtOrientation;
+ if(ctx->mBufferMirrorMode)
+ extOrient = getMirrorModeOrientation(ctx);
+ if(extOrient & HWC_TRANSFORM_ROT_90) {
+ int dstWidth = ctx->dpyAttr[dpy].xres;
+ int dstHeight = ctx->dpyAttr[dpy].yres;;
+ int srcWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
+ int srcHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
+ if(!isPrimaryPortrait(ctx)) {
+ swap(srcWidth, srcHeight);
+ } // Get Aspect Ratio for external
+ getAspectRatioPosition(dstWidth, dstHeight, srcWidth,
+ srcHeight, displayFrame);
+ // Crop - this is needed, because for sidesync, the dest fb will
+ // be in portrait orientation, so update the crop to not show the
+ // black side bands.
+ if (isOrientationPortrait(ctx)) {
+ sourceCrop = displayFrame;
+ displayFrame.left = 0;
+ displayFrame.top = 0;
+ displayFrame.right = dstWidth;
+ displayFrame.bottom = dstHeight;
+ }
+ }
+ if(ctx->dpyAttr[dpy].mDownScaleMode) {
+ int extW, extH;
+ // if downscale is enabled, map the co-ordinates to new
+ // domain(downscaled)
+ float fbWidth = ctx->dpyAttr[dpy].xres;
+ float fbHeight = ctx->dpyAttr[dpy].yres;
+ // query MDP configured attributes
+ if(dpy == HWC_DISPLAY_EXTERNAL)
+ ctx->mExtDisplay->getAttributes(extW, extH);
+ else
+ ctx->mVirtualDisplay->getAttributes(extW, extH);
+ //Calculate the ratio...
+ float wRatio = ((float)extW)/fbWidth;
+ float hRatio = ((float)extH)/fbHeight;
+
+ //convert Dim to hwc_rect_t
+ displayFrame.left *= wRatio;
+ displayFrame.top *= hRatio;
+ displayFrame.right *= wRatio;
+ displayFrame.bottom *= hRatio;
+ }
+}
+
+/* Returns the orientation which needs to be set on External for
+ * SideSync/Buffer Mirrormode
+ */
+int getMirrorModeOrientation(hwc_context_t *ctx) {
+ int extOrientation = 0;
+ int deviceOrientation = ctx->deviceOrientation;
+ if(!isPrimaryPortrait(ctx))
+ deviceOrientation = (deviceOrientation + 1) % 4;
+ if (deviceOrientation == 0)
+ extOrientation = HWC_TRANSFORM_ROT_270;
+ else if (deviceOrientation == 1)//90
+ extOrientation = 0;
+ else if (deviceOrientation == 2)//180
+ extOrientation = HWC_TRANSFORM_ROT_90;
+ else if (deviceOrientation == 3)//270
+ extOrientation = HWC_TRANSFORM_FLIP_V | HWC_TRANSFORM_FLIP_H;
+
+ return extOrientation;
+}
bool needsScaling(hwc_context_t* ctx, hwc_layer_1_t const* layer,
const int& dpy) {
@@ -474,9 +691,10 @@
ctx->mExtOrientation = atoi(value); */
// Assuming the orientation value is in terms of HAL_TRANSFORM,
// This needs mapping to HAL, if its in different convention
- if(ctx->mExtOrientation) {
- ALOGD_IF(HWC_UTILS_DEBUG, "%s: ext orientation = %d",
- __FUNCTION__, ctx->mExtOrientation);
+ if(ctx->mExtOrientation || ctx->mBufferMirrorMode) {
+ ALOGD_IF(HWC_UTILS_DEBUG, "%s: ext orientation = %d"
+ "BufferMirrorMode = %d", __FUNCTION__,
+ ctx->mExtOrientation, ctx->mBufferMirrorMode);
if(ctx->mOverlay->isPipeTypeAttached(OV_MDP_PIPE_DMA)) {
ctx->isPaddingRound = true;
}
@@ -975,22 +1193,21 @@
}
}
}
-
- uint32_t x = dst.left, y = dst.top;
- uint32_t w = dst.right - dst.left;
- uint32_t h = dst.bottom - dst.top;
-
if(dpy) {
+ int extOrient = ctx->mExtOrientation;
+ if(ctx->mBufferMirrorMode)
+ extOrient = getMirrorModeOrientation(ctx);
// Just need to set the position to portrait as the transformation
// will already be set to required orientation on TV
- getAspectRatioPosition(ctx, dpy, ctx->mExtOrientation, x, y, w, h);
+ if(extOrient || ctx->dpyAttr[dpy].mDownScaleMode) {
+ getAspectRatioPosition(ctx, dpy, extOrient, dst, dst);
+ if(extOrient) {
+ transform = extOrient;
+ orient = static_cast<eTransform>(transform);
+ }
+ }
// Calculate the actionsafe dimensions for External(dpy = 1 or 2)
- getActionSafePosition(ctx, dpy, x, y, w, h);
- // Convert position to hwc_rect_t
- dst.left = x;
- dst.top = y;
- dst.right = w + dst.left;
- dst.bottom = h + dst.top;
+ getActionSafePosition(ctx, dpy, dst);
}
if(isYuvBuffer(hnd) && ctx->mMDP.version >= qdutils::MDP_V4_2 &&
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 9a7ef0d..71b51ab 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -83,6 +83,8 @@
// To trigger padding round to clean up mdp
// pipes
bool isConfiguring;
+ // External Display is in MDP Downscale mode indicator
+ bool mDownScaleMode;
};
struct ListStats {
@@ -175,12 +177,25 @@
void dumpsys_log(android::String8& buf, const char* fmt, ...);
/* Calculates the destination position based on the action safe rectangle */
-void getActionSafePosition(hwc_context_t *ctx, int dpy, uint32_t& x,
- uint32_t& y, uint32_t& w, uint32_t& h);
+void getActionSafePosition(hwc_context_t *ctx, int dpy, hwc_rect_t& dst);
+void getAspectRatioPosition(int destWidth, int destHeight, int srcWidth,
+ int srcHeight, hwc_rect_t& rect);
-void getAspectRatioPosition(hwc_context_t *ctx, int dpy, int orientation,
- uint32_t& x, uint32_t& y, uint32_t& w, uint32_t& h);
+void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
+ hwc_rect_t& inRect, hwc_rect_t& outRect);
+
+bool isPrimaryPortrait(hwc_context_t *ctx);
+
+bool isOrientationPortrait(hwc_context_t *ctx);
+
+void calcExtDisplayPosition(hwc_context_t *ctx,
+ int dpy,
+ hwc_rect_t& sourceCrop,
+ hwc_rect_t& displayFrame);
+// Returns the orientation that needs to be set on external for
+// BufferMirrirMode(Sidesync)
+int getMirrorModeOrientation(hwc_context_t *ctx);
//Close acquireFenceFds of all layers of incoming list
void closeAcquireFds(hwc_display_contents_1_t* list);
@@ -346,12 +361,24 @@
mutable Locker mBlankLock;
//Lock to protect prepare & set when detaching external disp
mutable Locker mExtLock;
+ /*Lock to set both mSecureMode and mSecuring as part
+ of binder thread without context switch to composition
+ thread. This lock is needed only for A-family targets
+ since the state of mSecureMode and mSecuring variables
+ are not checked in B-family targets.
+ */
+ mutable Locker mSecureLock;
//Drawing round when we use GPU
bool isPaddingRound;
// External Orientation
int mExtOrientation;
//Flags the transition of a video session
bool mVideoTransFlag;
+
+ //Used for SideSync feature
+ //which overrides the mExtOrientation
+ bool mBufferMirrorMode;
+
qhwc::LayerRotMap *mLayerRotMap[HWC_NUM_DISPLAY_TYPES];
};
diff --git a/libqservice/IQService.cpp b/libqservice/IQService.cpp
index a3ff150..e45f42e 100644
--- a/libqservice/IQService.cpp
+++ b/libqservice/IQService.cpp
@@ -78,6 +78,13 @@
data.writeInt32(orientation);
remote()->transact(EXTERNAL_ORIENTATION, data, &reply);
}
+
+ virtual void setBufferMirrorMode(uint32_t enable) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IQService::getInterfaceDescriptor());
+ data.writeInt32(enable);
+ remote()->transact(BUFFER_MIRRORMODE, data, &reply);
+ }
};
IMPLEMENT_META_INTERFACE(QService, "android.display.IQService");
@@ -160,6 +167,18 @@
setExtOrientation(orientation);
return NO_ERROR;
} break;
+ case BUFFER_MIRRORMODE: {
+ CHECK_INTERFACE(IQService, data, reply);
+ if(callerUid != AID_SYSTEM) {
+ ALOGE("display.qservice BUFFER_MIRRORMODE access denied: \
+ pid=%d uid=%d process=%s",callerPid,
+ callerUid, callingProcName);
+ return PERMISSION_DENIED;
+ }
+ uint32_t enable = data.readInt32();
+ setBufferMirrorMode(enable);
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index ff034be..149cd8b 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -42,6 +42,7 @@
CONNECT,
SCREEN_REFRESH,
EXTERNAL_ORIENTATION,
+ BUFFER_MIRRORMODE,
};
enum {
END = 0,
@@ -52,6 +53,7 @@
virtual void connect(const android::sp<qClient::IQClient>& client) = 0;
virtual android::status_t screenRefresh() = 0;
virtual void setExtOrientation(uint32_t orientation) = 0;
+ virtual void setBufferMirrorMode(uint32_t enable) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/libqservice/QService.cpp b/libqservice/QService.cpp
index f780a75..a8c5dca 100644
--- a/libqservice/QService.cpp
+++ b/libqservice/QService.cpp
@@ -77,6 +77,12 @@
}
}
+void QService::setBufferMirrorMode(uint32_t enable) {
+ if(mClient.get()) {
+ mClient->notifyCallback(BUFFER_MIRRORMODE, enable);
+ }
+}
+
void QService::init()
{
if(!sQService) {
diff --git a/libqservice/QService.h b/libqservice/QService.h
index 8eefa21..a241d44 100644
--- a/libqservice/QService.h
+++ b/libqservice/QService.h
@@ -50,6 +50,7 @@
virtual void connect(const android::sp<qClient::IQClient>& client);
virtual android::status_t screenRefresh();
virtual void setExtOrientation(uint32_t orientation);
+ virtual void setBufferMirrorMode(uint32_t enable);
static void init();
private:
QService();
diff --git a/libtilerenderer/Android.mk b/libtilerenderer/Android.mk
deleted file mode 100644
index ca17fbc..0000000
--- a/libtilerenderer/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(LOCAL_PATH)/../common.mk
-include $(CLEAR_VARS)
-
-ifeq ($(USE_OPENGL_RENDERER),true)
-LOCAL_MODULE := libtilerenderer
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := -DLOG_TAG=\"qdtilerenderer\"
-LOCAL_C_INCLUDES := \
- frameworks/base/include/utils \
- frameworks/base/libs/hwui \
- external/skia/include/core \
- external/skia/include/effects \
- external/skia/include/images \
- external/skia/src/ports \
- external/skia/include/utils \
- hardware/libhardware/include/hardware \
- frameworks/base/opengl/include/GLES2
-LOCAL_SHARED_LIBRARIES := $(common_libs) libGLESv2 libhwui
-LOCAL_SRC_FILES := tilerenderer.cpp
-
-include $(BUILD_SHARED_LIBRARY)
-endif
diff --git a/libtilerenderer/tilerenderer.cpp b/libtilerenderer/tilerenderer.cpp
deleted file mode 100644
index 03a0aea..0000000
--- a/libtilerenderer/tilerenderer.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- *
- * 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.
- */
-
-#include <GLES2/gl2.h>
-#include <EGL/egl.h>
-#include <gl2ext.h>
-#include <OpenGLRenderer.h>
-#include "tilerenderer.h"
-
-namespace android {
-ANDROID_SINGLETON_STATIC_INSTANCE(uirenderer::TileRenderer) ;
-namespace uirenderer {
-
-TileRenderer::TileRenderer() {
- mIsTiled = false;
-}
-
-TileRenderer::~TileRenderer() {
-}
-
-void TileRenderer::startTileRendering(OpenGLRenderer* renderer,
- int left, int top,
- int right, int bottom) {
- int width = 0;
- int height = 0;
- GLenum status = GL_NO_ERROR;
-
- if (renderer != NULL) {
- renderer->getViewport(width, height);
- }
-
- if (!left && !right && !top && !bottom) {
- left = 0;
- top = 0;
- right = width;
- bottom = height;
- }
-
- if (!left && !right && !top && !bottom) {
- //can't do tile rendering
- ALOGE("can't tile render; drity region, width, height not available");
- return;
- }
-
- int l = left, t = (height - bottom), w = (right - left), h = (bottom - top), preserve = 0;
-
- if (l < 0 || t < 0) {
- l = (l < 0) ? 0 : l;
- t = (t < 0) ? 0 : t;
- preserve = 1;
- }
-
- if (w > width || h > height) {
- w = (w > width) ? width : w;
- h = (h > height) ? height : h;
- preserve = 1;
- }
-
- //clear off all errors before tiling, if any
- while ((status = glGetError()) != GL_NO_ERROR);
-
- if (preserve)
- glStartTilingQCOM(l, t, w, h, GL_COLOR_BUFFER_BIT0_QCOM);
- else
- glStartTilingQCOM(l, t, w, h, GL_NONE);
-
- status = glGetError();
- if (status == GL_NO_ERROR)
- mIsTiled = true;
-}
-
-void TileRenderer::endTileRendering(OpenGLRenderer*) {
- if (!mIsTiled) {
- return;
- }
- glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
- mIsTiled = false;
- GLenum status = GL_NO_ERROR;
- while ((status = glGetError()) != GL_NO_ERROR);
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libtilerenderer/tilerenderer.h b/libtilerenderer/tilerenderer.h
deleted file mode 100644
index d894d33..0000000
--- a/libtilerenderer/tilerenderer.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- *
- * 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.
- */
-#ifndef ANDROID_TILE_RENDERER_H
-#define ANDROID_TILE_RENDERER_H
-
-#include <utils/Singleton.h>
-
-namespace android {
-namespace uirenderer {
-
-class OpenGLRenderer;
-
-class TileRenderer: public Singleton<TileRenderer> {
- public:
- TileRenderer();
- ~TileRenderer();
-
- void startTileRendering(OpenGLRenderer* renderer, int left, int top, int right, int bottom);
- void endTileRendering(OpenGLRenderer*);
-
- private:
- bool mIsTiled;
-};
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif
diff --git a/libvirtual/Android.mk b/libvirtual/Android.mk
index 1231f8d..beeef25 100644
--- a/libvirtual/Android.mk
+++ b/libvirtual/Android.mk
@@ -6,7 +6,7 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
-LOCAL_SHARED_LIBRARIES := $(common_libs) liboverlay
+LOCAL_SHARED_LIBRARIES := $(common_libs) liboverlay libqdutils
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdvirtual\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := virtual.cpp
diff --git a/libvirtual/virtual.cpp b/libvirtual/virtual.cpp
index e2f239a..8e96a56 100644
--- a/libvirtual/virtual.cpp
+++ b/libvirtual/virtual.cpp
@@ -47,6 +47,7 @@
#include "virtual.h"
#include "overlayUtils.h"
#include "overlay.h"
+#include "mdp_version.h"
using namespace android;
@@ -67,6 +68,11 @@
return 0;
}
+void VirtualDisplay::getAttributes(int& width, int& height) {
+ width = mVInfo.xres;
+ height = mVInfo.yres;
+}
+
int VirtualDisplay::teardown() {
closeFrameBuffer();
memset(&mVInfo, 0, sizeof(mVInfo));
@@ -85,12 +91,35 @@
}
void VirtualDisplay::setAttributes() {
- mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].xres = mVInfo.xres;
- mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].yres = mVInfo.yres;
- mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].vsync_period =
- 1000000000l /60;
- ALOGD_IF(DEBUG,"%s: Setting Virtual Attr: res(%d x %d)",__FUNCTION__,
- mVInfo.xres, mVInfo.yres);
+ if(mHwcContext) {
+ // Always set dpyAttr res to mVInfo res
+ mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].xres = mVInfo.xres;
+ mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].yres = mVInfo.yres;
+ mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].mDownScaleMode = false;
+ if(!qdutils::MDPVersion::getInstance().is8x26()) {
+ uint32_t priW = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
+ uint32_t priH = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
+ // if primary resolution is more than the wfd resolution
+ // configure dpy attr to primary resolution and set
+ // downscale mode
+ if((priW * priH) > (mVInfo.xres * mVInfo.yres)) {
+ mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].xres = priW;
+ mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].yres = priH;
+ // WFD is always in landscape, so always assign the higher
+ // dimension to wfd's xres
+ if(priH > priW) {
+ mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].xres = priH;
+ mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].yres = priW;
+ }
+ // Set External Display MDP Downscale mode indicator
+ mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].mDownScaleMode = true;
+ }
+ }
+ mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].vsync_period =
+ 1000000000l /60;
+ ALOGD_IF(DEBUG,"%s: Setting Virtual Attr: res(%d x %d)",__FUNCTION__,
+ mVInfo.xres, mVInfo.yres);
+ }
}
bool VirtualDisplay::openFrameBuffer()
diff --git a/libvirtual/virtual.h b/libvirtual/virtual.h
index cd0e7da..8003e23 100644
--- a/libvirtual/virtual.h
+++ b/libvirtual/virtual.h
@@ -43,6 +43,7 @@
VirtualDisplay(hwc_context_t* ctx);
~VirtualDisplay();
int configure();
+ void getAttributes(int& width, int& height);
int teardown();
bool isConnected() {
return mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].connected;