Merge "hwc: Move aspect ratio helper function to qdutils"
diff --git a/common.mk b/common.mk
index 099ccf9..d8ea260 100644
--- a/common.mk
+++ b/common.mk
@@ -20,7 +20,8 @@
#Common C flags
common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
-common_flags += -Werror
+#TODO: Add -Werror back once all the current warnings are fixed
+common_flags += -Wconversion -Wall
ifeq ($(ARCH_ARM_HAVE_NEON),true)
common_flags += -D__ARM_HAVE_NEON
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index 1268b0f..0465521 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -113,7 +113,7 @@
* Used to show QCOM 8974 instead of Input 1 for example
*/
void ExternalDisplay::setSPDInfo(const char* node, const char* property) {
- int err = -1;
+ ssize_t err = -1;
char info[PROPERTY_VALUE_MAX];
char sysFsSPDFilePath[MAX_SYSFS_FILE_PATH];
memset(sysFsSPDFilePath, 0, sizeof(sysFsSPDFilePath));
@@ -172,7 +172,7 @@
void ExternalDisplay::readCEUnderscanInfo()
{
int hdmiScanInfoFile = -1;
- int len = -1;
+ ssize_t len = -1;
char scanInfo[17];
char *ce_info_str = NULL;
char *save_ptr;
@@ -191,7 +191,7 @@
return;
} else {
len = read(hdmiScanInfoFile, scanInfo, sizeof(scanInfo)-1);
- ALOGD("%s: Scan Info string: %s length = %d",
+ ALOGD("%s: Scan Info string: %s length = %zu",
__FUNCTION__, scanInfo, len);
if (len <= 0) {
close(hdmiScanInfoFile);
@@ -200,8 +200,8 @@
return;
}
scanInfo[len] = '\0'; /* null terminate the string */
+ close(hdmiScanInfoFile);
}
- close(hdmiScanInfoFile);
/*
* The scan_info contains the three fields
@@ -304,7 +304,7 @@
"/sys/devices/virtual/graphics/fb%d/edid_modes", mFbNum);
int hdmiEDIDFile = open(sysFsEDIDFilePath, O_RDONLY, 0);
- int len = -1;
+ ssize_t len = -1;
char edidStr[128] = {'\0'};
if (hdmiEDIDFile < 0) {
@@ -313,7 +313,7 @@
return false;
} else {
len = read(hdmiEDIDFile, edidStr, sizeof(edidStr)-1);
- ALOGD_IF(DEBUG, "%s: EDID string: %s length = %d",
+ ALOGD_IF(DEBUG, "%s: EDID string: %s length = %zu",
__FUNCTION__, edidStr, len);
if ( len <= 0) {
ALOGE("%s: edid_modes file empty '%s'",
@@ -326,8 +326,8 @@
}
edidStr[len] = '\0';
}
+ close(hdmiEDIDFile);
}
- close(hdmiEDIDFile);
if(len > 0) {
// Get EDID modes from the EDID strings
mModeCount = parseResolution(edidStr, mEDIDModes);
@@ -558,7 +558,7 @@
__FUNCTION__, sysFsHPDFilePath, hdmiHPDFile, strerror(errno));
ret = false;
} else {
- int err = -1;
+ ssize_t err = -1;
ALOGD_IF(DEBUG, "%s: option = %d", __FUNCTION__, userOption);
if(userOption)
err = write(hdmiHPDFile, "1", 2);
@@ -585,7 +585,8 @@
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()) {
+ if(!qdutils::MDPVersion::getInstance().is8x26()
+ && mHwcContext->mMDPDownscaleEnabled) {
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
@@ -607,7 +608,7 @@
}
}
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period =
- 1000000000l / fps;
+ (int) 1000000000l / fps;
}
}
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 723267b..878f17c 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -47,7 +47,6 @@
#endif
#define ASTC_BLOCK_SIZE 16
-#define ASTC_IN_UNITS(n, unit_size) (((n) + (unit_size) -1) / (unit_size))
using namespace gralloc;
using namespace qdutils;
@@ -93,6 +92,7 @@
LINK_adreno_compute_aligned_width_and_height = NULL;
LINK_adreno_compute_padding = NULL;
LINK_adreno_isMacroTilingSupportedByGpu = NULL;
+ LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
if (libadreno_utils) {
@@ -102,6 +102,9 @@
::dlsym(libadreno_utils, "compute_surface_padding");
*(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
+ *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
+ ::dlsym(libadreno_utils,
+ "compute_compressedfmt_aligned_width_and_height");
}
}
@@ -207,73 +210,47 @@
break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
- aligned_w = ASTC_IN_UNITS(width, 4);
- aligned_h = ASTC_IN_UNITS(height, 4);
- break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
- aligned_w = ASTC_IN_UNITS(width, 5);
- aligned_h = ASTC_IN_UNITS(height, 4);
- break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
- aligned_w = ASTC_IN_UNITS(width, 5);
- aligned_h = ASTC_IN_UNITS(height, 5);
- break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
- aligned_w = ASTC_IN_UNITS(width, 6);
- aligned_h = ASTC_IN_UNITS(height, 5);
- break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
- aligned_w = ASTC_IN_UNITS(width, 6);
- aligned_h = ASTC_IN_UNITS(height, 6);
- break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
- aligned_w = ASTC_IN_UNITS(width, 8);
- aligned_h = ASTC_IN_UNITS(height, 5);
- break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
- aligned_w = ASTC_IN_UNITS(width, 8);
- aligned_h = ASTC_IN_UNITS(height, 6);
- break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
- aligned_w = ASTC_IN_UNITS(width, 8);
- aligned_h = ASTC_IN_UNITS(height, 8);
- break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
- aligned_w = ASTC_IN_UNITS(width, 10);
- aligned_h = ASTC_IN_UNITS(height, 5);
- break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
- aligned_w = ASTC_IN_UNITS(width, 10);
- aligned_h = ASTC_IN_UNITS(height, 6);
- break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
- aligned_w = ASTC_IN_UNITS(width, 10);
- aligned_h = ASTC_IN_UNITS(height, 8);
- break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
- aligned_w = ASTC_IN_UNITS(width, 10);
- aligned_h = ASTC_IN_UNITS(height, 10);
- break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
- aligned_w = ASTC_IN_UNITS(width, 12);
- aligned_h = ASTC_IN_UNITS(height, 10);
- break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
- aligned_w = ASTC_IN_UNITS(width, 12);
- aligned_h = ASTC_IN_UNITS(height, 12);
+ if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
+ int bytesPerPixel = 0;
+ int raster_mode = 0; //Adreno unknown raster mode.
+ int padding_threshold = 512; //Threshold for padding
+ //surfaces.
+
+ LINK_adreno_compute_compressedfmt_aligned_width_and_height(
+ width, height, format, 0,raster_mode, padding_threshold,
+ &aligned_w, &aligned_h, &bytesPerPixel);
+
+ } else {
+ ALOGW("%s: Warning!! Symbols" \
+ " compute_compressedfmt_aligned_width_and_height" \
+ " not found", __FUNCTION__);
+ }
break;
default: break;
}
@@ -393,6 +370,7 @@
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_RGB_565:
{
tileEnabled = true;
// check the usage flags
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index bb7060b..b6253cd 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -95,13 +95,6 @@
if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY) {
flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
- //The EXTERNAL_BLOCK flag is always an add-on
- if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_BLOCK) {
- flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_BLOCK;
- }
- if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_CC) {
- flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_CC;
- }
}
if (bufferType == BUFFER_TYPE_VIDEO) {
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index 8c68e16..20b2994 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -120,12 +120,12 @@
// Pointer to the padding library.
void *libadreno_utils;
- // link to the surface padding library.
+ // link(s)to adreno surface padding library.
int (*LINK_adreno_compute_padding) (int width, int bpp,
int surface_tile_height,
int screen_tile_height,
int padding_threshold);
- // link to the surface padding library.
+
void (*LINK_adreno_compute_aligned_width_and_height) (int width,
int height,
int bpp,
@@ -134,8 +134,18 @@
int padding_threshold,
int *aligned_w,
int *aligned_h);
- // link to the surface padding library.
+
int (*LINK_adreno_isMacroTilingSupportedByGpu) (void);
+ void(*LINK_adreno_compute_compressedfmt_aligned_width_and_height)(
+ int width,
+ int height,
+ int format,
+ int tile_mode,
+ int raster_mode,
+ int padding_threshold,
+ int *aligned_w,
+ int *aligned_h,
+ int *bpp);
};
#endif /* GR_H_ */
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index c56eca9..89f1a88 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 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.
@@ -60,13 +60,8 @@
/* Buffer content should be displayed on an external display only */
GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY = 0x08000000,
- /* Only this buffer content should be displayed on external, even if
- * other EXTERNAL_ONLY buffers are available. Used during suspend.
- */
- GRALLOC_USAGE_PRIVATE_EXTERNAL_BLOCK = 0x00100000,
-
- /* Close Caption displayed on an external display only */
- GRALLOC_USAGE_PRIVATE_EXTERNAL_CC = 0x00200000,
+ /* This flag is set for WFD usecase */
+ GRALLOC_USAGE_PRIVATE_WFD = 0x00200000,
/* CAMERA heap is a carveout heap for camera, is not secured*/
GRALLOC_USAGE_PRIVATE_CAMERA_HEAP = 0x00400000,
@@ -85,6 +80,7 @@
GRALLOC_MODULE_PERFORM_GET_STRIDE,
GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE,
GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES,
+ GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE,
};
#define GRALLOC_HEAP_MASK (GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |\
@@ -194,10 +190,6 @@
PRIV_FLAGS_NOT_MAPPED = 0x00001000,
// Display on external only
PRIV_FLAGS_EXTERNAL_ONLY = 0x00002000,
- // Display only this buffer on external
- PRIV_FLAGS_EXTERNAL_BLOCK = 0x00004000,
- // Display this buffer on external as close caption
- PRIV_FLAGS_EXTERNAL_CC = 0x00008000,
PRIV_FLAGS_VIDEO_ENCODER = 0x00010000,
PRIV_FLAGS_CAMERA_WRITE = 0x00020000,
PRIV_FLAGS_CAMERA_READ = 0x00040000,
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 109c141..df9f7e4 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 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.
@@ -368,6 +368,19 @@
res = 0;
} break;
+ case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE:
+ {
+ private_handle_t* hnd = va_arg(args, private_handle_t*);
+ int *color_space = va_arg(args, int *);
+ if (private_handle_t::validate(hnd)) {
+ return res;
+ }
+ MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+ if(metadata && metadata->operation & UPDATE_COLOR_SPACE) {
+ *color_space = metadata->colorSpace;
+ res = 0;
+ }
+ } break;
default:
break;
}
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index f1c54f2..15b9da4 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -437,8 +437,11 @@
int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
- if (!ctx->mPanelResetStatus)
+ if (!ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
+ ALOGD ("%s : Display OFF - Skip BLANK & UNBLANK", __FUNCTION__);
+ ctx->mPanelResetStatus = false;
return;
+ }
ALOGD("%s: calling BLANK DISPLAY", __FUNCTION__);
ret = hwc_blank(dev, HWC_DISPLAY_PRIMARY, 1);
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index d47853a..3a4bada 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -26,6 +26,7 @@
#include "gr.h"
#include "cb_utils.h"
#include "cb_swap_rect.h"
+#include "math.h"
using namespace qdutils;
namespace qhwc {
@@ -488,12 +489,6 @@
dsdx,dtdy,copybitsMaxScale,1/copybitsMinScale,screen_w,screen_h,
src_crop_width,src_crop_height);
- //Driver makes width and height as even
- //that may cause wrong calculation of the ratio
- //in display and crop.Hence we make
- //crop width and height as even.
- src_crop_width = (src_crop_width/2)*2;
- src_crop_height = (src_crop_height/2)*2;
int tmp_w = src_crop_width;
int tmp_h = src_crop_height;
@@ -502,10 +497,11 @@
tmp_w = src_crop_width*copybitsMaxScale;
tmp_h = src_crop_height*copybitsMaxScale;
}else if (dsdx < 1/copybitsMinScale ||dtdy < 1/copybitsMinScale ){
- tmp_w = src_crop_width/copybitsMinScale;
- tmp_h = src_crop_height/copybitsMinScale;
- tmp_w = (tmp_w/2)*2;
- tmp_h = (tmp_h/2)*2;
+ // ceil the tmp_w and tmp_h value to maintain proper ratio
+ // b/w src and dst (should not cross the desired scale limit
+ // due to float -> int )
+ tmp_w = ceil(src_crop_width/copybitsMinScale);
+ tmp_h = ceil(src_crop_height/copybitsMinScale);
}
ALOGD("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h);
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index cc9e3b9..678eecb 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -39,6 +39,9 @@
IFBUpdate* IFBUpdate::getObject(hwc_context_t *ctx, const int& dpy) {
if(isDisplaySplit(ctx, dpy)) {
+ if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
+ return new FBSrcSplit(ctx, dpy);
+ }
return new FBUpdateSplit(ctx, dpy);
}
return new FBUpdateNonSplit(ctx, dpy);
@@ -278,121 +281,105 @@
bool ret = false;
hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
if (LIKELY(ctx->mOverlay)) {
+ /* External only layer present */
int extOnlyLayerIndex = ctx->listStats[mDpy].extOnlyLayerIndex;
- // ext only layer present..
if(extOnlyLayerIndex != -1) {
layer = &list->hwLayers[extOnlyLayerIndex];
layer->compositionType = HWC_OVERLAY;
}
+ ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
+ ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
+ mTileEnabled));
+
overlay::Overlay& ov = *(ctx->mOverlay);
-
- ovutils::Whf info(mAlignedFBWidth,
- mAlignedFBHeight,
- ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
- mTileEnabled));
- //Request left pipe
- ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
- Overlay::MIXER_LEFT);
- if(destL == ovutils::OV_INVALID) { //None available
- ALOGE("%s: No pipes available to configure fb for dpy %d's left"
- " mixer", __FUNCTION__, mDpy);
- return false;
- }
- //Request right pipe
- ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
- Overlay::MIXER_RIGHT);
- if(destR == ovutils::OV_INVALID) { //None available
- ALOGE("%s: No pipes available to configure fb for dpy %d's right"
- " mixer", __FUNCTION__, mDpy);
- return false;
- }
-
- mDestLeft = destL;
- mDestRight = destR;
-
- ovutils::eMdpFlags mdpFlagsL = ovutils::OV_MDP_BLEND_FG_PREMULT;
-
+ ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
-
- //XXX: FB layer plane alpha is currently sent as zero from
- //surfaceflinger
- ovutils::PipeArgs pargL(mdpFlagsL,
- info,
- zOrder,
- ovutils::IS_FG_OFF,
- ovutils::ROT_FLAGS_NONE,
- ovutils::DEFAULT_PLANE_ALPHA,
- (ovutils::eBlending)
- getBlending(layer->blending));
- ov.setSource(pargL, destL);
-
- ovutils::eMdpFlags mdpFlagsR = mdpFlagsL;
- ovutils::setMdpFlags(mdpFlagsR, ovutils::OV_MDSS_MDP_RIGHT_MIXER);
- ovutils::PipeArgs pargR(mdpFlagsR,
- info,
- zOrder,
- ovutils::IS_FG_OFF,
- ovutils::ROT_FLAGS_NONE,
- ovutils::DEFAULT_PLANE_ALPHA,
- (ovutils::eBlending)
- getBlending(layer->blending));
- ov.setSource(pargR, destR);
+ ovutils::eTransform orient =
+ static_cast<ovutils::eTransform>(layer->transform);
+ const int hw_w = ctx->dpyAttr[mDpy].xres;
+ const int hw_h = ctx->dpyAttr[mDpy].yres;
+ const int lSplit = getLeftSplit(ctx, mDpy);
+ mDestLeft = ovutils::OV_INVALID;
+ mDestRight = ovutils::OV_INVALID;
hwc_rect_t sourceCrop = fbUpdatingRect;
hwc_rect_t displayFrame = fbUpdatingRect;
- const float xres = ctx->dpyAttr[mDpy].xres;
- const int lSplit = getLeftSplit(ctx, mDpy);
- const float lSplitRatio = lSplit / xres;
- const float lCropWidth =
- (sourceCrop.right - sourceCrop.left) * lSplitRatio;
-
- ovutils::Dim dcropL(
- sourceCrop.left,
- sourceCrop.top,
- lCropWidth,
- sourceCrop.bottom - sourceCrop.top);
-
- ovutils::Dim dcropR(
- sourceCrop.left + lCropWidth,
- sourceCrop.top,
- (sourceCrop.right - sourceCrop.left) - lCropWidth,
- sourceCrop.bottom - sourceCrop.top);
-
- ov.setCrop(dcropL, destL);
- ov.setCrop(dcropR, destR);
-
- int transform = layer->transform;
- ovutils::eTransform orient =
- static_cast<ovutils::eTransform>(transform);
- ov.setTransform(orient, destL);
- ov.setTransform(orient, destR);
-
- const int lWidth = (lSplit - displayFrame.left);
- const int rWidth = (displayFrame.right - lSplit);
- const int height = displayFrame.bottom - displayFrame.top;
-
- ovutils::Dim dposL(displayFrame.left,
- displayFrame.top,
- lWidth,
- height);
- ov.setPosition(dposL, destL);
-
- ovutils::Dim dposR(0,
- displayFrame.top,
- rWidth,
- height);
- ov.setPosition(dposR, destR);
-
ret = true;
- if (!ov.commit(destL)) {
- ALOGE("%s: commit fails for left", __FUNCTION__);
- ret = false;
+ /* Configure left pipe */
+ if(displayFrame.left < lSplit) {
+ ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
+ Overlay::MIXER_LEFT);
+ if(destL == ovutils::OV_INVALID) { //None available
+ ALOGE("%s: No pipes available to configure fb for dpy %d's left"
+ " mixer", __FUNCTION__, mDpy);
+ return false;
+ }
+
+ mDestLeft = destL;
+
+ //XXX: FB layer plane alpha is currently sent as zero from
+ //surfaceflinger
+ ovutils::PipeArgs pargL(mdpFlags,
+ info,
+ zOrder,
+ ovutils::IS_FG_OFF,
+ ovutils::ROT_FLAGS_NONE,
+ ovutils::DEFAULT_PLANE_ALPHA,
+ (ovutils::eBlending)
+ getBlending(layer->blending));
+ hwc_rect_t cropL = sourceCrop;
+ hwc_rect_t dstL = displayFrame;
+ hwc_rect_t scissorL = {0, 0, lSplit, hw_h };
+ qhwc::calculate_crop_rects(cropL, dstL, scissorL, 0);
+
+ if (configMdp(ctx->mOverlay, pargL, orient, cropL,
+ dstL, NULL, destL)< 0) {
+ ALOGE("%s: configMdp fails for left FB", __FUNCTION__);
+ ret = false;
+ }
}
- if (!ov.commit(destR)) {
- ALOGE("%s: commit fails for right", __FUNCTION__);
- ret = false;
+
+ /* Configure right pipe */
+ if(displayFrame.right > lSplit) {
+ ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
+ Overlay::MIXER_RIGHT);
+ if(destR == ovutils::OV_INVALID) { //None available
+ ALOGE("%s: No pipes available to configure fb for dpy %d's"
+ " right mixer", __FUNCTION__, mDpy);
+ return false;
+ }
+
+ mDestRight = destR;
+ ovutils::eMdpFlags mdpFlagsR = mdpFlags;
+ ovutils::setMdpFlags(mdpFlagsR, ovutils::OV_MDSS_MDP_RIGHT_MIXER);
+
+ //XXX: FB layer plane alpha is currently sent as zero from
+ //surfaceflinger
+ ovutils::PipeArgs pargR(mdpFlagsR,
+ info,
+ zOrder,
+ ovutils::IS_FG_OFF,
+ ovutils::ROT_FLAGS_NONE,
+ ovutils::DEFAULT_PLANE_ALPHA,
+ (ovutils::eBlending)
+ getBlending(layer->blending));
+
+ hwc_rect_t cropR = sourceCrop;
+ hwc_rect_t dstR = displayFrame;
+ hwc_rect_t scissorR = {lSplit, 0, hw_w, hw_h };
+ qhwc::calculate_crop_rects(cropR, dstR, scissorR, 0);
+
+ dstR.left -= lSplit;
+ dstR.right -= lSplit;
+
+ if (configMdp(ctx->mOverlay, pargR, orient, cropR,
+ dstR, NULL, destR) < 0) {
+ ALOGE("%s: configMdp fails for right FB", __FUNCTION__);
+ ret = false;
+ }
}
+
if(ret == false) {
ctx->mLayerRotMap[mDpy]->clear();
}
@@ -407,18 +394,117 @@
}
bool ret = true;
overlay::Overlay& ov = *(ctx->mOverlay);
- ovutils::eDest destL = mDestLeft;
- ovutils::eDest destR = mDestRight;
- if (!ov.queueBuffer(hnd->fd, hnd->offset, destL)) {
- ALOGE("%s: queue failed for left of dpy = %d",
- __FUNCTION__, mDpy);
+ if(mDestLeft != ovutils::OV_INVALID) {
+ if (!ov.queueBuffer(hnd->fd, hnd->offset, mDestLeft)) {
+ ALOGE("%s: queue failed for left of dpy = %d",
+ __FUNCTION__, mDpy);
+ ret = false;
+ }
+ }
+ if(mDestRight != ovutils::OV_INVALID) {
+ if (!ov.queueBuffer(hnd->fd, hnd->offset, mDestRight)) {
+ ALOGE("%s: queue failed for right of dpy = %d",
+ __FUNCTION__, mDpy);
+ ret = false;
+ }
+ }
+ return ret;
+}
+
+//=================FBSrcSplit====================================
+FBSrcSplit::FBSrcSplit(hwc_context_t *ctx, const int& dpy):
+ FBUpdateSplit(ctx, dpy) {}
+
+bool FBSrcSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
+ hwc_rect_t fbUpdatingRect, int fbZorder) {
+ bool ret = false;
+ hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
+ int extOnlyLayerIndex = ctx->listStats[mDpy].extOnlyLayerIndex;
+ // ext only layer present..
+ if(extOnlyLayerIndex != -1) {
+ layer = &list->hwLayers[extOnlyLayerIndex];
+ layer->compositionType = HWC_OVERLAY;
+ }
+ overlay::Overlay& ov = *(ctx->mOverlay);
+
+ ovutils::Whf info(mAlignedFBWidth,
+ mAlignedFBHeight,
+ ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
+ mTileEnabled));
+ //Request left pipe, VG first owing to higher prio
+ ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy,
+ Overlay::MIXER_DEFAULT);
+ if(destL == ovutils::OV_INVALID) {
+ destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
+ Overlay::MIXER_DEFAULT);
+ if(destL == ovutils::OV_INVALID) {
+ ALOGE("%s: No pipes available to configure fb for dpy %d's left"
+ " mixer", __FUNCTION__, mDpy);
+ return false;
+ }
+ }
+ //Request right pipe
+ ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
+ Overlay::MIXER_DEFAULT);
+ if(destR == ovutils::OV_INVALID) {
+ ALOGE("%s: No pipes available to configure fb for dpy %d's right"
+ " mixer", __FUNCTION__, mDpy);
+ return false;
+ }
+
+ mDestLeft = destL;
+ mDestRight = destR;
+
+ ovutils::eMdpFlags mdpFlags = OV_MDP_BLEND_FG_PREMULT;
+ ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
+
+ ovutils::PipeArgs parg(mdpFlags,
+ info,
+ zOrder,
+ ovutils::IS_FG_OFF,
+ ovutils::ROT_FLAGS_NONE,
+ ovutils::DEFAULT_PLANE_ALPHA,
+ (ovutils::eBlending)
+ getBlending(layer->blending));
+ ov.setSource(parg, destL);
+ ov.setSource(parg, destR);
+
+ //Crop and Position are same for FB
+ ovutils::Dim cropPosL(
+ fbUpdatingRect.left,
+ fbUpdatingRect.top,
+ (fbUpdatingRect.right - fbUpdatingRect.left) / 2,
+ fbUpdatingRect.bottom - fbUpdatingRect.top);
+
+ ovutils::Dim cropPosR(
+ cropPosL.x + cropPosL.w,
+ cropPosL.y,
+ cropPosL.w,
+ cropPosL.h);
+
+ ov.setCrop(cropPosL, destL);
+ ov.setCrop(cropPosR, destR);
+ ov.setPosition(cropPosL, destL);
+ ov.setPosition(cropPosR, destR);
+
+ int transform = layer->transform;
+ ovutils::eTransform orient =
+ static_cast<ovutils::eTransform>(transform);
+ ov.setTransform(orient, destL);
+ ov.setTransform(orient, destR);
+
+ ret = true;
+ if (!ov.commit(destL)) {
+ ALOGE("%s: commit fails for left", __FUNCTION__);
ret = false;
}
- if (!ov.queueBuffer(hnd->fd, hnd->offset, destR)) {
- ALOGE("%s: queue failed for right of dpy = %d",
- __FUNCTION__, mDpy);
+ if (!ov.commit(destR)) {
+ ALOGE("%s: commit fails for right", __FUNCTION__);
ret = false;
}
+ if(ret == false) {
+ ctx->mLayerRotMap[mDpy]->clear();
+ }
return ret;
}
diff --git a/libhwcomposer/hwc_fbupdate.h b/libhwcomposer/hwc_fbupdate.h
index c8347fa..545f5bd 100644
--- a/libhwcomposer/hwc_fbupdate.h
+++ b/libhwcomposer/hwc_fbupdate.h
@@ -88,13 +88,24 @@
hwc_rect_t fbUpdatingRect, int fbZorder);
bool draw(hwc_context_t *ctx, private_handle_t *hnd);
void reset();
-private:
- bool configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
+
+protected:
+ virtual bool configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
hwc_rect_t fbUpdatingRect, int fbZorder);
ovutils::eDest mDestLeft; //left pipe to draw on
ovutils::eDest mDestRight; //right pipe to draw on
};
+//Source Split Handler
+class FBSrcSplit : public FBUpdateSplit {
+public:
+ explicit FBSrcSplit(hwc_context_t *ctx, const int& dpy);
+ virtual ~FBSrcSplit() {};
+private:
+ bool configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
+ hwc_rect_t fbUpdatingRect, int fbZorder);
+};
+
}; //namespace qhwc
#endif //HWC_FBUPDATE_H
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 469ffba..028af47 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -44,12 +44,13 @@
bool MDPComp::sEnableMixedMode = true;
bool MDPComp::sEnablePartialFrameUpdate = false;
int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
-double MDPComp::sMaxBw = 0.0;
-double MDPComp::sBwClaimed = 0.0;
bool MDPComp::sEnable4k2kYUVSplit = false;
MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
if(isDisplaySplit(ctx, dpy)) {
+ if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
+ return new MDPCompSrcSplit(dpy);
+ }
return new MDPCompSplit(dpy);
}
return new MDPCompNonSplit(dpy);
@@ -663,13 +664,11 @@
bool ret = false;
if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
- ret = loadBasedCompPreferGPU(ctx, list) or
- loadBasedCompPreferMDP(ctx, list) or
+ ret = loadBasedComp(ctx, list) or
cacheBasedComp(ctx, list);
} else {
ret = cacheBasedComp(ctx, list) or
- loadBasedCompPreferGPU(ctx, list) or
- loadBasedCompPreferMDP(ctx, list);
+ loadBasedComp(ctx, list);
}
return ret;
@@ -725,196 +724,89 @@
return true;
}
-bool MDPComp::loadBasedCompPreferGPU(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- if(not isLoadBasedCompDoable(ctx)) {
- return false;
- }
-
- int numAppLayers = ctx->listStats[mDpy].numAppLayers;
- mCurrentFrame.reset(numAppLayers);
-
- int stagesForMDP = min(sMaxPipesPerMixer, ctx->mOverlay->availablePipes(
- mDpy, Overlay::MIXER_DEFAULT));
- //If MDP has X possible stages, it can take X layers.
- const int batchSize = (numAppLayers - mCurrentFrame.dropCount) -
- (stagesForMDP - 1); //1 for FB
-
- if(batchSize <= 0) {
- ALOGD_IF(isDebug(), "%s: Not attempting", __FUNCTION__);
- return false;
- }
-
- int minBatchStart = -1;
- int minBatchEnd = -1;
- size_t minBatchPixelCount = SIZE_MAX;
-
- /* Iterate through the layer list to find out a contigous batch of batchSize
- * non-dropped layers with loweest pixel count */
- for(int i = 0; i <= (numAppLayers - batchSize); i++) {
- if(mCurrentFrame.drop[i])
- continue;
-
- int batchCount = batchSize;
- uint32_t batchPixelCount = 0;
- int j = i;
- for(; j < numAppLayers && batchCount; j++){
- if(!mCurrentFrame.drop[j]) {
- hwc_layer_1_t* layer = &list->hwLayers[j];
- hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t dst = layer->displayFrame;
-
- /* If we have a valid ROI, count pixels only for the MDP fetched
- * region of the buffer */
- if((ctx->listStats[mDpy].roi.w != ctx->dpyAttr[mDpy].xres) ||
- (ctx->listStats[mDpy].roi.h != ctx->dpyAttr[mDpy].yres)) {
- hwc_rect_t roi;
- roi.left = ctx->listStats[mDpy].roi.x;
- roi.top = ctx->listStats[mDpy].roi.y;
- roi.right = roi.left + ctx->listStats[mDpy].roi.w;
- roi.bottom = roi.top + ctx->listStats[mDpy].roi.h;
-
- /* valid ROI means no scaling layer is composed. So check
- * only intersection to find actual fetched pixels */
- crop = getIntersection(roi, dst);
- }
-
- batchPixelCount += (crop.right - crop.left) *
- (crop.bottom - crop.top);
- batchCount--;
- }
- }
-
- /* we dont want to program any batch of size lesser than batchSize */
- if(!batchCount && (batchPixelCount < minBatchPixelCount)) {
- minBatchPixelCount = batchPixelCount;
- minBatchStart = i;
- minBatchEnd = j-1;
- }
- }
-
- if(minBatchStart < 0) {
- ALOGD_IF(isDebug(), "%s: No batch found batchSize %d numAppLayers %d",
- __FUNCTION__, batchSize, numAppLayers);
- return false;
- }
-
- /* non-dropped layers falling ouside the selected batch will be marked for
- * MDP */
- for(int i = 0; i < numAppLayers; i++) {
- if((i < minBatchStart || i > minBatchEnd) && !mCurrentFrame.drop[i] ) {
- hwc_layer_1_t* layer = &list->hwLayers[i];
- if(not isSupportedForMDPComp(ctx, layer)) {
- ALOGD_IF(isDebug(), "%s: MDP unsupported layer found at %d",
- __FUNCTION__, i);
- reset(ctx);
- return false;
- }
- mCurrentFrame.isFBComposed[i] = false;
- }
- }
-
- mCurrentFrame.fbZ = minBatchStart;
- mCurrentFrame.fbCount = batchSize;
- mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
- mCurrentFrame.dropCount;
-
- ALOGD_IF(isDebug(), "%s: fbZ %d batchSize %d fbStart: %d fbEnd: %d",
- __FUNCTION__, mCurrentFrame.fbZ, batchSize, minBatchStart,
- minBatchEnd);
-
- if(sEnable4k2kYUVSplit){
- adjustForSourceSplit(ctx, list);
- }
-
- if(!postHeuristicsHandling(ctx, list)) {
- ALOGD_IF(isDebug(), "post heuristic handling failed");
- reset(ctx);
- return false;
- }
-
- return true;
-}
-
-bool MDPComp::loadBasedCompPreferMDP(hwc_context_t *ctx,
+bool MDPComp::loadBasedComp(hwc_context_t *ctx,
hwc_display_contents_1_t* list) {
if(not isLoadBasedCompDoable(ctx)) {
return false;
}
const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
- mCurrentFrame.reset(numAppLayers);
+ const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
+ const int stagesForMDP = min(sMaxPipesPerMixer,
+ ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
- //Full screen is from ib perspective, not actual full screen
- const int bpp = 4;
- double panelRefRate =
- 1000000000.0 / ctx->dpyAttr[mDpy].vsync_period;
+ int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
+ int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
+ int lastMDPSupportedIndex = numAppLayers;
+ int dropCount = 0;
- double bwLeft = sMaxBw - sBwClaimed;
-
- const int fullScreenLayers = bwLeft * 1000000000 / (ctx->dpyAttr[mDpy].xres
- * ctx->dpyAttr[mDpy].yres * bpp * panelRefRate);
-
- const int fbBatchSize = (numAppLayers - mCurrentFrame.dropCount)
- - (fullScreenLayers - 1);
-
- //If batch size is not at least 2, we aren't really preferring MDP, since
- //only 1 layer going to GPU could actually translate into an entire FB
- //needed to be fetched by MDP, thus needing more b/w rather than less.
- if(fbBatchSize < 2 || fbBatchSize > numAppLayers) {
- ALOGD_IF(isDebug(), "%s: Not attempting", __FUNCTION__);
- return false;
- }
-
- //Find top fbBatchSize non-dropped layers to get your batch
- int fbStart = -1, fbEnd = -1, batchCount = fbBatchSize;
- for(int i = numAppLayers - 1; i >= 0; i--) {
- if(mCurrentFrame.drop[i])
+ //Find the minimum MDP batch size
+ for(int i = 0; i < numAppLayers;i++) {
+ if(mCurrentFrame.drop[i]) {
+ dropCount++;
continue;
-
- if(fbEnd < 0)
- fbEnd = i;
-
- if(!(--batchCount)) {
- fbStart = i;
+ }
+ hwc_layer_1_t* layer = &list->hwLayers[i];
+ if(not isSupportedForMDPComp(ctx, layer)) {
+ lastMDPSupportedIndex = i;
+ mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
+ fbBatchSize = numNonDroppedLayers - mdpBatchSize;
break;
}
}
- //Bottom layers constitute MDP batch
- for(int i = 0; i < fbStart; i++) {
- if((i < fbStart || i > fbEnd) && !mCurrentFrame.drop[i] ) {
- hwc_layer_1_t* layer = &list->hwLayers[i];
- if(not isSupportedForMDPComp(ctx, layer)) {
- ALOGD_IF(isDebug(), "%s: MDP unsupported layer found at %d",
- __FUNCTION__, i);
- reset(ctx);
- return false;
- }
- mCurrentFrame.isFBComposed[i] = false;
- }
+ ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
+ "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
+ mCurrentFrame.dropCount);
+
+ //Start at a point where the fb batch should at least have 2 layers, for
+ //this mode to be justified.
+ while(fbBatchSize < 2) {
+ ++fbBatchSize;
+ --mdpBatchSize;
}
- mCurrentFrame.fbZ = fbStart;
- mCurrentFrame.fbCount = fbBatchSize;
- mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
- - mCurrentFrame.dropCount;
-
- ALOGD_IF(isDebug(), "%s: FB Z %d, app layers %d, non-dropped layers: %d, "
- "MDP Batch Size %d",__FUNCTION__, mCurrentFrame.fbZ, numAppLayers,
- numAppLayers - mCurrentFrame.dropCount, mCurrentFrame.mdpCount);
-
- if(sEnable4k2kYUVSplit){
- adjustForSourceSplit(ctx, list);
- }
-
- if(!postHeuristicsHandling(ctx, list)) {
- ALOGD_IF(isDebug(), "post heuristic handling failed");
- reset(ctx);
+ //If there are no layers for MDP, this mode doesnt make sense.
+ if(mdpBatchSize < 1) {
+ ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
+ __FUNCTION__);
return false;
}
- return true;
+ mCurrentFrame.reset(numAppLayers);
+
+ //Try with successively smaller mdp batch sizes until we succeed or reach 1
+ while(mdpBatchSize > 0) {
+ //Mark layers for MDP comp
+ int mdpBatchLeft = mdpBatchSize;
+ for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
+ if(mCurrentFrame.drop[i]) {
+ continue;
+ }
+ mCurrentFrame.isFBComposed[i] = false;
+ --mdpBatchLeft;
+ }
+
+ mCurrentFrame.fbZ = mdpBatchSize;
+ mCurrentFrame.fbCount = fbBatchSize;
+ mCurrentFrame.mdpCount = mdpBatchSize;
+
+ ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
+ __FUNCTION__, mdpBatchSize, fbBatchSize,
+ mCurrentFrame.dropCount);
+
+ if(postHeuristicsHandling(ctx, list)) {
+ ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
+ __FUNCTION__);
+ return true;
+ }
+
+ reset(ctx);
+ --mdpBatchSize;
+ ++fbBatchSize;
+ }
+
+ return false;
}
bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
@@ -1322,45 +1214,6 @@
return true;
}
-double MDPComp::calcMDPBytesRead(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- double size = 0;
- const double GIG = 1000000000.0;
-
- //Skip for targets where no device tree value for bw is supplied
- if(sMaxBw <= 0.0) {
- return 0.0;
- }
-
- for (uint32_t i = 0; i < list->numHwLayers - 1; i++) {
- if(!mCurrentFrame.isFBComposed[i]) {
- hwc_layer_1_t* layer = &list->hwLayers[i];
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if (hnd) {
- hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t dst = layer->displayFrame;
- float bpp = ((float)hnd->size) / (hnd->width * hnd->height);
- size += (bpp * (crop.right - crop.left) *
- (crop.bottom - crop.top) *
- ctx->dpyAttr[mDpy].yres / (dst.bottom - dst.top)) /
- GIG;
- }
- }
- }
-
- if(mCurrentFrame.fbCount) {
- hwc_layer_1_t* layer = &list->hwLayers[list->numHwLayers - 1];
- int tempw, temph;
- size += (getBufferSizeAndDimensions(
- layer->displayFrame.right - layer->displayFrame.left,
- layer->displayFrame.bottom - layer->displayFrame.top,
- HAL_PIXEL_FORMAT_RGBA_8888,
- tempw, temph)) / GIG;
- }
-
- return size;
-}
-
bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
hwc_display_contents_1_t* list) {
@@ -1441,13 +1294,6 @@
if(isFrameDoable(ctx)) {
generateROI(ctx, list);
- //Convert from kbps to gbps
- sMaxBw = mdpVersion.getHighBw() / 1000000.0;
- if (ctx->mExtDisplay->isConnected() ||
- ctx->mMDP.panel != MIPI_CMD_PANEL) {
- sMaxBw = mdpVersion.getLowBw() / 1000000.0;
- }
-
if(tryFullFrame(ctx, list) || tryVideoOnly(ctx, list)) {
setMDPCompLayerFlags(ctx, list);
} else {
@@ -1472,9 +1318,6 @@
mCachedFrame.cacheAll(list);
mCachedFrame.updateCounts(mCurrentFrame);
- double panelRefRate =
- 1000000000.0 / ctx->dpyAttr[mDpy].vsync_period;
- sBwClaimed += calcMDPBytesRead(ctx, list) * panelRefRate;
return ret;
}
@@ -1985,5 +1828,183 @@
return true;
}
+
+//================MDPCompSrcSplit==============================================
+bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
+ MdpPipeInfoSplit& pipe_info, ePipeType /*type*/) {
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+ hwc_rect_t dst = layer->displayFrame;
+ hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
+ pipe_info.lIndex = ovutils::OV_INVALID;
+ pipe_info.rIndex = ovutils::OV_INVALID;
+
+ //If 2 pipes are staged on a single stage of a mixer, then the left pipe
+ //should have a higher priority than the right one. Pipe priorities are
+ //starting with VG0, VG1 ... , RGB0 ..., DMA1
+ //TODO Currently we acquire VG pipes for left side and RGB/DMA for right to
+ //make sure pipe priorities are satisfied. A better way is to have priority
+ //as part of overlay object and acquire any 2 pipes. Assign the higher
+ //priority one to left side and lower to right side.
+
+ //1 pipe by default for a layer
+ pipe_info.lIndex = getMdpPipe(ctx, MDPCOMP_OV_VG, Overlay::MIXER_DEFAULT);
+ if(pipe_info.lIndex == ovutils::OV_INVALID) {
+ if(isYuvBuffer(hnd)) {
+ return false;
+ }
+ pipe_info.lIndex = getMdpPipe(ctx, MDPCOMP_OV_ANY,
+ Overlay::MIXER_DEFAULT);
+ if(pipe_info.lIndex == ovutils::OV_INVALID) {
+ return false;
+ }
+ }
+
+ //If layer's crop width or dest width > 2048, use 2 pipes
+ if((dst.right - dst.left) > qdutils::MAX_DISPLAY_DIM or
+ (crop.right - crop.left) > qdutils::MAX_DISPLAY_DIM) {
+ ePipeType rightType = isYuvBuffer(hnd) ?
+ MDPCOMP_OV_VG : MDPCOMP_OV_ANY;
+ pipe_info.rIndex = getMdpPipe(ctx, rightType, Overlay::MIXER_DEFAULT);
+ if(pipe_info.rIndex == ovutils::OV_INVALID) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool MDPCompSrcSplit::allocLayerPipes(hwc_context_t *ctx,
+ hwc_display_contents_1_t* list) {
+ for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
+ if(mCurrentFrame.isFBComposed[index]) continue;
+ hwc_layer_1_t* layer = &list->hwLayers[index];
+ int mdpIndex = mCurrentFrame.layerToMDP[index];
+ PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
+ info.pipeInfo = new MdpPipeInfoSplit;
+ info.rot = NULL;
+ MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
+
+ ePipeType type = MDPCOMP_OV_ANY;
+ if(!acquireMDPPipes(ctx, layer, pipe_info, type)) {
+ ALOGD_IF(isDebug(), "%s: Unable to get pipe for type = %d",
+ __FUNCTION__, (int) type);
+ return false;
+ }
+ }
+ return true;
+}
+
+int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
+ PipeLayerPair& PipeLayerPair) {
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+ if(!hnd) {
+ ALOGE("%s: layer handle is NULL", __FUNCTION__);
+ return -1;
+ }
+ MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+ MdpPipeInfoSplit& mdp_info =
+ *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
+ Rotator **rot = &PipeLayerPair.rot;
+ eZorder z = static_cast<eZorder>(mdp_info.zOrder);
+ eIsFg isFg = IS_FG_OFF;
+ eDest lDest = mdp_info.lIndex;
+ eDest rDest = mdp_info.rIndex;
+ hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
+ hwc_rect_t dst = layer->displayFrame;
+ int transform = layer->transform;
+ eTransform orient = static_cast<eTransform>(transform);
+ const int downscale = 0;
+ int rotFlags = ROT_FLAGS_NONE;
+ uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
+ Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
+
+ ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
+ "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
+
+ // Handle R/B swap
+ if (layer->flags & HWC_FORMAT_RB_SWAP) {
+ if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
+ whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
+ else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
+ whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
+ }
+
+ eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
+ setMdpFlags(layer, mdpFlagsL, 0, transform);
+ eMdpFlags mdpFlagsR = mdpFlagsL;
+
+ if(lDest != OV_INVALID && rDest != OV_INVALID) {
+ //Enable overfetch
+ setMdpFlags(mdpFlagsL, OV_MDSS_MDP_DUAL_PIPE);
+ }
+
+ if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
+ (*rot) = ctx->mRotMgr->getNext();
+ if((*rot) == NULL) return -1;
+ //Configure rotator for pre-rotation
+ if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
+ ALOGE("%s: configRotator failed!", __FUNCTION__);
+ return -1;
+ }
+ ctx->mLayerRotMap[mDpy]->add(layer, *rot);
+ whf.format = (*rot)->getDstFormat();
+ updateSource(orient, whf, crop);
+ rotFlags |= ROT_PREROTATED;
+ }
+
+ //If 2 pipes being used, divide layer into half, crop and dst
+ hwc_rect_t cropL = crop;
+ hwc_rect_t cropR = crop;
+ hwc_rect_t dstL = dst;
+ hwc_rect_t dstR = dst;
+ if(lDest != OV_INVALID && rDest != OV_INVALID) {
+ cropL.right = (crop.right + crop.left) / 2;
+ cropR.left = cropL.right;
+ sanitizeSourceCrop(cropL, cropR, hnd);
+
+ //Swap crops on H flip since 2 pipes are being used
+ if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
+ hwc_rect_t tmp = cropL;
+ cropL = cropR;
+ cropR = tmp;
+ }
+
+ dstL.right = (dst.right + dst.left) / 2;
+ dstR.left = dstL.right;
+ }
+
+ //For the mdp, since either we are pre-rotating or MDP does flips
+ orient = OVERLAY_TRANSFORM_0;
+ transform = 0;
+
+ //configure left pipe
+ if(lDest != OV_INVALID) {
+ PipeArgs pargL(mdpFlagsL, whf, z, isFg,
+ static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
+ (ovutils::eBlending) getBlending(layer->blending));
+
+ if(configMdp(ctx->mOverlay, pargL, orient,
+ cropL, dstL, metadata, lDest) < 0) {
+ ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
+ return -1;
+ }
+ }
+
+ //configure right pipe
+ if(rDest != OV_INVALID) {
+ PipeArgs pargR(mdpFlagsR, whf, z, isFg,
+ static_cast<eRotFlags>(rotFlags),
+ layer->planeAlpha,
+ (ovutils::eBlending) getBlending(layer->blending));
+ if(configMdp(ctx->mOverlay, pargR, orient,
+ cropR, dstR, metadata, rDest) < 0) {
+ ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
}; //namespace
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 4215881..94199e3 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -52,7 +52,7 @@
/* Initialize MDP comp*/
static bool init(hwc_context_t *ctx);
static void resetIdleFallBack() { sIdleFallBack = false; }
- static void reset() { sBwClaimed = 0.0; sHandleTimeout = false; };
+ static void reset() { sHandleTimeout = false; };
protected:
enum { MAX_SEC_LAYERS = 1 }; //TODO add property support
@@ -158,16 +158,11 @@
bool partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
/* Partial MDP comp that uses caching to save power as primary goal */
bool cacheBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- /* Partial MDP comp that prefers GPU perf-wise. Since the GPU's
- * perf is proportional to the pixels it processes, we use the number of
- * pixels as a heuristic */
- bool loadBasedCompPreferGPU(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
- /* Partial MDP comp that prefers MDP perf-wise. Since the MDP's perf is
- * proportional to the bandwidth, overlaps it sees, we use that as a
- * heuristic */
- bool loadBasedCompPreferMDP(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
+ /* Partial MDP comp that balances the load between MDP and GPU such that
+ * MDP is loaded to the max of its capacity. The lower z order layers are
+ * fed to MDP, whereas the upper ones to GPU, because the upper ones have
+ * lower number of pixels and can reduce GPU processing time */
+ bool loadBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
/* Checks if its worth doing load based partial comp */
bool isLoadBasedCompDoable(hwc_context_t *ctx);
/* checks for conditions where only video can be bypassed */
@@ -176,9 +171,6 @@
bool secureOnly);
/* checks for conditions where YUV layers cannot be bypassed */
bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
- /* calcs bytes read by MDP in gigs for a given frame */
- double calcMDPBytesRead(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
/* checks if MDP/MDSS can process current list w.r.to HW limitations
* All peculiar HW limitations should go here */
bool hwLimitationsCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list);
@@ -234,11 +226,6 @@
/* Handles the timeout event from kernel, if the value is set to true */
static bool sHandleTimeout;
static int sMaxPipesPerMixer;
- //Max bandwidth. Value is in GBPS. For ex: 2.3 means 2.3GBPS
- static double sMaxBw;
- //Tracks composition bandwidth claimed. Represented as the total
- //w*h*bpp*fps (gigabytes-per-second) going to MDP mixers.
- static double sBwClaimed;
static IdleInvalidator *idleInvalidator;
struct FrameInfo mCurrentFrame;
struct LayerCache mCachedFrame;
@@ -282,14 +269,15 @@
explicit MDPCompSplit(int dpy):MDPComp(dpy){};
virtual ~MDPCompSplit(){};
virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
-private:
+
+protected:
struct MdpPipeInfoSplit : public MdpPipeInfo {
ovutils::eDest lIndex;
ovutils::eDest rIndex;
virtual ~MdpPipeInfoSplit() {};
};
- bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
+ virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
MdpPipeInfoSplit& pipe_info, ePipeType type);
/* configure's overlay pipes for the frame */
@@ -300,6 +288,7 @@
virtual bool allocLayerPipes(hwc_context_t *ctx,
hwc_display_contents_1_t* list);
+private:
/* Increments mdpCount if 4k2k yuv layer split is enabled.
* updates framebuffer z order if fb lies above source-split layer */
virtual void adjustForSourceSplit(hwc_context_t *ctx,
@@ -310,5 +299,20 @@
PipeLayerPair& PipeLayerPair);
};
+class MDPCompSrcSplit : public MDPCompSplit {
+public:
+ explicit MDPCompSrcSplit(int dpy) : MDPCompSplit(dpy){};
+ virtual ~MDPCompSrcSplit(){};
+private:
+ virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
+ MdpPipeInfoSplit& pipe_info, ePipeType type);
+
+ virtual bool allocLayerPipes(hwc_context_t *ctx,
+ hwc_display_contents_1_t* list);
+
+ virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
+ PipeLayerPair& pipeLayerPair);
+};
+
}; //namespace
#endif
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index f2a4bda..85a9a43 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -239,6 +239,14 @@
ctx->mBufferMirrorMode = false;
ctx->mVPUClient = NULL;
+ // Read the system property to determine if downscale feature is enabled.
+ ctx->mMDPDownscaleEnabled = false;
+ char value[PROPERTY_VALUE_MAX];
+ if(property_get("sys.hwc.mdp_downscale_enabled", value, "false")
+ && !strcmp(value, "true")) {
+ ctx->mMDPDownscaleEnabled = true;
+ }
+
#ifdef VPU_TARGET
if(qdutils::MDPVersion::getInstance().is8092())
ctx->mVPUClient = new VPUClient(ctx);
@@ -958,8 +966,14 @@
bool isActionSafePresent(hwc_context_t *ctx, int dpy) {
// if external supports underscan, do nothing
// it will be taken care in the driver
- if(!dpy || ctx->mExtDisplay->isCEUnderscanSupported())
+ // Disable Action safe for 8974 due to HW limitation for downscaling
+ // layers with overlapped region
+ // Disable Actionsafe for non HDMI displays.
+ if(!(dpy == HWC_DISPLAY_EXTERNAL) ||
+ qdutils::MDPVersion::getInstance().is8x74v2() ||
+ ctx->mExtDisplay->isCEUnderscanSupported()) {
return false;
+ }
char value[PROPERTY_VALUE_MAX];
// Read action safe properties
@@ -1697,6 +1711,10 @@
whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
}
+ /* Calculate the external display position based on MDP downscale,
+ ActionSafe, and extorientation features. */
+ calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
+
setMdpFlags(layer, mdpFlagsL, 0, transform);
if(lDest != OV_INVALID && rDest != OV_INVALID) {
@@ -1832,6 +1850,10 @@
Whf whf(getWidth(hnd), getHeight(hnd),
getMdpFormat(hnd->format), hnd->size);
+ /* Calculate the external display position based on MDP downscale,
+ ActionSafe, and extorientation features. */
+ calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
+
setMdpFlags(layer, mdpFlagsL, 0, transform);
trimLayer(ctx, dpy, transform, crop, dst);
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 5d977af..4aa6410 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -379,16 +379,6 @@
return (hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY));
}
-//Return true if buffer is for external display only with a BLOCK flag.
-static inline bool isExtBlock(const private_handle_t* hnd) {
- return (hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_EXTERNAL_BLOCK));
-}
-
-//Return true if buffer is for external display only with a Close Caption flag.
-static inline bool isExtCC(const private_handle_t* hnd) {
- return (hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_EXTERNAL_CC));
-}
-
//Return true if the buffer is intended for Secure Display
static inline bool isSecureDisplayBuffer(const private_handle_t* hnd) {
return (hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY));
@@ -513,6 +503,9 @@
bool mPanelResetStatus;
// number of active Displays
int numActiveDisplays;
+ // Downscale feature switch, set via system the property
+ // sys.hwc.mdp_downscale_enabled
+ bool mMDPDownscaleEnabled;
};
namespace qhwc {
diff --git a/liblight/lights.c b/liblight/lights.c
index 229777a..1aa0b58 100644
--- a/liblight/lights.c
+++ b/liblight/lights.c
@@ -84,7 +84,7 @@
if (fd >= 0) {
char buffer[20];
int bytes = sprintf(buffer, "%d\n", value);
- int amt = write(fd, buffer, bytes);
+ ssize_t amt = write(fd, buffer, (size_t)bytes);
close(fd);
return amt == -1 ? -errno : 0;
} else {
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index 41efc48..ddba868 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -161,8 +161,7 @@
case HAL_PIXEL_FORMAT_RGBX_8888:
return MDP_RGBX_8888_TILE;
case HAL_PIXEL_FORMAT_RGB_565:
- // Currenty Driver doesnt support 565 tile format
- return MDP_RGB_565;
+ return MDP_RGB_565_TILE;
case HAL_PIXEL_FORMAT_BGRA_8888:
return MDP_BGRA_8888_TILE;
case HAL_PIXEL_FORMAT_BGRX_8888:
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index 400d96a..c0066f3 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -555,6 +555,7 @@
formats[MDP_XRGB_8888_TILE] = STR(MDP_XRGB_8888_TILE);
formats[MDP_XBGR_8888_TILE] = STR(MDP_XBGR_8888_TILE);
formats[MDP_BGRX_8888_TILE] = STR(MDP_BGRX_8888_TILE);
+ formats[MDP_RGB_565_TILE] = STR(MDP_RGB_565_TILE);
formats[MDP_IMGTYPE_LIMIT] = STR(MDP_IMGTYPE_LIMIT);
if(format < 0 || format >= MDP_IMGTYPE_LIMIT) {
diff --git a/libqdutils/cb_utils.cpp b/libqdutils/cb_utils.cpp
index 3d07c4f..a2b706c 100644
--- a/libqdutils/cb_utils.cpp
+++ b/libqdutils/cb_utils.cpp
@@ -43,14 +43,14 @@
int CBUtils::getuiClearRegion(hwc_display_contents_1_t* list,
hwc_rect_t &clearWormholeRect, LayerProp *layerProp) {
- uint32_t last = list->numHwLayers - 1;
+ size_t last = list->numHwLayers - 1;
hwc_rect_t fbFrame = list->hwLayers[last].displayFrame;
Rect fbFrameRect(fbFrame.left,fbFrame.top,fbFrame.right,fbFrame.bottom);
Region wormholeRegion(fbFrameRect);
if(cb_swap_rect::getInstance().checkSwapRectFeature_on() == true){
wormholeRegion.set(0,0);
- for(uint32_t i = 0 ; i < last; i++) {
+ for(size_t i = 0 ; i < last; i++) {
if((list->hwLayers[i].blending == HWC_BLENDING_NONE) ||
!(layerProp[i].mFlags & HWC_COPYBIT) ||
(list->hwLayers[i].flags & HWC_SKIP_HWC_COMPOSITION))
@@ -61,7 +61,7 @@
wormholeRegion.set(tmpRect);
}
}else{
- for (uint32_t i = 0 ; i < last; i++) {
+ for (size_t i = 0 ; i < last; i++) {
// need to take care only in per pixel blending.
// Restrict calculation only for copybit layers.
if((list->hwLayers[i].blending != HWC_BLENDING_NONE) ||
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index c341dfa..ed21b2c 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -70,6 +70,7 @@
mPanelType = NO_PANEL;
mLowBw = 0;
mHighBw = 0;
+ mSourceSplit = false;
if(!updatePanelInfo()) {
ALOGE("Unable to read Primary Panel Information");
@@ -184,13 +185,13 @@
mMdpRev = atoi(tokens[1]);
}
else if(!strncmp(tokens[0], "rgb_pipes", strlen("rgb_pipes"))) {
- mRGBPipes = atoi(tokens[1]);
+ mRGBPipes = (uint8_t)atoi(tokens[1]);
}
else if(!strncmp(tokens[0], "vig_pipes", strlen("vig_pipes"))) {
- mVGPipes = atoi(tokens[1]);
+ mVGPipes = (uint8_t)atoi(tokens[1]);
}
else if(!strncmp(tokens[0], "dma_pipes", strlen("dma_pipes"))) {
- mDMAPipes = atoi(tokens[1]);
+ mDMAPipes = (uint8_t)atoi(tokens[1]);
}
else if(!strncmp(tokens[0], "max_downscale_ratio",
strlen("max_downscale_ratio"))) {
@@ -218,6 +219,9 @@
strlen("tile_format"))) {
if(enableMacroTile)
mMacroTileEnabled = true;
+ } else if(!strncmp(tokens[i], "src_split",
+ strlen("src_split"))) {
+ mSourceSplit = true;
}
}
}
@@ -287,6 +291,10 @@
return mMacroTileEnabled;
}
+bool MDPVersion::isSrcSplit() const {
+ return mSourceSplit;
+}
+
bool MDPVersion::is8x26() {
return (mMdpRev >= MDSS_MDP_HW_REV_101 and
mMdpRev < MDSS_MDP_HW_REV_102);
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index 853b9f5..5e36291 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -100,7 +100,9 @@
int getMDPVersion() {return mMDPVersion;}
char getPanelType() {return mPanelType;}
bool hasOverlay() {return mHasOverlay;}
- uint8_t getTotalPipes() { return (mRGBPipes + mVGPipes + mDMAPipes);}
+ uint8_t getTotalPipes() {
+ return (uint8_t)(mRGBPipes + mVGPipes + mDMAPipes);
+ }
uint8_t getRGBPipes() { return mRGBPipes; }
uint8_t getVGPipes() { return mVGPipes; }
uint8_t getDMAPipes() { return mDMAPipes; }
@@ -113,6 +115,7 @@
int getRightSplit() { return mSplit.right(); }
unsigned long getLowBw() { return mLowBw; }
unsigned long getHighBw() { return mHighBw; }
+ bool isSrcSplit() const;
bool is8x26();
bool is8x74v2();
bool is8084();
@@ -139,6 +142,7 @@
Split mSplit;
unsigned long mLowBw; //kbps
unsigned long mHighBw; //kbps
+ bool mSourceSplit;
};
}; //namespace qdutils
#endif //INCLUDE_LIBQCOMUTILS_MDPVER
diff --git a/libqdutils/profiler.cpp b/libqdutils/profiler.cpp
index 997c839..56bb2c6 100644
--- a/libqdutils/profiler.cpp
+++ b/libqdutils/profiler.cpp
@@ -90,7 +90,7 @@
debug_fps_metadata.ignorethresh_us = atoi(prop);
debug_fps_metadata.framearrival_steps =
- (debug_fps_metadata.ignorethresh_us / 16666);
+ (unsigned int)(debug_fps_metadata.ignorethresh_us / 16666);
if (debug_fps_metadata.framearrival_steps > MAX_FRAMEARRIVAL_STEPS) {
debug_fps_metadata.framearrival_steps = MAX_FRAMEARRIVAL_STEPS;
@@ -106,7 +106,7 @@
debug_fps_metadata.curr_frame = 0;
- ALOGD("period: %d", debug_fps_metadata.period);
+ ALOGD("period: %u", debug_fps_metadata.period);
ALOGD("ignorethresh_us: %"PRId64, debug_fps_metadata.ignorethresh_us);
}
@@ -165,7 +165,8 @@
debug_fps_metadata.curr_frame++;
if (debug_fps_level > 1) {
- unsigned int currstep = (diff + debug_fps_metadata.margin_us) / 16666;
+ unsigned int currstep =
+ (unsigned int)(diff + debug_fps_metadata.margin_us) / 16666;
if (currstep < debug_fps_metadata.framearrival_steps) {
debug_fps_metadata.accum_framearrivals[currstep-1]++;
@@ -178,14 +179,15 @@
nsecs_t sum = 0;
for (unsigned int i = 0; i < debug_fps_metadata.period; i++)
sum += debug_fps_metadata.framearrivals[i];
- print_fps((debug_fps_metadata.period * float(1000000))/float(sum));
+ print_fps(float(float(debug_fps_metadata.period * 1000000) /
+ (float)sum));
}
}
else if (debug_fps_metadata_t::DFM_TIME == debug_fps_metadata.type) {
- debug_fps_metadata.time_elapsed += ((float)diff/1000.0);
+ debug_fps_metadata.time_elapsed += (float)((float)diff/1000.0);
if (debug_fps_metadata.time_elapsed >= debug_fps_metadata.time_period) {
- float fps = (1000.0 * debug_fps_metadata.curr_frame)/
- (float)debug_fps_metadata.time_elapsed;
+ float fps = float(1000.0 * debug_fps_metadata.curr_frame/
+ debug_fps_metadata.time_elapsed);
print_fps(fps);
}
}
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index ecbf873..b736478 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -103,12 +103,15 @@
}
}
break;
+ case UPDATE_COLOR_SPACE:
+ data->colorSpace = *((ColorSpace_t *)param);
+ break;
default:
ALOGE("Unknown paramType %d", paramType);
break;
}
if(munmap(base, size))
- ALOGE("%s: failed to unmap ptr 0x%"PRIdPTR", err %d", __func__, (intptr_t)base,
+ ALOGE("%s: failed to unmap ptr %p, err %d", __func__, (void*)base,
errno);
return 0;
}
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index 4b6e678..3a0e615 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -30,6 +30,10 @@
#ifndef _QDMETADATA_H
#define _QDMETADATA_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define MAX_IGC_LUT_ENTRIES 256
#define MAX_VFM_DATA_SIZE 64 //bytes per data buffer
#define MAX_VFM_DATA_COUNT 16 //number of data buffers
@@ -45,6 +49,12 @@
return indx;
}
+enum ColorSpace_t{
+ ITU_R_601,
+ ITU_R_601_FR,
+ ITU_R_709,
+};
+
struct HSICData_t {
int32_t hue;
float saturation;
@@ -78,18 +88,19 @@
struct MetaData_t {
int32_t operation;
int32_t interlaced;
- BufferDim_t bufferDim;
- HSICData_t hsicData;
+ struct BufferDim_t bufferDim;
+ struct HSICData_t hsicData;
int32_t sharpness;
int32_t video_interface;
- IGCData_t igcData;
- Sharp2Data_t Sharp2Data;
+ struct IGCData_t igcData;
+ struct Sharp2Data_t Sharp2Data;
int64_t timestamp;
int32_t vfmDataBitMap;
- VfmData_t vfmData[MAX_VFM_DATA_COUNT];
+ struct VfmData_t vfmData[MAX_VFM_DATA_COUNT];
+ enum ColorSpace_t colorSpace;
};
-typedef enum {
+enum DispParamType {
PP_PARAM_HSIC = 0x0001,
PP_PARAM_SHARPNESS = 0x0002,
PP_PARAM_INTERLACED = 0x0004,
@@ -99,9 +110,16 @@
PP_PARAM_TIMESTAMP = 0x0040,
UPDATE_BUFFER_GEOMETRY = 0x0080,
PP_PARAM_VFM_DATA = 0x0100,
-} DispParamType;
+ UPDATE_COLOR_SPACE = 0x0200,
+};
-int setMetaData(private_handle_t *handle, DispParamType paramType, void *param);
+struct private_handle_t;
+int setMetaData(struct private_handle_t *handle, enum DispParamType paramType,
+ void *param);
+
+#ifdef __cplusplus
+}
+#endif
#endif /* _QDMETADATA_H */
diff --git a/libqdutils/qd_utils.cpp b/libqdutils/qd_utils.cpp
index 1ac2b63..f67de52 100644
--- a/libqdutils/qd_utils.cpp
+++ b/libqdutils/qd_utils.cpp
@@ -88,7 +88,7 @@
return 0;
}
- size = read(edidFile, (char*)buffer, EDID_RAW_DATA_SIZE);
+ size = (int)read(edidFile, (char*)buffer, EDID_RAW_DATA_SIZE);
close(edidFile);
return size;
}
diff --git a/libqservice/IQService.cpp b/libqservice/IQService.cpp
index f0d7576..eee22f0 100644
--- a/libqservice/IQService.cpp
+++ b/libqservice/IQService.cpp
@@ -125,8 +125,10 @@
if (fd < 0) {
strlcpy(buf, "Unknown", size);
} else {
- int len = read(fd, buf, size - 1);
- buf[len] = 0;
+ ssize_t len = read(fd, buf, size - 1);
+ if (len >= 0)
+ buf[len] = 0;
+
close(fd);
}
}
diff --git a/libvirtual/virtual.cpp b/libvirtual/virtual.cpp
index 795d8a1..7d8b942 100644
--- a/libvirtual/virtual.cpp
+++ b/libvirtual/virtual.cpp
@@ -167,7 +167,13 @@
initResolution(extW, extH);
- if(!qdutils::MDPVersion::getInstance().is8x26()) {
+ // Dynamic Resolution Change depends on MDP downscaling.
+ // MDP downscale property will be ignored to exercise DRC use case.
+ // If DRC is in progress, ext WxH will have non-zero values.
+ bool isDRC = (extW > 0) && (extH > 0);
+
+ if(!qdutils::MDPVersion::getInstance().is8x26()
+ && (mHwcContext->mMDPDownscaleEnabled || isDRC)) {
// maxArea represents the maximum resolution between
// primary and virtual display.