Merge "overlay: Use correct downscale for rotator."
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index fa63b4c..efbd350 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -1297,12 +1297,6 @@
unmap_gpuaddr(ctx, mapped_src_idx);
return COPYBIT_FAILURE;
}
- } else {
- int c2d_format = get_format(src->format);
- if(is_alpha(c2d_format))
- src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE;
- else
- src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
}
} else {
src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index 3f13906..af28bce 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -174,6 +174,10 @@
memset(&mVInfo, 0, sizeof(mVInfo));
//Determine the fb index for external display devices.
updateExtDispDevFbIndex();
+ // disable HPD at start, it will be enabled later
+ // when the display powers on
+ // This helps for framework reboot or adb shell stop/start
+ writeHPDOption(0);
}
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 8ef5611..c697cf8 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -283,8 +283,6 @@
size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
break;
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
- case HAL_PIXEL_FORMAT_YCbCr_420_SP:
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YV12:
if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
ALOGE("w or h is odd for the YV12 format");
@@ -301,6 +299,11 @@
}
size = ALIGN(size, 4096);
break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ alignedh = height;
+ size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
+ break;
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
if(width & 1) {
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 8b9a6c5..628494b 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -174,7 +174,7 @@
if ((ssize_t)size <= 0)
return -EINVAL;
- size = (bufferSize != 0)? bufferSize : size;
+ size = (bufferSize >= size)? bufferSize : size;
// All buffers marked as protected or for external
// display need to go to overlay
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 540040a..bc705ac 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -108,17 +108,12 @@
}
//clear prev layer prop flags and realloc for current frame
-static void reset_layer_prop(hwc_context_t* ctx, int dpy) {
- int layer_count = ctx->listStats[dpy].numAppLayers;
-
+static void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers) {
if(ctx->layerProp[dpy]) {
delete[] ctx->layerProp[dpy];
ctx->layerProp[dpy] = NULL;
}
-
- if(layer_count) {
- ctx->layerProp[dpy] = new LayerProp[layer_count];
- }
+ ctx->layerProp[dpy] = new LayerProp[numAppLayers];
}
static int display_commit(hwc_context_t *ctx, int dpy) {
@@ -136,23 +131,27 @@
hwc_display_contents_1_t *list) {
hwc_context_t* ctx = (hwc_context_t*)(dev);
const int dpy = HWC_DISPLAY_PRIMARY;
- if (LIKELY(list && list->numHwLayers > 1 &&
- list->numHwLayers <= MAX_NUM_LAYERS) && ctx->dpyAttr[dpy].isActive) {
+ if (LIKELY(list && list->numHwLayers > 1) &&
+ ctx->dpyAttr[dpy].isActive) {
+ reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(fbLayer->handle) {
+ if(list->numHwLayers > MAX_NUM_LAYERS) {
+ ctx->mFBUpdate[dpy]->prepare(ctx, list);
+ return 0;
+ }
setListStats(ctx, list, dpy);
- reset_layer_prop(ctx, dpy);
- int ret = ctx->mMDPComp->prepare(ctx, list);
+ bool ret = ctx->mMDPComp->prepare(ctx, list);
if(!ret) {
// IF MDPcomp fails use this route
ctx->mVidOv[dpy]->prepare(ctx, list);
ctx->mFBUpdate[dpy]->prepare(ctx, list);
+ // Use Copybit, when MDP comp fails
+ if(ctx->mCopyBit[dpy])
+ ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
+ ctx->mLayerCache[dpy]->updateLayerCache(list);
}
- ctx->mLayerCache[dpy]->updateLayerCache(list);
- // Use Copybit, when MDP comp fails
- if(!ret && ctx->mCopyBit[dpy])
- ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
}
}
return 0;
@@ -162,22 +161,25 @@
hwc_display_contents_1_t *list, int dpy) {
hwc_context_t* ctx = (hwc_context_t*)(dev);
- if (LIKELY(list && list->numHwLayers > 1 &&
- list->numHwLayers <= MAX_NUM_LAYERS) &&
- ctx->dpyAttr[dpy].isActive &&
- ctx->dpyAttr[dpy].connected) {
+ if (LIKELY(list && list->numHwLayers > 1) &&
+ ctx->dpyAttr[dpy].isActive &&
+ ctx->dpyAttr[dpy].connected) {
+ reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
uint32_t last = list->numHwLayers - 1;
+ hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(!ctx->dpyAttr[dpy].isPause) {
- hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(fbLayer->handle) {
+ ctx->mExtDispConfiguring = false;
+ if(list->numHwLayers > MAX_NUM_LAYERS) {
+ ctx->mFBUpdate[dpy]->prepare(ctx, list);
+ return 0;
+ }
setListStats(ctx, list, dpy);
- reset_layer_prop(ctx, dpy);
ctx->mVidOv[dpy]->prepare(ctx, list);
ctx->mFBUpdate[dpy]->prepare(ctx, list);
ctx->mLayerCache[dpy]->updateLayerCache(list);
if(ctx->mCopyBit[dpy])
ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
- ctx->mExtDispConfiguring = false;
}
} else {
// External Display is in Pause state.
@@ -200,6 +202,7 @@
ctx->mOverlay->configBegin();
ctx->mRotMgr->configBegin();
+ ctx->mNeedsRotator = false;
for (int32_t i = numDisplays; i >= 0; i--) {
hwc_display_contents_1_t *list = displays[i];
@@ -361,19 +364,15 @@
//TODO We dont check for SKIP flag on this layer because we need PAN
//always. Last layer is always FB
- private_handle_t *hnd = NULL;
+ private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
if(copybitDone) {
hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
- } else {
- hnd = (private_handle_t *)fbLayer->handle;
}
- if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
- if(!(fbLayer->flags & HWC_SKIP_LAYER) &&
- (list->numHwLayers > 1)) {
- if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
- ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
- ret = -1;
- }
+
+ if(hnd) {
+ if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
+ ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
+ ret = -1;
}
}
@@ -412,16 +411,12 @@
ret = -1;
}
- private_handle_t *hnd = NULL;
+ private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
if(copybitDone) {
hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
- } else {
- hnd = (private_handle_t *)fbLayer->handle;
}
- if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET &&
- !(fbLayer->flags & HWC_SKIP_LAYER) && hnd &&
- (list->numHwLayers > 1)) {
+ if(hnd) {
if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
ret = -1;
@@ -430,7 +425,7 @@
if (display_commit(ctx, dpy) < 0) {
ALOGE("%s: display commit fail!", __FUNCTION__);
- return -1;
+ ret = -1;
}
}
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index aa05aa9..3f40753 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -93,7 +93,7 @@
if (compositionType & qdutils::COMPOSITION_TYPE_DYN) {
// DYN Composition:
- // use copybit, if (TotalRGBRenderArea < 2 * FB Area)
+ // use copybit, if (TotalRGBRenderArea < threashold * FB Area)
// this is done based on perf inputs in ICS
// TODO: Above condition needs to be re-evaluated in JB
int fbWidth = ctx->dpyAttr[dpy].xres;
@@ -102,7 +102,7 @@
unsigned int renderArea = getRGBRenderingArea(list);
ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u",
__FUNCTION__, renderArea, fbArea);
- if (renderArea <= (2 * fbArea)) {
+ if (renderArea < (mDynThreshold * fbArea)) {
return true;
}
} else if ((compositionType & qdutils::COMPOSITION_TYPE_MDP)) {
@@ -554,6 +554,11 @@
mRenderBuffer[i] = NULL;
mRelFd[0] = -1;
mRelFd[1] = -1;
+
+ char value[PROPERTY_VALUE_MAX];
+ property_get("debug.hwc.dynThreshold", value, "2");
+ mDynThreshold = atof(value);
+
if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
if(copybit_open(module, &mEngine) < 0) {
ALOGE("FATAL ERROR: copybit open failed.");
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index bc3f263..a2d6405 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -80,6 +80,9 @@
//These are the the release FDs of the T-2 and T-1 round
//We wait on the T-2 fence
int mRelFd[2];
+
+ //Dynamic composition threshold for deciding copybit usage.
+ double mDynThreshold;
};
}; //namespace qhwc
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 7a740ee..a8ad8fe 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -66,10 +66,6 @@
if (LIKELY(ctx->mOverlay)) {
overlay::Overlay& ov = *(ctx->mOverlay);
private_handle_t *hnd = (private_handle_t *)layer->handle;
- if (!hnd) {
- ALOGE("%s:NULL private handle for layer!", __FUNCTION__);
- return false;
- }
ovutils::Whf info(hnd->width, hnd->height,
ovutils::getMdpFormat(hnd->format), hnd->size);
@@ -167,10 +163,6 @@
if (LIKELY(ctx->mOverlay)) {
overlay::Overlay& ov = *(ctx->mOverlay);
private_handle_t *hnd = (private_handle_t *)layer->handle;
- if (!hnd) {
- ALOGE("%s:NULL private handle for layer!", __FUNCTION__);
- return false;
- }
ovutils::Whf info(hnd->width, hnd->height,
ovutils::getMdpFormat(hnd->format), hnd->size);
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index f141af8..56432db 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -250,6 +250,7 @@
case MDPCOMP_OV_DMA:
mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, dpy);
if(mdp_pipe != ovutils::OV_INVALID) {
+ ctx->mDMAInUse = true;
return mdp_pipe;
}
case MDPCOMP_OV_ANY:
@@ -277,10 +278,14 @@
//Number of layers
const int dpy = HWC_DISPLAY_PRIMARY;
int numAppLayers = ctx->listStats[dpy].numAppLayers;
+ int numDMAPipes = qdutils::MDPVersion::getInstance().getDMAPipes();
overlay::Overlay& ov = *ctx->mOverlay;
int availablePipes = ov.availablePipes(dpy);
+ if(ctx->mNeedsRotator)
+ availablePipes -= numDMAPipes;
+
if(numAppLayers < 1 || numAppLayers > MAX_PIPES_PER_MIXER ||
pipesNeeded(ctx, list) > availablePipes) {
ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__);
@@ -320,14 +325,19 @@
return false;
}
+ if(ctx->mNeedsRotator && ctx->mDMAInUse) {
+ ALOGD_IF(isDebug(), "%s: DMA not available for Rotator",__FUNCTION__);
+ return false;
+ }
+
//MDP composition is not efficient if layer needs rotator.
for(int i = 0; i < numAppLayers; ++i) {
// As MDP h/w supports flip operation, use MDP comp only for
// 180 transforms. Fail for any transform involving 90 (90, 270).
hwc_layer_1_t* layer = &list->hwLayers[i];
private_handle_t *hnd = (private_handle_t *)layer->handle;
- if((layer->transform & HWC_TRANSFORM_ROT_90) && (!isYuvBuffer(hnd)
- || !canRotate())) {
+
+ if(layer->transform & HWC_TRANSFORM_ROT_90 && !isYuvBuffer(hnd)) {
ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
return false;
}
@@ -347,6 +357,7 @@
return -1;
}
+ ctx->mDMAInUse = false;
if(!allocLayerPipes(ctx, list, mCurrentFrame)) {
ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
return false;
@@ -468,7 +479,14 @@
info.rot = NULL;
MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo;
- pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_ANY);
+ ePipeType type = MDPCOMP_OV_ANY;
+
+ if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator
+ && ctx->mMDP.version >= qdutils::MDSS_V5) {
+ type = MDPCOMP_OV_DMA;
+ }
+
+ pipe_info.index = getMdpPipe(ctx, type);
if(pipe_info.index == ovutils::OV_INVALID) {
ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
return false;
@@ -637,7 +655,7 @@
ePipeType type = MDPCOMP_OV_ANY;
- if(!qhwc::needsScaling(layer) && !ctx->mDMAInUse
+ if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator
&& ctx->mMDP.version >= qdutils::MDSS_V5)
type = MDPCOMP_OV_DMA;
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 926f637..d847f56 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -88,8 +88,6 @@
/* configures MPD pipes */
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
PipeLayerPair& pipeLayerPair) = 0;
- /* Is rotation supported */
- virtual bool canRotate(){ return true; };
/* set/reset flags for MDPComp */
@@ -173,7 +171,6 @@
FrameInfo& current_frame);
virtual int pipesNeeded(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- virtual bool canRotate(){ return false; };
};
}; //namespace
#endif
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index f9b1afc..dd8c292 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -122,7 +122,6 @@
IVideoOverlay::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
HWC_DISPLAY_PRIMARY);
- char value[PROPERTY_VALUE_MAX];
// Check if the target supports copybit compostion (dyn/mdp/c2d) to
// decide if we need to open the copybit module.
int compositionType =
@@ -284,9 +283,21 @@
}
bool isAlphaScaled(hwc_layer_1_t const* layer) {
- if(needsScaling(layer)) {
- if(layer->blending != HWC_BLENDING_NONE)
+ if(needsScaling(layer) && isAlphaPresent(layer)) {
+ return true;
+ }
+ return false;
+}
+
+bool isAlphaPresent(hwc_layer_1_t const* layer) {
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+ int format = hnd->format;
+ switch(format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ // In any more formats with Alpha go here..
return true;
+ default : return false;
}
return false;
}
@@ -299,7 +310,6 @@
ctx->listStats[dpy].skipCount = 0;
ctx->listStats[dpy].needsAlphaScale = false;
ctx->listStats[dpy].yuvCount = 0;
- ctx->mDMAInUse = false;
for (size_t i = 0; i < list->numHwLayers; i++) {
hwc_layer_1_t const* layer = &list->hwLayers[i];
@@ -318,8 +328,8 @@
ctx->listStats[dpy].yuvIndices[yuvCount] = i;
yuvCount++;
- if((layer->transform & HWC_TRANSFORM_ROT_90) && !ctx->mDMAInUse)
- ctx->mDMAInUse = true;
+ if(layer->transform & HWC_TRANSFORM_ROT_90)
+ ctx->mNeedsRotator = true;
}
if(!ctx->listStats[dpy].needsAlphaScale)
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index e4431d0..254903e 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -33,9 +33,7 @@
#define ALIGN_TO(x, align) (((x) + ((align)-1)) & ~((align)-1))
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-#define FINAL_TRANSFORM_MASK 0x000F
-#define MAX_NUM_DISPLAYS 4 //Yes, this is ambitious
-#define MAX_NUM_LAYERS 32
+#define MAX_NUM_LAYERS 32 //includes fb layer
#define MAX_DISPLAY_DIM 2048
// For support of virtual displays
@@ -143,6 +141,7 @@
bool isSecureModePolicy(int mdpVersion);
bool isExternalActive(hwc_context_t* ctx);
bool needsScaling(hwc_layer_1_t const* layer);
+bool isAlphaPresent(hwc_layer_1_t const* layer);
int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable);
//Helper function to dump logs
@@ -296,6 +295,8 @@
struct vsync_state vstate;
//DMA used for rotator
bool mDMAInUse;
+ //MDP rotater needed
+ bool mNeedsRotator;
};
namespace qhwc {
diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp
index 2166a5b..f09cc35 100644
--- a/libhwcomposer/hwc_video.cpp
+++ b/libhwcomposer/hwc_video.cpp
@@ -94,6 +94,13 @@
}
}
+ if((layer->transform & HWC_TRANSFORM_ROT_90) && ctx->mDMAInUse) {
+ ctx->mDMAInUse = false;
+ ALOGD_IF(VIDEO_DEBUG, "%s: Rotator not available since \
+ DMA Pipe(s) are in use",__FUNCTION__);
+ return false;
+ }
+
if(configure(ctx, layer)) {
markFlags(layer);
mModeOn = true;
diff --git a/libqservice/IQService.cpp b/libqservice/IQService.cpp
index 6c6f7b6..53b05e3 100644
--- a/libqservice/IQService.cpp
+++ b/libqservice/IQService.cpp
@@ -133,7 +133,7 @@
} break;
case SCREEN_REFRESH: {
CHECK_INTERFACE(IQService, data, reply);
- if(callerUid != AID_GRAPHICS) {
+ if(callerUid != AID_SYSTEM) {
ALOGE("display.qservice SCREEN_REFRESH access denied: \
pid=%d uid=%d process=%s",callerPid,
callerUid, callingProcName);