Merge "hqd: Use MSM_VIDC_TARGET_LIST for Venus color format"
diff --git a/Android.mk b/Android.mk
index 772b66e..d8b168d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,5 +1,5 @@
display-hals := libgralloc libgenlock libcopybit liblight
-display-hals += libhwcomposer liboverlay libqdutils libexternal libqservice
+display-hals += libhwcomposer liboverlay libqdutils libhdmi libqservice
display-hals += libmemtrack
ifeq ($(call is-vendor-board-platform,QCOM),true)
include $(call all-named-subdir-makefiles,$(display-hals))
diff --git a/common.mk b/common.mk
index 18b5d4a..5a7e81f 100644
--- a/common.mk
+++ b/common.mk
@@ -4,7 +4,7 @@
common_includes += $(LOCAL_PATH)/../libcopybit
common_includes += $(LOCAL_PATH)/../libqdutils
common_includes += $(LOCAL_PATH)/../libhwcomposer
-common_includes += $(LOCAL_PATH)/../libexternal
+common_includes += $(LOCAL_PATH)/../libhdmi
common_includes += $(LOCAL_PATH)/../libqservice
ifeq ($(TARGET_USES_POST_PROCESSING),true)
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index 84d7620..2302d64 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -37,6 +37,7 @@
#include "gralloc_priv.h"
#include "software_converter.h"
+#include <qdMetaData.h>
#define DEBUG_MDP_ERRORS 1
@@ -504,6 +505,13 @@
flags |= MDP_BLIT_NON_CACHED;
}
+ // Set Color Space for MDP to configure CSC matrix
+ req->color_space = ITU_R_601;
+ MetaData_t *metadata = (MetaData_t *)src_hnd->base_metadata;
+ if (metadata && (metadata->operation & UPDATE_COLOR_SPACE)) {
+ req->color_space = metadata->colorSpace;
+ }
+
set_infos(ctx, req, flags);
set_image(&req->dst, dst);
set_image(&req->src, src);
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 5ba737a..943e64f 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -63,12 +63,15 @@
return -EINVAL;
private_handle_t* hnd = (private_handle_t*)handle;
+ unsigned int size = 0;
+ int err = 0;
+ IMemAlloc* memalloc = getAllocator(hnd->flags) ;
void *mappedAddress;
+ // Dont map FRAMEBUFFER and SECURE_BUFFERS
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
!(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) {
- unsigned int size = hnd->size;
- IMemAlloc* memalloc = getAllocator(hnd->flags) ;
- int err = memalloc->map_buffer(&mappedAddress, size,
+ size = hnd->size;
+ err = memalloc->map_buffer(&mappedAddress, size,
hnd->offset, hnd->fd);
if(err || mappedAddress == MAP_FAILED) {
ALOGE("Could not mmap handle %p, fd=%d (%s)",
@@ -78,6 +81,10 @@
}
hnd->base = uint64_t(mappedAddress) + hnd->offset;
+ }
+
+ //Allow mapping of metadata for all buffers and SECURE_BUFFER
+ if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
mappedAddress = MAP_FAILED;
size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
err = memalloc->map_buffer(&mappedAddress, size,
diff --git a/libexternal/Android.mk b/libhdmi/Android.mk
similarity index 67%
rename from libexternal/Android.mk
rename to libhdmi/Android.mk
index 05e42d4..89ba4a9 100644
--- a/libexternal/Android.mk
+++ b/libhdmi/Android.mk
@@ -2,12 +2,12 @@
include $(LOCAL_PATH)/../common.mk
include $(CLEAR_VARS)
-LOCAL_MODULE := libexternal
+LOCAL_MODULE := libhdmi
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_SHARED_LIBRARIES := $(common_libs) liboverlay libqdutils
-LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdexternal\"
+LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhdmi\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES := external.cpp
+LOCAL_SRC_FILES := hdmi.cpp
include $(BUILD_SHARED_LIBRARY)
diff --git a/libexternal/external.cpp b/libhdmi/hdmi.cpp
similarity index 87%
rename from libexternal/external.cpp
rename to libhdmi/hdmi.cpp
index 28cf590..4fb7cfa 100644
--- a/libexternal/external.cpp
+++ b/libhdmi/hdmi.cpp
@@ -26,7 +26,7 @@
#include <sys/ioctl.h>
#include <cutils/properties.h>
#include "hwc_utils.h"
-#include "external.h"
+#include "hdmi.h"
#include "overlayUtils.h"
#include "overlay.h"
#include "qd_utils.h"
@@ -64,26 +64,37 @@
EDIDData(HDMI_VFRMT_720x480p60_16_9, 720, 480, 60, 8),
EDIDData(HDMI_VFRMT_720x576p50_4_3, 720, 576, 50, 9),
EDIDData(HDMI_VFRMT_720x576p50_16_9, 720, 576, 50, 10),
- EDIDData(HDMI_VFRMT_1024x768p60_4_3, 1024, 768, 60, 11),
- EDIDData(HDMI_VFRMT_1280x1024p60_5_4, 1280, 1024, 60, 12),
- EDIDData(HDMI_VFRMT_1280x720p50_16_9, 1280, 720, 50, 13),
- EDIDData(HDMI_VFRMT_1280x720p60_16_9, 1280, 720, 60, 14),
- EDIDData(HDMI_VFRMT_1920x1080p24_16_9, 1920, 1080, 24, 15),
- EDIDData(HDMI_VFRMT_1920x1080p25_16_9, 1920, 1080, 25, 16),
- EDIDData(HDMI_VFRMT_1920x1080p30_16_9, 1920, 1080, 30, 17),
- EDIDData(HDMI_VFRMT_1920x1080p50_16_9, 1920, 1080, 50, 18),
- EDIDData(HDMI_VFRMT_1920x1080p60_16_9, 1920, 1080, 60, 19),
- EDIDData(HDMI_VFRMT_2560x1600p60_16_9, 2560, 1600, 60, 20),
- EDIDData(HDMI_VFRMT_3840x2160p24_16_9, 3840, 2160, 24, 21),
- EDIDData(HDMI_VFRMT_3840x2160p25_16_9, 3840, 2160, 25, 22),
- EDIDData(HDMI_VFRMT_3840x2160p30_16_9, 3840, 2160, 30, 23),
- EDIDData(HDMI_VFRMT_4096x2160p24_16_9, 4096, 2160, 24, 24),
+ EDIDData(HDMI_VFRMT_800x600p60_4_3, 800, 600, 60, 11),
+ EDIDData(HDMI_VFRMT_848x480p60_16_9, 848, 480, 60, 12),
+ EDIDData(HDMI_VFRMT_1024x768p60_4_3, 1024, 768, 60, 13),
+ EDIDData(HDMI_VFRMT_1280x1024p60_5_4, 1280, 1024, 60, 14),
+ EDIDData(HDMI_VFRMT_1280x720p50_16_9, 1280, 720, 50, 15),
+ EDIDData(HDMI_VFRMT_1280x720p60_16_9, 1280, 720, 60, 16),
+ EDIDData(HDMI_VFRMT_1280x800p60_16_10, 1280, 800, 60, 17),
+ EDIDData(HDMI_VFRMT_1280x960p60_4_3, 1280, 960, 60, 18),
+ EDIDData(HDMI_VFRMT_1360x768p60_16_9, 1360, 768, 60, 19),
+ EDIDData(HDMI_VFRMT_1366x768p60_16_10, 1366, 768, 60, 20),
+ EDIDData(HDMI_VFRMT_1440x900p60_16_10, 1440, 900, 60, 21),
+ EDIDData(HDMI_VFRMT_1400x1050p60_4_3, 1400, 1050, 60, 22),
+ EDIDData(HDMI_VFRMT_1680x1050p60_16_10, 1680, 1050, 60, 23),
+ EDIDData(HDMI_VFRMT_1600x1200p60_4_3, 1600, 1200, 60, 24),
+ EDIDData(HDMI_VFRMT_1920x1080p24_16_9, 1920, 1080, 24, 25),
+ EDIDData(HDMI_VFRMT_1920x1080p25_16_9, 1920, 1080, 25, 26),
+ EDIDData(HDMI_VFRMT_1920x1080p30_16_9, 1920, 1080, 30, 27),
+ EDIDData(HDMI_VFRMT_1920x1080p50_16_9, 1920, 1080, 50, 28),
+ EDIDData(HDMI_VFRMT_1920x1080p60_16_9, 1920, 1080, 60, 29),
+ EDIDData(HDMI_VFRMT_1920x1200p60_16_10, 1920, 1200, 60, 30),
+ EDIDData(HDMI_VFRMT_2560x1600p60_16_9, 2560, 1600, 60, 31),
+ EDIDData(HDMI_VFRMT_3840x2160p24_16_9, 3840, 2160, 24, 32),
+ EDIDData(HDMI_VFRMT_3840x2160p25_16_9, 3840, 2160, 25, 33),
+ EDIDData(HDMI_VFRMT_3840x2160p30_16_9, 3840, 2160, 30, 34),
+ EDIDData(HDMI_VFRMT_4096x2160p24_16_9, 4096, 2160, 24, 35),
};
// Number of modes in gEDIDData
const int gEDIDCount = (sizeof(gEDIDData)/sizeof(gEDIDData)[0]);
-int ExternalDisplay::configure() {
+int HDMIDisplay::configure() {
if(!openFrameBuffer()) {
ALOGE("%s: Failed to open FB: %d", __FUNCTION__, mFbNum);
return -1;
@@ -113,12 +124,12 @@
return 0;
}
-void ExternalDisplay::getAttributes(uint32_t& width, uint32_t& height) {
+void HDMIDisplay::getAttributes(uint32_t& width, uint32_t& height) {
uint32_t fps = 0;
getAttrForMode(width, height, fps);
}
-int ExternalDisplay::teardown() {
+int HDMIDisplay::teardown() {
closeFrameBuffer();
resetInfo();
// unset system property
@@ -126,7 +137,7 @@
return 0;
}
-ExternalDisplay::ExternalDisplay():mFd(-1),
+HDMIDisplay::HDMIDisplay():mFd(-1),
mCurrentMode(-1), mModeCount(0), mPrimaryWidth(0), mPrimaryHeight(0),
mUnderscanSupported(false)
{
@@ -166,7 +177,7 @@
* to the sysfs node, so that the driver can get that information
* Used to show QCOM 8974 instead of Input 1 for example
*/
-void ExternalDisplay::setSPDInfo(const char* node, const char* property) {
+void HDMIDisplay::setSPDInfo(const char* node, const char* property) {
char info[PROPERTY_VALUE_MAX];
ssize_t err = -1;
int spdFile = openDeviceNode(node, O_RDWR);
@@ -189,12 +200,12 @@
}
}
-void ExternalDisplay::setHPD(uint32_t value) {
+void HDMIDisplay::setHPD(uint32_t value) {
ALOGD_IF(DEBUG,"HPD enabled=%d", value);
writeHPDOption(value);
}
-void ExternalDisplay::setActionSafeDimension(int w, int h) {
+void HDMIDisplay::setActionSafeDimension(int w, int h) {
ALOGD_IF(DEBUG,"ActionSafe w=%d h=%d", w, h);
char actionsafeWidth[PROPERTY_VALUE_MAX];
char actionsafeHeight[PROPERTY_VALUE_MAX];
@@ -204,12 +215,12 @@
property_set("persist.sys.actionsafe.height", actionsafeHeight);
}
-int ExternalDisplay::getModeCount() const {
+int HDMIDisplay::getModeCount() const {
ALOGD_IF(DEBUG,"HPD mModeCount=%d", mModeCount);
return mModeCount;
}
-void ExternalDisplay::readCEUnderscanInfo()
+void HDMIDisplay::readCEUnderscanInfo()
{
int hdmiScanInfoFile = -1;
ssize_t len = -1;
@@ -258,8 +269,8 @@
if (ce_info_str) {
// ce_info contains the underscan information
- if (ce_info == EXT_SCAN_ALWAYS_UNDERSCANED ||
- ce_info == EXT_SCAN_BOTH_SUPPORTED)
+ if (ce_info == HDMI_SCAN_ALWAYS_UNDERSCANED ||
+ ce_info == HDMI_SCAN_BOTH_SUPPORTED)
// if TV supported underscan, then driver will always underscan
// hence no need to apply action safe rectangle
mUnderscanSupported = true;
@@ -273,7 +284,7 @@
return;
}
-ExternalDisplay::~ExternalDisplay()
+HDMIDisplay::~HDMIDisplay()
{
delete [] supported_video_mode_lut;
closeFrameBuffer();
@@ -309,7 +320,7 @@
info.upper_margin = mode->back_porch_v;
}
-int ExternalDisplay::parseResolution(char* edidStr)
+int HDMIDisplay::parseResolution(char* edidStr)
{
char delim = ',';
int count = 0;
@@ -330,7 +341,7 @@
return count;
}
-bool ExternalDisplay::readResolution()
+bool HDMIDisplay::readResolution()
{
ssize_t len = -1;
char edidStr[128] = {'\0'};
@@ -364,7 +375,7 @@
return (len > 0);
}
-bool ExternalDisplay::openFrameBuffer()
+bool HDMIDisplay::openFrameBuffer()
{
if (mFd == -1) {
char strDevPath[MAX_SYSFS_FILE_PATH];
@@ -376,7 +387,7 @@
return (mFd > 0);
}
-bool ExternalDisplay::closeFrameBuffer()
+bool HDMIDisplay::closeFrameBuffer()
{
int ret = 0;
if(mFd >= 0) {
@@ -387,7 +398,7 @@
}
// clears the vinfo, edid, best modes
-void ExternalDisplay::resetInfo()
+void HDMIDisplay::resetInfo()
{
memset(&mVInfo, 0, sizeof(mVInfo));
memset(mEDIDModes, 0, sizeof(mEDIDModes));
@@ -403,7 +414,7 @@
property_set("hw.underscan_supported", prop);
}
-int ExternalDisplay::getModeOrder(int mode)
+int HDMIDisplay::getModeOrder(int mode)
{
for (int dataIndex = 0; dataIndex < gEDIDCount; dataIndex++) {
if (gEDIDData[dataIndex].mMode == mode) {
@@ -415,7 +426,7 @@
}
/// Returns the user mode set(if any) using adb shell
-int ExternalDisplay::getUserMode() {
+int HDMIDisplay::getUserMode() {
/* Based on the property set the resolution */
char property_value[PROPERTY_VALUE_MAX];
property_get("hw.hdmi.resolution", property_value, "-1");
@@ -429,7 +440,7 @@
}
// Get the best mode for the current HD TV
-int ExternalDisplay::getBestMode() {
+int HDMIDisplay::getBestMode() {
int bestOrder = 0;
int bestMode = HDMI_VFRMT_640x480p60_4_3;
// for all the edid read, get the best mode
@@ -444,7 +455,7 @@
return bestMode;
}
-inline bool ExternalDisplay::isValidMode(int ID)
+inline bool HDMIDisplay::isValidMode(int ID)
{
bool valid = false;
for (int i = 0; i < mModeCount; i++) {
@@ -457,7 +468,7 @@
}
// returns true if the mode(ID) is interlaced mode format
-bool ExternalDisplay::isInterlacedMode(int ID) {
+bool HDMIDisplay::isInterlacedMode(int ID) {
bool interlaced = false;
switch(ID) {
case HDMI_VFRMT_1440x480i60_4_3:
@@ -476,7 +487,7 @@
// Does a put_vscreen info on the HDMI interface which will update
// the configuration (resolution, timing info) to match mCurrentMode
-void ExternalDisplay::activateDisplay()
+void HDMIDisplay::activateDisplay()
{
int ret = 0;
ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
@@ -526,7 +537,7 @@
}
}
-bool ExternalDisplay::writeHPDOption(int userOption) const
+bool HDMIDisplay::writeHPDOption(int userOption) const
{
bool ret = true;
if(mFbNum != -1) {
@@ -550,7 +561,7 @@
}
-void ExternalDisplay::setAttributes() {
+void HDMIDisplay::setAttributes() {
uint32_t fps = 0;
// Always set dpyAttr res to mVInfo res
getAttrForMode(mXres, mYres, fps);
@@ -619,7 +630,7 @@
ALOGD_IF(DEBUG, "%s xres=%d, yres=%d", __FUNCTION__, mXres, mYres);
}
-void ExternalDisplay::getAttrForMode(uint32_t& width, uint32_t& height,
+void HDMIDisplay::getAttrForMode(uint32_t& width, uint32_t& height,
uint32_t& fps) {
for (int dataIndex = 0; dataIndex < gEDIDCount; dataIndex++) {
if (gEDIDData[dataIndex].mMode == mCurrentMode) {
@@ -633,7 +644,7 @@
}
/* returns the fd related to the node specified*/
-int ExternalDisplay::openDeviceNode(const char* node, int fileMode) const {
+int HDMIDisplay::openDeviceNode(const char* node, int fileMode) const {
char sysFsFilePath[MAX_SYSFS_FILE_PATH];
memset(sysFsFilePath, 0, sizeof(sysFsFilePath));
snprintf(sysFsFilePath , sizeof(sysFsFilePath),
@@ -649,12 +660,12 @@
return fd;
}
-bool ExternalDisplay::isHDMIPrimaryDisplay() {
+bool HDMIDisplay::isHDMIPrimaryDisplay() {
int hdmiNode = qdutils::getHDMINode();
return (hdmiNode == HWC_DISPLAY_PRIMARY);
}
-int ExternalDisplay::getConnectedState() {
+int HDMIDisplay::getConnectedState() {
int ret = -1;
int mFbNum = qdutils::getHDMINode();
int connectedNode = openDeviceNode("connected", O_RDONLY);
@@ -679,7 +690,7 @@
return ret;
}
-void ExternalDisplay::setPrimaryAttributes(uint32_t primaryWidth,
+void HDMIDisplay::setPrimaryAttributes(uint32_t primaryWidth,
uint32_t primaryHeight) {
mPrimaryHeight = primaryHeight;
mPrimaryWidth = primaryWidth;
diff --git a/libexternal/external.h b/libhdmi/hdmi.h
similarity index 90%
rename from libexternal/external.h
rename to libhdmi/hdmi.h
index fa98de9..605d9be 100644
--- a/libexternal/external.h
+++ b/libhdmi/hdmi.h
@@ -18,8 +18,8 @@
* limitations under the License.
*/
-#ifndef HWC_EXTERNAL_DISPLAY_H
-#define HWC_EXTERNAL_DISPLAY_H
+#ifndef HWC_HDMI_DISPLAY_H
+#define HWC_HDMI_DISPLAY_H
#include <linux/fb.h>
@@ -28,11 +28,11 @@
namespace qhwc {
//Type of scanning of EDID(Video Capability Data Block)
-enum external_scansupport_type {
- EXT_SCAN_NOT_SUPPORTED = 0,
- EXT_SCAN_ALWAYS_OVERSCANED = 1,
- EXT_SCAN_ALWAYS_UNDERSCANED = 2,
- EXT_SCAN_BOTH_SUPPORTED = 3
+enum hdmi_scansupport_type {
+ HDMI_SCAN_NOT_SUPPORTED = 0,
+ HDMI_SCAN_ALWAYS_OVERSCANED = 1,
+ HDMI_SCAN_ALWAYS_UNDERSCANED = 2,
+ HDMI_SCAN_BOTH_SUPPORTED = 3
};
// Structure to store EDID related data
@@ -45,11 +45,11 @@
{ }
};
-class ExternalDisplay
+class HDMIDisplay
{
public:
- ExternalDisplay();
- ~ExternalDisplay();
+ HDMIDisplay();
+ ~HDMIDisplay();
void setHPD(uint32_t startEnd);
void setActionSafeDimension(int w, int h);
bool isCEUnderscanSupported() { return mUnderscanSupported; }
@@ -107,4 +107,4 @@
}; //qhwc
// ---------------------------------------------------------------------------
-#endif //HWC_EXTERNAL_DISPLAY_H
+#endif //HWC_HDMI_DISPLAY_H
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index 8e3fc8e..df3e464 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -9,7 +9,7 @@
$(TOP)/external/skia/include/core \
$(TOP)/external/skia/include/images
LOCAL_SHARED_LIBRARIES := $(common_libs) libEGL liboverlay \
- libexternal libqdutils libhardware_legacy \
+ libhdmi libqdutils libhardware_legacy \
libdl libmemalloc libqservice libsync \
libbinder libmedia
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index ae1389d..288b2e0 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -34,7 +34,7 @@
#include "hwc_fbupdate.h"
#include "hwc_mdpcomp.h"
#include "hwc_dump_layers.h"
-#include "external.h"
+#include "hdmi.h"
#include "hwc_copybit.h"
#include "hwc_ad.h"
#include "profiler.h"
@@ -442,7 +442,7 @@
if(mode == HWC_POWER_MODE_NORMAL) {
// Enable HPD here, as during bootup POWER_MODE_NORMAL is set
// when SF is completely initialized
- ctx->mExtDisplay->setHPD(1);
+ ctx->mHDMIDisplay->setHPD(1);
}
ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
diff --git a/libhwcomposer/hwc_ad.cpp b/libhwcomposer/hwc_ad.cpp
index 679e6d6..7e96d97 100644
--- a/libhwcomposer/hwc_ad.cpp
+++ b/libhwcomposer/hwc_ad.cpp
@@ -34,7 +34,6 @@
#include <mdp_version.h>
#include "hwc_ad.h"
#include "hwc_utils.h"
-#include "external.h"
#define DEBUG 0
using namespace overlay;
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 8164fd3..67cca88 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -96,7 +96,7 @@
int fbWidth = ctx->dpyAttr[dpy].xres;
int fbHeight = ctx->dpyAttr[dpy].yres;
unsigned int fbArea = (fbWidth * fbHeight);
- unsigned int renderArea = getRGBRenderingArea(list);
+ unsigned int renderArea = getRGBRenderingArea(ctx, list);
ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u",
__FUNCTION__, renderArea, fbArea);
if (renderArea < (mDynThreshold * fbArea)) {
@@ -112,8 +112,8 @@
return false;
}
-unsigned int CopyBit::getRGBRenderingArea
- (const hwc_display_contents_1_t *list) {
+unsigned int CopyBit::getRGBRenderingArea (const hwc_context_t *ctx,
+ const hwc_display_contents_1_t *list) {
//Calculates total rendering area for RGB layers
unsigned int renderArea = 0;
unsigned int w=0, h=0;
@@ -122,7 +122,7 @@
for (unsigned int i=0; i<list->numHwLayers -1; i++) {
private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
if (hnd) {
- if (BUFFER_TYPE_UI == hnd->bufferType) {
+ if (BUFFER_TYPE_UI == hnd->bufferType && !ctx->copybitDrop[i]) {
getLayerResolution(&list->hwLayers[i], w, h);
renderArea += (w*h);
}
@@ -316,6 +316,9 @@
for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
int dst_h, dst_w, src_h, src_w;
float dx, dy;
+ if(ctx->copybitDrop[i]) {
+ continue;
+ }
hwc_layer_1_t *layer = (hwc_layer_1_t *) &list->hwLayers[i];
if (layer->planeAlpha != 0xFF)
return true;
@@ -349,7 +352,8 @@
}
//Allocate render buffers if they're not allocated
- if (ctx->mMDP.version != qdutils::MDP_V3_0_4 &&
+ if ((ctx->mMDP.version != qdutils::MDP_V3_0_4 &&
+ ctx->mMDP.version != qdutils::MDP_V3_0_5) &&
(useCopybitForYUV || useCopybitForRGB)) {
int ret = allocRenderBuffers(mAlignedWidth,
mAlignedHeight,
@@ -375,7 +379,8 @@
for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
layerProp[i].mFlags |= HWC_COPYBIT;
#ifdef QCOM_BSP
- if (ctx->mMDP.version == qdutils::MDP_V3_0_4)
+ if (ctx->mMDP.version == qdutils::MDP_V3_0_4 ||
+ ctx->mMDP.version == qdutils::MDP_V3_0_5)
list->hwLayers[i].compositionType = HWC_BLIT;
else
#endif
@@ -496,7 +501,8 @@
return true;
}
//render buffer
- if (ctx->mMDP.version == qdutils::MDP_V3_0_4) {
+ if (ctx->mMDP.version == qdutils::MDP_V3_0_4 ||
+ ctx->mMDP.version == qdutils::MDP_V3_0_5) {
last = (uint32_t)list->numHwLayers - 1;
renderBuffer = (private_handle_t *)list->hwLayers[last].handle;
} else {
@@ -541,6 +547,9 @@
ALOGD_IF(DEBUG_COPYBIT, "%s: Not Marked for copybit", __FUNCTION__);
continue;
}
+ if(ctx->copybitDrop[i]) {
+ continue;
+ }
//skip non updating layers
if((mDirtyLayerIndex != -1) && (mDirtyLayerIndex != i) )
continue;
@@ -568,7 +577,8 @@
copybit_device_t *copybit = getCopyBitDevice();
// Async mode
copybit->flush_get_fence(copybit, fd);
- if(ctx->mMDP.version == qdutils::MDP_V3_0_4 &&
+ if((ctx->mMDP.version == qdutils::MDP_V3_0_4 ||
+ ctx->mMDP.version == qdutils::MDP_V3_0_5) &&
list->hwLayers[last].acquireFenceFd >= 0) {
close(list->hwLayers[last].acquireFenceFd);
list->hwLayers[last].acquireFenceFd = -1;
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 99a39c8..a7ce43e 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -101,8 +101,8 @@
// flag that indicates whether CopyBit composition is enabled for this cycle
bool mCopyBitDraw;
- unsigned int getRGBRenderingArea
- (const hwc_display_contents_1_t *list);
+ unsigned int getRGBRenderingArea (const hwc_context_t *ctx,
+ const hwc_display_contents_1_t *list);
void getLayerResolution(const hwc_layer_1_t* layer,
unsigned int &width, unsigned int& height);
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 7839139..43ae916 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -25,7 +25,6 @@
#include <overlayRotator.h>
#include "hwc_fbupdate.h"
#include "mdp_version.h"
-#include "external.h"
using namespace qdutils;
using namespace overlay;
@@ -514,12 +513,13 @@
based on an empirically derived value of panel height.
*/
- bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
+ const bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
qdutils::MDPVersion::getInstance().isSrcSplitAlways();
+ const uint32_t lSplit = getLeftSplit(ctx, mDpy);
+ const uint32_t cropWidth = sourceCrop.right - sourceCrop.left;
- if(((sourceCrop.right - sourceCrop.left) >
- (int)qdutils::MDPVersion::getInstance().getMaxMixerWidth()) or
- primarySplitAlways) {
+ if((cropWidth > qdutils::MDPVersion::getInstance().getMaxMixerWidth()) or
+ (primarySplitAlways and cropWidth > lSplit)) {
destR = ov.getPipe(pipeSpecs);
if(destR == ovutils::OV_INVALID) {
ALOGE("%s: No pipes available to configure fb for dpy %d's right"
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 072eda3..2904e6f 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -19,7 +19,7 @@
#include <math.h>
#include "hwc_mdpcomp.h"
#include <sys/ioctl.h>
-#include "external.h"
+#include "hdmi.h"
#include "qdMetaData.h"
#include "mdp_version.h"
#include "hwc_fbupdate.h"
@@ -36,7 +36,7 @@
//==============MDPComp========================================================
-IdleInvalidator *MDPComp::idleInvalidator = NULL;
+IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
bool MDPComp::sIdleFallBack = false;
bool MDPComp::sHandleTimeout = false;
bool MDPComp::sDebugLogs = false;
@@ -46,6 +46,7 @@
int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
bool MDPComp::sEnableYUVsplit = false;
bool MDPComp::sSrcSplitEnabled = false;
+bool MDPComp::enablePartialUpdateForMDP3 = false;
MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
sSrcSplitEnabled = true;
@@ -110,7 +111,7 @@
return false;
}
- char property[PROPERTY_VALUE_MAX];
+ char property[PROPERTY_VALUE_MAX] = {0};
sEnabled = false;
if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
@@ -134,23 +135,10 @@
}
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();
-
- if(idleInvalidator == NULL) {
- ALOGE("%s: failed to instantiate idleInvalidator object",
- __FUNCTION__);
- } else {
- idleInvalidator->init(timeout_handler, ctx,
- (unsigned int)idle_timeout);
+ sIdleInvalidator = IdleInvalidator::getInstance();
+ if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
+ delete sIdleInvalidator;
+ sIdleInvalidator = NULL;
}
}
@@ -162,13 +150,32 @@
sEnableYUVsplit = true;
}
- if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
- ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
- (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
+ bool defaultPTOR = false;
+ //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
+ //8x16 and 8x39 targets by default
+ if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
+ (qdutils::MDPVersion::getInstance().is8x16() ||
+ qdutils::MDPVersion::getInstance().is8x39())) {
+ defaultPTOR = true;
+ }
+
+ if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
+ (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
HWC_DISPLAY_PRIMARY);
}
+ if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
+ (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
+ enablePartialUpdateForMDP3 = true;
+ }
+
+ if(!enablePartialUpdateForMDP3 &&
+ (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+ (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+ enablePartialUpdateForMDP3 = true;
+ }
+
return true;
}
@@ -206,6 +213,25 @@
ctx->proc->invalidate(ctx->proc);
}
+void MDPComp::setIdleTimeout(const uint32_t& timeout) {
+ enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
+
+ if(sIdleInvalidator) {
+ if(timeout <= ONE_REFRESH_PERIOD_MS) {
+ //If the specified timeout is < 1 draw cycle worth, "virtually"
+ //disable idle timeout. The ideal way for clients to disable
+ //timeout is to set it to 0
+ sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
+ ALOGI("Disabled idle timeout");
+ return;
+ }
+ sIdleInvalidator->setIdleTimeout(timeout);
+ ALOGI("Idle timeout set to %u", timeout);
+ } else {
+ ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
+ }
+}
+
void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
hwc_display_contents_1_t* list) {
LayerProp *layerProp = ctx->layerProp[mDpy];
@@ -358,7 +384,7 @@
* There also is a HW limilation in MDP, minimum block size is 2x2
* Fallback to GPU if height is less than 2.
*/
- if((crop_w < 5)||(crop_h < 5))
+ if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
return false;
if((w_scale > 1.0f) || (h_scale > 1.0f)) {
@@ -684,9 +710,18 @@
const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
- // No Idle fall back, if secure display or secure RGB layers are present
+ // Fall back to video only composition, if AIV video mode is enabled
+ if(ctx->listStats[mDpy].mAIVVideoMode) {
+ ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
+ __FUNCTION__, mDpy);
+ return false;
+ }
+
+ // No Idle fall back, if secure display or secure RGB layers are present or
+ // if there's only a single layer being composed
if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
- !ctx->listStats[mDpy].secureRGBCount)) {
+ !ctx->listStats[mDpy].secureRGBCount) &&
+ (ctx->listStats[mDpy].numAppLayers != 1)) {
ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
return false;
}
@@ -1274,6 +1309,13 @@
/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
hwc_display_contents_1_t* list) {
+ // Fall back to video only composition, if AIV video mode is enabled
+ if(ctx->listStats[mDpy].mAIVVideoMode) {
+ ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
+ __FUNCTION__, mDpy);
+ return false;
+ }
+
const bool secureOnly = true;
return mdpOnlyLayersComp(ctx, list, not secureOnly) or
mdpOnlyLayersComp(ctx, list, secureOnly);
@@ -1570,6 +1612,24 @@
__FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
}
+// drop other non-AIV layers from external display list.
+void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
+ hwc_display_contents_1_t* list) {
+ for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
+ hwc_layer_1_t * layer = &list->hwLayers[i];
+ if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
+ mCurrentFrame.dropCount++;
+ mCurrentFrame.drop[i] = true;
+ }
+ }
+ mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
+ mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
+ mCurrentFrame.fbCount - mCurrentFrame.dropCount;
+ ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
+ __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
+ mCurrentFrame.dropCount);
+}
+
void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
bool secureOnly, FrameInfo& frame) {
int nYuvCount = ctx->listStats[mDpy].yuvCount;
@@ -1577,6 +1637,10 @@
int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
+ if(mCurrentFrame.drop[nYuvIndex]) {
+ continue;
+ }
+
if(!isYUVDoable(ctx, layer)) {
if(!frame.isFBComposed[nYuvIndex]) {
frame.isFBComposed[nYuvIndex] = true;
@@ -1845,6 +1909,11 @@
//Hard conditions, if not met, cannot do MDP comp
if(isFrameDoable(ctx)) {
generateROI(ctx, list);
+ // if AIV Video mode is enabled, drop all non AIV layers from the
+ // external display list.
+ if(ctx->listStats[mDpy].mAIVVideoMode) {
+ dropNonAIVLayers(ctx, list);
+ }
// if tryFullFrame fails, try to push all video and secure RGB layers
// to MDP for composition.
@@ -1862,6 +1931,13 @@
"MDP Composition Strategies Failed");
}
} else {
+ if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
+ enablePartialUpdateForMDP3) {
+ generateROI(ctx, list);
+ for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
+ ctx->copybitDrop[i] = mCurrentFrame.drop[i];
+ }
+ }
ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
__FUNCTION__);
ret = -1;
@@ -1880,6 +1956,8 @@
if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
FrameInfo frame;
frame.reset(mCurrentFrame.layerCount);
+ memset(&frame.drop, 0, sizeof(frame.drop));
+ frame.dropCount = 0;
ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
__FUNCTION__);
updateLayerCache(ctx, list, frame);
@@ -2055,7 +2133,7 @@
}
// Set the Handle timeout to true for MDP or MIXED composition.
- if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
+ if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
sHandleTimeout = true;
}
@@ -2310,7 +2388,7 @@
}
// Set the Handle timeout to true for MDP or MIXED composition.
- if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
+ if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
sHandleTimeout = true;
}
@@ -2469,7 +2547,8 @@
mdpHw.isSrcSplitAlways();
int lSplit = getLeftSplit(ctx, mDpy);
int dstWidth = dst.right - dst.left;
- int cropWidth = crop.right - crop.left;
+ int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
+ crop.right - crop.left;
//TODO Even if a 4k video is going to be rot-downscaled to dimensions under
//pipe line length, we are still using 2 pipes. This is fine just because
@@ -2528,6 +2607,10 @@
else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
}
+ // update source crop and destination position of AIV video layer.
+ if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
+ updateCoordinates(ctx, crop, dst, mDpy);
+ }
/* Calculate the external display position based on MDP downscale,
ActionSafe, and extorientation features. */
calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index e43c4f4..4634fbc 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -25,7 +25,6 @@
#include <cutils/properties.h>
#include <overlay.h>
-#define DEFAULT_IDLE_TIME 70
#define MAX_PIPES_PER_MIXER 4
namespace overlay {
@@ -57,6 +56,7 @@
static void resetIdleFallBack() { sIdleFallBack = false; }
static bool isIdleFallback() { return sIdleFallBack; }
static void dynamicDebug(bool enable){ sDebugLogs = enable; }
+ static void setIdleTimeout(const uint32_t& timeout);
protected:
enum { MAX_SEC_LAYERS = 1 }; //TODO add property support
@@ -222,6 +222,9 @@
bool intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
int fromIndex, int toIndex, int targetLayerIndex);
+ /* drop other non-AIV layers from external display list.*/
+ void dropNonAIVLayers(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+
/* updates cache map with YUV info */
void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
bool secureOnly, FrameInfo& frame);
@@ -255,13 +258,15 @@
static bool sHandleTimeout;
static int sMaxPipesPerMixer;
static bool sSrcSplitEnabled;
- static IdleInvalidator *idleInvalidator;
+ static IdleInvalidator *sIdleInvalidator;
struct FrameInfo mCurrentFrame;
struct LayerCache mCachedFrame;
//Enable 4kx2k yuv layer split
static bool sEnableYUVsplit;
bool mModeOn; // if prepare happened
bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index);
+ //Enable Partial Update for MDP3 targets
+ static bool enablePartialUpdateForMDP3;
};
class MDPCompNonSplit : public MDPComp {
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 8490058..6bde3d2 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -245,6 +245,13 @@
}
}
+static void setIdleTimeout(hwc_context_t* ctx, const Parcel* inParcel) {
+ uint32_t timeout = (uint32_t)inParcel->readInt32();
+ ALOGD("%s :%u ms", __FUNCTION__, timeout);
+ Locker::Autolock _sl(ctx->mDrawLock);
+ MDPComp::setIdleTimeout(timeout);
+}
+
status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
Parcel* outParcel) {
status_t ret = NO_ERROR;
@@ -290,6 +297,9 @@
case IQService::DYNAMIC_DEBUG:
toggleDynamicDebug(mHwcContext, inParcel);
break;
+ case IQService::SET_IDLE_TIMEOUT:
+ setIdleTimeout(mHwcContext, inParcel);
+ break;
default:
ret = NO_ERROR;
}
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 821bfa9..6b2316b 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -30,7 +30,7 @@
#include "hwc_mdpcomp.h"
#include "hwc_copybit.h"
#include "comptype.h"
-#include "external.h"
+#include "hdmi.h"
#include "hwc_virtual.h"
#include "mdp_version.h"
using namespace overlay;
@@ -107,10 +107,11 @@
break;
}
- Locker::Autolock _l(ctx->mDrawLock);
+ ctx->mDrawLock.lock();
destroyCompositionResources(ctx, dpy);
- ctx->mExtDisplay->teardown();
+ ctx->mHDMIDisplay->teardown();
resetDisplayInfo(ctx, dpy);
+ ctx->mDrawLock.unlock();
/* We need to send hotplug to SF only when we are disconnecting
* HDMI */
@@ -127,19 +128,19 @@
"for display: %d", __FUNCTION__, dpy);
break;
}
- {
- //Force composition to give up resources like pipes and
- //close fb. For example if assertive display is going on,
- //fb2 could be open, thus connecting Layer Mixer#0 to
- //WriteBack module. If HDMI attempts to open fb1, the driver
- //will try to attach Layer Mixer#0 to HDMI INT, which will
- //fail, since Layer Mixer#0 is still connected to WriteBack.
- //This block will force composition to close fb2 in above
- //example.
- Locker::Autolock _l(ctx->mDrawLock);
- ctx->dpyAttr[dpy].isConfiguring = true;
- ctx->proc->invalidate(ctx->proc);
- }
+ ctx->mDrawLock.lock();
+ //Force composition to give up resources like pipes and
+ //close fb. For example if assertive display is going on,
+ //fb2 could be open, thus connecting Layer Mixer#0 to
+ //WriteBack module. If HDMI attempts to open fb1, the driver
+ //will try to attach Layer Mixer#0 to HDMI INT, which will
+ //fail, since Layer Mixer#0 is still connected to WriteBack.
+ //This block will force composition to close fb2 in above
+ //example.
+ ctx->dpyAttr[dpy].isConfiguring = true;
+ ctx->mDrawLock.unlock();
+
+ ctx->proc->invalidate(ctx->proc);
//2 cycles for slower content
usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
* 2 / 1000);
@@ -163,15 +164,16 @@
"uevent thread", __FUNCTION__);
ctx->mWfdSyncLock.unlock();
}
- ctx->mExtDisplay->configure();
- ctx->mExtDisplay->activateDisplay();
+ ctx->mHDMIDisplay->configure();
+ ctx->mHDMIDisplay->activateDisplay();
- Locker::Autolock _l(ctx->mDrawLock);
+ ctx->mDrawLock.lock();
updateDisplayInfo(ctx, dpy);
initCompositionResources(ctx, dpy);
ctx->dpyAttr[dpy].isPause = false;
ctx->dpyAttr[dpy].connected = true;
ctx->dpyAttr[dpy].isConfiguring = true;
+ ctx->mDrawLock.unlock();
/* External display is HDMI */
ALOGE_IF(UEVENT_DEBUG, "%s: Sending EXTERNAL ONLINE"
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 44725de..1f3e99a 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -37,12 +37,13 @@
#include "mdp_version.h"
#include "hwc_copybit.h"
#include "hwc_dump_layers.h"
-#include "external.h"
+#include "hdmi.h"
#include "hwc_qclient.h"
#include "QService.h"
#include "comptype.h"
#include "hwc_virtual.h"
#include "qd_utils.h"
+#include <sys/sysinfo.h>
using namespace qClient;
using namespace qService;
@@ -73,6 +74,11 @@
#endif
#endif
+#define PROP_DEFAULT_APPBUFFER "ro.sf.default_app_buffer"
+#define MAX_RAM_SIZE 512*1024*1024
+#define qHD_WIDTH 540
+
+
namespace qhwc {
//Std refresh rates for digital videos- 24p, 30p and 48p
@@ -95,38 +101,40 @@
char *yptr = NULL;
if (property_get("debug.hwc.fbsize", property, NULL) > 0) {
yptr = strcasestr(property,"x");
- int xres_new = atoi(property);
- int yres_new = atoi(yptr + 1);
- if (isValidResolution(ctx,xres_new,yres_new) &&
- xres_new != xres_orig && yres_new != yres_orig) {
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_new = xres_new;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_new = yres_new;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = true;
+ if(yptr) {
+ int xres_new = atoi(property);
+ int yres_new = atoi(yptr + 1);
+ if (isValidResolution(ctx,xres_new,yres_new) &&
+ xres_new != xres_orig && yres_new != yres_orig) {
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_new = xres_new;
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_new = yres_new;
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = true;
- //Caluculate DPI according to changed resolution.
- float xdpi = ((float)xres_new * 25.4f) / (float)width;
- float ydpi = ((float)yres_new * 25.4f) / (float)height;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = xdpi;
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
+ //Caluculate DPI according to changed resolution.
+ float xdpi = ((float)xres_new * 25.4f) / (float)width;
+ float ydpi = ((float)yres_new * 25.4f) / (float)height;
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = xdpi;
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
+ }
}
}
}
-// Initialize external display attributes based on
-// external display class state
+// Initialize hdmi display attributes based on
+// hdmi display class state
void updateDisplayInfo(hwc_context_t* ctx, int dpy) {
- ctx->dpyAttr[dpy].fd = ctx->mExtDisplay->getFd();
- ctx->dpyAttr[dpy].xres = ctx->mExtDisplay->getWidth();
- ctx->dpyAttr[dpy].yres = ctx->mExtDisplay->getHeight();
- ctx->dpyAttr[dpy].mMDPScalingMode = ctx->mExtDisplay->getMDPScalingMode();
- ctx->dpyAttr[dpy].vsync_period = ctx->mExtDisplay->getVsyncPeriod();
+ ctx->dpyAttr[dpy].fd = ctx->mHDMIDisplay->getFd();
+ ctx->dpyAttr[dpy].xres = ctx->mHDMIDisplay->getWidth();
+ ctx->dpyAttr[dpy].yres = ctx->mHDMIDisplay->getHeight();
+ ctx->dpyAttr[dpy].mMDPScalingMode = ctx->mHDMIDisplay->getMDPScalingMode();
+ ctx->dpyAttr[dpy].vsync_period = ctx->mHDMIDisplay->getVsyncPeriod();
ctx->mViewFrame[dpy].left = 0;
ctx->mViewFrame[dpy].top = 0;
ctx->mViewFrame[dpy].right = ctx->dpyAttr[dpy].xres;
ctx->mViewFrame[dpy].bottom = ctx->dpyAttr[dpy].yres;
}
-// Reset external display attributes and list stats structures
+// Reset hdmi display attributes and list stats structures
void resetDisplayInfo(hwc_context_t* ctx, int dpy) {
memset(&(ctx->dpyAttr[dpy]), 0, sizeof(ctx->dpyAttr[dpy]));
memset(&(ctx->listStats[dpy]), 0, sizeof(ctx->listStats[dpy]));
@@ -232,6 +240,25 @@
return 0;
}
+static void changeDefaultAppBufferCount() {
+ struct sysinfo info;
+ unsigned long int ramSize = 0;
+ if (!sysinfo(&info)) {
+ ramSize = info.totalram ;
+ }
+ int fb_fd = -1;
+ struct fb_var_screeninfo sInfo ={0};
+ fb_fd = open("/dev/graphics/fb0", O_RDONLY);
+ if (fb_fd >=0) {
+ ioctl(fb_fd, FBIOGET_VSCREENINFO, &sInfo);
+ close(fb_fd);
+ }
+ if ((ramSize && ramSize < MAX_RAM_SIZE) &&
+ (sInfo.xres && sInfo.xres <= qHD_WIDTH )) {
+ property_set(PROP_DEFAULT_APPBUFFER, "2");
+ }
+}
+
void initContext(hwc_context_t *ctx)
{
openFramebufferDevice(ctx);
@@ -243,6 +270,10 @@
ctx->mOverlay = overlay::Overlay::getInstance();
ctx->mRotMgr = RotMgr::getInstance();
+ //default_app_buffer for ferrum
+ if (ctx->mMDP.version == qdutils::MDP_V3_0_5) {
+ changeDefaultAppBufferCount();
+ }
// Initialize composition objects for the primary display
initCompositionResources(ctx, HWC_DISPLAY_PRIMARY);
@@ -254,18 +285,20 @@
// Only MDP copybit is used
if ((compositionType & (qdutils::COMPOSITION_TYPE_DYN |
qdutils::COMPOSITION_TYPE_MDP)) &&
+ ((qdutils::MDPVersion::getInstance().getMDPVersion() ==
+ qdutils::MDP_V3_0_4) ||
(qdutils::MDPVersion::getInstance().getMDPVersion() ==
- qdutils::MDP_V3_0_4)) {
+ qdutils::MDP_V3_0_5))) {
ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
HWC_DISPLAY_PRIMARY);
}
- ctx->mExtDisplay = new ExternalDisplay();
- // Send the primary resolution to the external display class
+ ctx->mHDMIDisplay = new HDMIDisplay();
+ // Send the primary resolution to the hdmi display class
// to be used for MDP scaling functionality
uint32_t priW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
uint32_t priH = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
- ctx->mExtDisplay->setPrimaryAttributes(priW, priH);
+ ctx->mHDMIDisplay->setPrimaryAttributes(priW, priH);
ctx->mHWCVirtual = new HWCVirtualVDS();
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = false;
@@ -323,6 +356,9 @@
ctx->deviceOrientation = 0;
ctx->mBufferMirrorMode = false;
+ property_get("sys.hwc.windowbox_aspect_ratio_tolerance", value, "0");
+ ctx->mAspectRatioToleranceLevel = (((float)atoi(value)) / 100.0f);
+
ctx->enableABC = false;
property_get("debug.sf.hwc.canUseABC", value, "0");
ctx->enableABC = atoi(value) ? true : false;
@@ -337,6 +373,13 @@
ctx->mGPUHintInfo.mCompositionState = COMPOSITION_STATE_MDP;
ctx->mGPUHintInfo.mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
#endif
+ // Read the system property to determine if windowboxing feature is enabled.
+ ctx->mWindowboxFeature = false;
+ if(property_get("sys.hwc.windowbox_feature", value, "false")
+ && !strcmp(value, "true")) {
+ ctx->mWindowboxFeature = true;
+ }
+
memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
ALOGI("Initializing Qualcomm Hardware Composer");
ALOGI("MDP version: %d", ctx->mMDP.version);
@@ -366,9 +409,9 @@
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = -1;
}
- if(ctx->mExtDisplay) {
- delete ctx->mExtDisplay;
- ctx->mExtDisplay = NULL;
+ if(ctx->mHDMIDisplay) {
+ delete ctx->mHDMIDisplay;
+ ctx->mHDMIDisplay = NULL;
}
for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
@@ -478,7 +521,7 @@
if(ctx->dpyAttr[dpy].mMDPScalingMode) {
// if MDP scaling mode is enabled for external, need to query
// the actual width and height, as that is the physical w & h
- ctx->mExtDisplay->getAttributes(fbWidth, fbHeight);
+ ctx->mHDMIDisplay->getAttributes(fbWidth, fbHeight);
}
@@ -610,7 +653,7 @@
if(ctx->dpyAttr[dpy].mMDPScalingMode) {
uint32_t extW = 0, extH = 0;
if(dpy == HWC_DISPLAY_EXTERNAL) {
- ctx->mExtDisplay->getAttributes(extW, extH);
+ ctx->mHDMIDisplay->getAttributes(extW, extH);
} else if(dpy == HWC_DISPLAY_VIRTUAL) {
extW = ctx->mHWCVirtual->getScalingWidth();
extH = ctx->mHWCVirtual->getScalingHeight();
@@ -696,7 +739,7 @@
float fbHeight = (float)ctx->dpyAttr[dpy].yres;
// query MDP configured attributes
if(dpy == HWC_DISPLAY_EXTERNAL) {
- ctx->mExtDisplay->getAttributes(extW, extH);
+ ctx->mHDMIDisplay->getAttributes(extW, extH);
} else if(dpy == HWC_DISPLAY_VIRTUAL) {
extW = ctx->mHWCVirtual->getScalingWidth();
extH = ctx->mHWCVirtual->getScalingHeight();
@@ -926,6 +969,7 @@
uint32_t refreshRate = 0;
qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
+ ctx->listStats[dpy].mAIVVideoMode = false;
resetROI(ctx, dpy);
trimList(ctx, list, dpy);
@@ -935,6 +979,11 @@
private_handle_t *hnd = (private_handle_t *)layer->handle;
#ifdef QCOM_BSP
+ // Window boxing feature is applicable obly for external display, So
+ // enable mAIVVideoMode only for external display
+ if(ctx->mWindowboxFeature && dpy && isAIVVideoLayer(layer)) {
+ ctx->listStats[dpy].mAIVVideoMode = true;
+ }
if (layer->flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
ctx->listStats[dpy].isDisplayAnimating = true;
}
@@ -1114,7 +1163,7 @@
// Disable Actionsafe for non HDMI displays.
if(!(dpy == HWC_DISPLAY_EXTERNAL) ||
qdutils::MDPVersion::getInstance().is8x74v2() ||
- ctx->mExtDisplay->isCEUnderscanSupported()) {
+ ctx->mHDMIDisplay->isCEUnderscanSupported()) {
return false;
}
@@ -1434,7 +1483,7 @@
rotData.acq_fen_fd_cnt = 1; //1 ioctl call per rot session
}
int ret = 0;
- if(not ctx->mLayerRotMap[dpy]->isRotCached(i))
+ if(LIKELY(!swapzero) and (not ctx->mLayerRotMap[dpy]->isRotCached(i)))
ret = ioctl(rotFd, MSMFB_BUFFER_SYNC, &rotData);
if(ret < 0) {
@@ -1456,43 +1505,45 @@
//Accumulate acquireFenceFds for MDP Overlays
if(list->outbufAcquireFenceFd >= 0) {
//Writeback output buffer
- acquireFd[count++] = list->outbufAcquireFenceFd;
+ if(LIKELY(!swapzero) )
+ acquireFd[count++] = list->outbufAcquireFenceFd;
}
for(uint32_t i = 0; i < list->numHwLayers; i++) {
if(((isAbcInUse(ctx)== true ) ||
(list->hwLayers[i].compositionType == HWC_OVERLAY)) &&
list->hwLayers[i].acquireFenceFd >= 0) {
- if(UNLIKELY(swapzero))
- acquireFd[count++] = -1;
- // if ABC is enabled for more than one layer.
- // renderBufIndexforABC will work as FB.Hence
- // set the acquireFD from fd - which is coming from copybit
- else if(fd >= 0 && (isAbcInUse(ctx) == true)) {
- if(ctx->listStats[dpy].renderBufIndexforABC ==(int32_t)i)
- acquireFd[count++] = fd;
- else
- continue;
- } else
- acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
+ if(LIKELY(!swapzero) ) {
+ // if ABC is enabled for more than one layer.
+ // renderBufIndexforABC will work as FB.Hence
+ // set the acquireFD from fd - which is coming from copybit
+ if(fd >= 0 && (isAbcInUse(ctx) == true)) {
+ if(ctx->listStats[dpy].renderBufIndexforABC ==(int32_t)i)
+ acquireFd[count++] = fd;
+ else
+ continue;
+ } else
+ acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
+ }
}
if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
- if(UNLIKELY(swapzero))
- acquireFd[count++] = -1;
- else if(fd >= 0) {
- //set the acquireFD from fd - which is coming from c2d
- acquireFd[count++] = fd;
- // Buffer sync IOCTL should be async when using c2d fence is
- // used
- data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT;
- } else if(list->hwLayers[i].acquireFenceFd >= 0)
- acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
+ if(LIKELY(!swapzero) ) {
+ if(fd >= 0) {
+ //set the acquireFD from fd - which is coming from c2d
+ acquireFd[count++] = fd;
+ // Buffer sync IOCTL should be async when using c2d fence is
+ // used
+ data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT;
+ } else if(list->hwLayers[i].acquireFenceFd >= 0)
+ acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
+ }
}
}
if ((fd >= 0) && !dpy && ctx->mPtorInfo.isActive()) {
// Acquire c2d fence of Overlap render buffer
- acquireFd[count++] = fd;
+ if(LIKELY(!swapzero) )
+ acquireFd[count++] = fd;
}
data.acq_fen_fd_cnt = count;
@@ -1784,6 +1835,71 @@
return downscale;
}
+bool isZoomModeEnabled(hwc_rect_t crop) {
+ // This does not work for zooming in top left corner of the image
+ return(crop.top > 0 || crop.left > 0);
+}
+
+void updateCropAIVVideoMode(hwc_context_t *ctx, hwc_rect_t& crop, int dpy) {
+ ALOGD_IF(HWC_UTILS_DEBUG, "dpy %d Source crop [%d %d %d %d]", dpy,
+ crop.left, crop.top, crop.right, crop.bottom);
+ if(isZoomModeEnabled(crop)) {
+ Dim srcCrop(crop.left, crop.top,
+ crop.right - crop.left,
+ crop.bottom - crop.top);
+ int extW = ctx->dpyAttr[dpy].xres;
+ int extH = ctx->dpyAttr[dpy].yres;
+ //Crop the original video in order to fit external display aspect ratio
+ if(srcCrop.w * extH < extW * srcCrop.h) {
+ int offset = (srcCrop.h - ((srcCrop.w * extH) / extW)) / 2;
+ crop.top += offset;
+ crop.bottom -= offset;
+ } else {
+ int offset = (srcCrop.w - ((extW * srcCrop.h) / extH)) / 2;
+ crop.left += offset;
+ crop.right -= offset;
+ }
+ ALOGD_IF(HWC_UTILS_DEBUG, "External Resolution [%d %d] dpy %d Modified"
+ " source crop [%d %d %d %d]", extW, extH, dpy,
+ crop.left, crop.top, crop.right, crop.bottom);
+ }
+}
+
+void updateDestAIVVideoMode(hwc_context_t *ctx, hwc_rect_t crop,
+ hwc_rect_t& dst, int dpy) {
+ ALOGD_IF(HWC_UTILS_DEBUG, "dpy %d Destination position [%d %d %d %d]", dpy,
+ dst.left, dst.top, dst.right, dst.bottom);
+ Dim srcCrop(crop.left, crop.top,
+ crop.right - crop.left,
+ crop.bottom - crop.top);
+ int extW = ctx->dpyAttr[dpy].xres;
+ int extH = ctx->dpyAttr[dpy].yres;
+ // Set the destination coordinates of external display to full screen,
+ // when zoom in mode is enabled or the ratio between video aspect ratio
+ // and external display aspect ratio is below the minimum tolerance level
+ // and above maximum tolerance level
+ float videoAspectRatio = ((float)srcCrop.w / (float)srcCrop.h);
+ float extDisplayAspectRatio = ((float)extW / (float)extH);
+ float videoToExternalRatio = videoAspectRatio / extDisplayAspectRatio;
+ if((fabs(1.0f - videoToExternalRatio) <= ctx->mAspectRatioToleranceLevel) ||
+ (isZoomModeEnabled(crop))) {
+ dst.left = 0;
+ dst.top = 0;
+ dst.right = extW;
+ dst.bottom = extH;
+ }
+ ALOGD_IF(HWC_UTILS_DEBUG, "External Resolution [%d %d] dpy %d Modified"
+ " Destination position [%d %d %d %d] Source crop [%d %d %d %d]",
+ extW, extH, dpy, dst.left, dst.top, dst.right, dst.bottom,
+ crop.left, crop.top, crop.right, crop.bottom);
+}
+
+void updateCoordinates(hwc_context_t *ctx, hwc_rect_t& crop,
+ hwc_rect_t& dst, int dpy) {
+ updateCropAIVVideoMode(ctx, crop, dpy);
+ updateDestAIVVideoMode(ctx, crop, dst, dpy);
+}
+
int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
const int& dpy, eMdpFlags& mdpFlags, eZorder& z,
const eDest& dest, Rotator **rot) {
@@ -1816,7 +1932,10 @@
else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
}
-
+ // update source crop and destination position of AIV video layer.
+ if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
+ updateCoordinates(ctx, crop, dst, dpy);
+ }
calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
int downscale = getRotDownscale(ctx, layer);
setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
@@ -1911,7 +2030,12 @@
whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
}
- /* Calculate the external display position based on MDP scaling mode,
+ // update source crop and destination position of AIV video layer.
+ if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
+ updateCoordinates(ctx, crop, dst, dpy);
+ }
+
+ /* Calculate the external display position based on MDP downscale,
ActionSafe, and extorientation features. */
calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
int downscale = getRotDownscale(ctx, layer);
@@ -2052,6 +2176,11 @@
Whf whf(getWidth(hnd), getHeight(hnd),
getMdpFormat(hnd->format), (uint32_t)hnd->size);
+ // update source crop and destination position of AIV video layer.
+ if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
+ updateCoordinates(ctx, crop, dst, dpy);
+ }
+
/* Calculate the external display position based on MDP downscale,
ActionSafe, and extorientation features. */
calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
@@ -2160,7 +2289,8 @@
if(dpy == HWC_DISPLAY_PRIMARY)
return false;
}
- if(ctx->mMDP.version == qdutils::MDP_V3_0_4)
+ if((ctx->mMDP.version == qdutils::MDP_V3_0_4)
+ ||(ctx->mMDP.version == qdutils::MDP_V3_0_5))
return false;
return true;
}
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 041ca74..68bc741 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -62,7 +62,7 @@
namespace qhwc {
//fwrd decl
class QueuedBufferStore;
-class ExternalDisplay;
+class HDMIDisplay;
class VirtualDisplay;
class IFBUpdate;
class IVideoOverlay;
@@ -141,6 +141,8 @@
int secureRGBIndices[MAX_NUM_APP_LAYERS];
//dyn refresh rate-Client requested refreshrate
uint32_t refreshRateRequest;
+ // Flag related to windowboxing feature
+ bool mAIVVideoMode;
};
//PTOR Comp info
@@ -182,6 +184,12 @@
HWC_COPYBIT = 0x00000002,
};
+// AIV specific flags
+enum {
+ HWC_AIV_VIDEO = 0x80000000,
+ HWC_AIV_CC = 0x40000000,
+};
+
// HAL specific features
enum {
HWC_COLOR_FILL = 0x00000008,
@@ -372,6 +380,12 @@
void updateSource(ovutils::eTransform& orient, ovutils::Whf& whf,
hwc_rect_t& crop, overlay::Rotator *rot);
+bool isZoomModeEnabled(hwc_rect_t crop);
+void updateCropAIVVideoMode(hwc_context_t *ctx, hwc_rect_t& crop, int dpy);
+void updateDestAIVVideoMode(hwc_context_t *ctx, hwc_rect_t& dst, int dpy);
+void updateCoordinates(hwc_context_t *ctx, hwc_rect_t& crop,
+ hwc_rect_t& dst, int dpy);
+
//Routine to configure low resolution panels (<= 2048 width)
int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
@@ -419,6 +433,14 @@
return (UNLIKELY(l && (l->flags & HWC_SKIP_LAYER)));
}
+static inline bool isAIVVideoLayer(const hwc_layer_1_t* l) {
+ return (UNLIKELY(l && (l->flags & HWC_AIV_VIDEO)));
+}
+
+static inline bool isAIVCCLayer(const hwc_layer_1_t* l) {
+ return (UNLIKELY(l && (l->flags & HWC_AIV_CC)));
+}
+
// Returns true if the buffer is yuv
static inline bool isYuvBuffer(const private_handle_t* hnd) {
return (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO));
@@ -545,8 +567,9 @@
//Primary and external FB updater
qhwc::IFBUpdate *mFBUpdate[HWC_NUM_DISPLAY_TYPES];
- // External display related information
- qhwc::ExternalDisplay *mExtDisplay;
+ // HDMI display related object. Used to configure/teardown
+ // HDMI when it is connected as primary or external.
+ qhwc::HDMIDisplay *mHDMIDisplay;
qhwc::MDPInfo mMDP;
qhwc::VsyncState vstate;
qhwc::DisplayAttributes dpyAttr[HWC_NUM_DISPLAY_TYPES];
@@ -595,6 +618,13 @@
qhwc::PtorInfo mPtorInfo;
//Running in Thermal burst mode
bool mThermalBurstMode;
+ //Layers out of ROI
+ bool copybitDrop[MAX_NUM_APP_LAYERS];
+ // Flag related to windowboxing feature
+ bool mWindowboxFeature;
+ // This denotes the tolerance between video layer and external display
+ // aspect ratio
+ float mAspectRatioToleranceLevel;
};
namespace qhwc {
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index 66988f7..07d1e4e 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -29,7 +29,6 @@
#include "hwc_utils.h"
#include "qd_utils.h"
#include "string.h"
-#include "external.h"
#include "overlay.h"
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 85c9b78..96c057f 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+* Copyright (c) 2011-2014, 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
@@ -387,7 +387,7 @@
}
}
- if (mdpVersion < qdutils::MDSS_V5 && mdpVersion != qdutils::MDP_V3_0_4) {
+ if (mdpVersion < qdutils::MDSS_V5 && mdpVersion > qdutils::MDP_V3_0_5) {
msmfb_mixer_info_req req;
mdp_mixer_info *minfo = NULL;
char name[64];
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index ddc40ee..b8bb33e 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -218,6 +218,13 @@
bool MdpCtrl::setVisualParams(const MetaData_t& data) {
ALOGD_IF(0, "In %s: data.operation = %d", __FUNCTION__, data.operation);
+
+ // Set Color Space for MDP to configure CSC matrix
+ mOVInfo.color_space = ITU_R_601;
+ if (data.operation & UPDATE_COLOR_SPACE) {
+ mOVInfo.color_space = data.colorSpace;
+ }
+
#ifdef USES_POST_PROCESSING
bool needUpdate = false;
/* calculate the data */
diff --git a/libqdutils/idle_invalidator.cpp b/libqdutils/idle_invalidator.cpp
index 86191e9..5850ce5 100644
--- a/libqdutils/idle_invalidator.cpp
+++ b/libqdutils/idle_invalidator.cpp
@@ -47,10 +47,13 @@
ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
}
-int IdleInvalidator::init(InvalidatorHandler reg_handler, void* user_data,
- unsigned int idleSleepTime) {
- ALOGD_IF(II_DEBUG, "IdleInvalidator::%s idleSleepTime %d",
- __FUNCTION__, idleSleepTime);
+IdleInvalidator::~IdleInvalidator() {
+ if(mTimeoutEventFd >= 0) {
+ close(mTimeoutEventFd);
+ }
+}
+
+int IdleInvalidator::init(InvalidatorHandler reg_handler, void* user_data) {
mHandler = reg_handler;
mHwcContext = user_data;
@@ -62,34 +65,47 @@
return -1;
}
- // Open a sysfs node to send the timeout value to driver.
- int fd = open(IDLE_TIME_PATH, O_WRONLY);
- if (fd < 0) {
- ALOGE ("%s:not able to open %s node %s",
- __FUNCTION__, IDLE_TIME_PATH, strerror(errno));
+ enum {DEFAULT_IDLE_TIME = 70}; //ms
+ if(not setIdleTimeout(DEFAULT_IDLE_TIME)) {
close(mTimeoutEventFd);
mTimeoutEventFd = -1;
return -1;
}
- char strSleepTime[64];
- snprintf(strSleepTime, sizeof(strSleepTime), "%d", idleSleepTime);
- // Notify driver about the timeout value
- ssize_t len = pwrite(fd, strSleepTime, strlen(strSleepTime), 0);
- if(len < -1) {
- ALOGE ("%s:not able to write into %s node %s",
- __FUNCTION__, IDLE_TIME_PATH, strerror(errno));
- close(mTimeoutEventFd);
- mTimeoutEventFd = -1;
- close(fd);
- return -1;
- }
- close(fd);
//Triggers the threadLoop to run, if not already running.
run(threadName, android::PRIORITY_LOWEST);
return 0;
}
+bool IdleInvalidator::setIdleTimeout(const uint32_t& timeout) {
+ ALOGD_IF(II_DEBUG, "IdleInvalidator::%s timeout %d",
+ __FUNCTION__, timeout);
+
+ // Open a sysfs node to send the timeout value to driver.
+ int fd = open(IDLE_TIME_PATH, O_WRONLY);
+
+ if (fd < 0) {
+ ALOGE ("%s:Unable to open %s node %s",
+ __FUNCTION__, IDLE_TIME_PATH, strerror(errno));
+ return false;
+ }
+
+ char strSleepTime[64];
+ snprintf(strSleepTime, sizeof(strSleepTime), "%d", timeout);
+
+ // Notify driver about the timeout value
+ ssize_t len = pwrite(fd, strSleepTime, strlen(strSleepTime), 0);
+ if(len < -1) {
+ ALOGE ("%s:Unable to write into %s node %s",
+ __FUNCTION__, IDLE_TIME_PATH, strerror(errno));
+ close(fd);
+ return false;
+ }
+
+ close(fd);
+ return true;
+}
+
bool IdleInvalidator::threadLoop() {
ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
struct pollfd pFd;
diff --git a/libqdutils/idle_invalidator.h b/libqdutils/idle_invalidator.h
index a881c4b..52334a0 100644
--- a/libqdutils/idle_invalidator.h
+++ b/libqdutils/idle_invalidator.h
@@ -37,16 +37,18 @@
typedef void (*InvalidatorHandler)(void*);
class IdleInvalidator : public android::Thread {
+ IdleInvalidator();
void *mHwcContext;
int mTimeoutEventFd;
static InvalidatorHandler mHandler;
static android::sp<IdleInvalidator> sInstance;
- public:
- IdleInvalidator();
+public:
+ ~IdleInvalidator();
/* init timer obj */
- int init(InvalidatorHandler reg_handler, void* user_data, unsigned int
- idleSleepTime);
+ int init(InvalidatorHandler reg_handler, void* user_data);
+ bool setIdleTimeout(const uint32_t& timeout);
+
/*Overrides*/
virtual bool threadLoop();
virtual int readyToRun();
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index b0a8d7d..088f82b 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -411,6 +411,10 @@
}
+bool MDPVersion::hasMinCropWidthLimitation() const {
+ return mMdpRev <= MDSS_MDP_HW_REV_102;
+}
+
bool MDPVersion::supportsDecimation() {
return mFeatures & MDP_DECIMATION_EN;
}
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index d26c55c..3c7f6a3 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -138,6 +138,7 @@
uint32_t getMinFpsSupported() { return mPanelInfo.mMinFps; }
uint32_t getMaxFpsSupported() { return mPanelInfo.mMaxFps; }
uint32_t getMaxMixerWidth() const { return mMaxMixerWidth; }
+ bool hasMinCropWidthLimitation() const;
bool isSrcSplit() const;
bool isSrcSplitAlways() const;
bool isRGBScalarSupported() const;
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index de94591..88109c9 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -90,6 +90,9 @@
case UPDATE_COLOR_SPACE:
data->colorSpace = *((ColorSpace_t *)param);
break;
+ case MAP_SECURE_BUFFER:
+ data->mapSecureBuffer = *((int32_t *)param);
+ break;
default:
ALOGE("Unknown paramType %d", paramType);
break;
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index a71ee8b..32d788e 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -79,6 +79,13 @@
int64_t timestamp;
uint32_t refreshrate;
enum ColorSpace_t colorSpace;
+ /* Gralloc sets PRIV_SECURE_BUFFER flag to inform that the buffers are from
+ * ION_SECURE. which should not be mapped. However, for GPU post proc
+ * feature, GFX needs to map this buffer, in the client context and in SF
+ * context, it should not. Hence to differentiate, add this metadata field
+ * for clients to set, and GPU will to read and know when to map the
+ * SECURE_BUFFER(ION) */
+ int32_t mapSecureBuffer;
};
enum DispParamType {
@@ -92,6 +99,7 @@
UPDATE_BUFFER_GEOMETRY = 0x0080,
UPDATE_REFRESH_RATE = 0x0100,
UPDATE_COLOR_SPACE = 0x0200,
+ MAP_SECURE_BUFFER = 0x400,
};
struct private_handle_t;
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 30c064e..3be20f1 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -53,6 +53,7 @@
SET_WFD_STATUS, // Set if wfd connection is on/off
SET_VIEW_FRAME, // Set view frame of display
DYNAMIC_DEBUG, // Enable more logging on the fly
+ SET_IDLE_TIMEOUT, // Set idle timeout for GPU fallback
COMMAND_LIST_END = 400,
};