Merge "hwc: Fix bugs with mixed mode MDP comp"
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
commit
fe2795b9c6
@@ -73,6 +73,8 @@ bool FBUpdateLowRes::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
|
|||||||
//Request an RGB pipe
|
//Request an RGB pipe
|
||||||
ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy);
|
ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy);
|
||||||
if(dest == ovutils::OV_INVALID) { //None available
|
if(dest == ovutils::OV_INVALID) { //None available
|
||||||
|
ALOGE("%s: No pipes available to configure fb for dpy %d",
|
||||||
|
__FUNCTION__, mDpy);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,11 +173,15 @@ bool FBUpdateHighRes::configure(hwc_context_t *ctx,
|
|||||||
//Request left RGB pipe
|
//Request left RGB pipe
|
||||||
ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
|
ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
|
||||||
if(destL == ovutils::OV_INVALID) { //None available
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
//Request right RGB pipe
|
//Request right RGB pipe
|
||||||
ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
|
ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
|
||||||
if(destR == ovutils::OV_INVALID) { //None available
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -160,9 +160,6 @@ void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
|
|||||||
layer->compositionType = HWC_OVERLAY;
|
layer->compositionType = HWC_OVERLAY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mCachedFrame.mdpCount = mCurrentFrame.mdpCount;
|
|
||||||
mCachedFrame.cacheCount = mCurrentFrame.fbCount;
|
|
||||||
mCachedFrame.layerCount = ctx->listStats[mDpy].numAppLayers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -205,13 +202,11 @@ bool MDPComp::setupBasePipe(hwc_context_t *ctx) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
MDPComp::FrameInfo::FrameInfo() {
|
MDPComp::FrameInfo::FrameInfo() {
|
||||||
layerCount = 0;
|
reset(0);
|
||||||
reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MDPComp::FrameInfo::reset() {
|
void MDPComp::FrameInfo::reset(const int& numLayers) {
|
||||||
|
for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
|
||||||
for(int i = 0 ; i < MAX_PIPES_PER_MIXER && layerCount; i++ ) {
|
|
||||||
if(mdpToLayer[i].pipeInfo) {
|
if(mdpToLayer[i].pipeInfo) {
|
||||||
delete mdpToLayer[i].pipeInfo;
|
delete mdpToLayer[i].pipeInfo;
|
||||||
mdpToLayer[i].pipeInfo = NULL;
|
mdpToLayer[i].pipeInfo = NULL;
|
||||||
@@ -222,24 +217,50 @@ void MDPComp::FrameInfo::reset() {
|
|||||||
|
|
||||||
memset(&mdpToLayer, 0, sizeof(mdpToLayer));
|
memset(&mdpToLayer, 0, sizeof(mdpToLayer));
|
||||||
memset(&layerToMDP, -1, sizeof(layerToMDP));
|
memset(&layerToMDP, -1, sizeof(layerToMDP));
|
||||||
memset(&isFBComposed, 0, sizeof(isFBComposed));
|
memset(&isFBComposed, 1, sizeof(isFBComposed));
|
||||||
|
|
||||||
layerCount = 0;
|
layerCount = numLayers;
|
||||||
|
fbCount = numLayers;
|
||||||
mdpCount = 0;
|
mdpCount = 0;
|
||||||
fbCount = 0;
|
|
||||||
needsRedraw = false;
|
needsRedraw = false;
|
||||||
fbZ = 0;
|
fbZ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MDPComp::FrameInfo::map() {
|
||||||
|
// populate layer and MDP maps
|
||||||
|
int mdpIdx = 0;
|
||||||
|
for(int idx = 0; idx < layerCount; idx++) {
|
||||||
|
if(!isFBComposed[idx]) {
|
||||||
|
mdpToLayer[mdpIdx].listIndex = idx;
|
||||||
|
layerToMDP[idx] = mdpIdx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MDPComp::LayerCache::LayerCache() {
|
MDPComp::LayerCache::LayerCache() {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MDPComp::LayerCache::reset() {
|
void MDPComp::LayerCache::reset() {
|
||||||
memset(&hnd, 0, sizeof(buffer_handle_t));
|
memset(&hnd, 0, sizeof(hnd));
|
||||||
mdpCount = 0;
|
mdpCount = 0;
|
||||||
cacheCount = 0;
|
cacheCount = 0;
|
||||||
layerCount = 0;
|
layerCount = 0;
|
||||||
|
fbZ = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
|
||||||
|
const int numAppLayers = list->numHwLayers - 1;
|
||||||
|
for(int i = 0; i < numAppLayers; i++) {
|
||||||
|
hnd[i] = list->hwLayers[i].handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
|
||||||
|
mdpCount = curFrame.mdpCount;
|
||||||
|
cacheCount = curFrame.fbCount;
|
||||||
|
layerCount = curFrame.layerCount;
|
||||||
|
fbZ = curFrame.fbZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MDPComp::isWidthValid(hwc_context_t *ctx, hwc_layer_1_t *layer) {
|
bool MDPComp::isWidthValid(hwc_context_t *ctx, hwc_layer_1_t *layer) {
|
||||||
@@ -315,31 +336,30 @@ ovutils::eDest MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type) {
|
|||||||
|
|
||||||
bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
|
bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
|
||||||
int numAppLayers = ctx->listStats[mDpy].numAppLayers;
|
int numAppLayers = ctx->listStats[mDpy].numAppLayers;
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
if(!isEnabled()) {
|
if(!isEnabled()) {
|
||||||
ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
|
ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
|
||||||
return false;
|
ret = false;
|
||||||
}
|
} else if(ctx->mExtDispConfiguring) {
|
||||||
|
|
||||||
if(ctx->mExtDispConfiguring) {
|
|
||||||
ALOGD_IF( isDebug(),"%s: External Display connection is pending",
|
ALOGD_IF( isDebug(),"%s: External Display connection is pending",
|
||||||
__FUNCTION__);
|
__FUNCTION__);
|
||||||
return false;
|
ret = false;
|
||||||
}
|
} else if(ctx->listStats[mDpy].needsAlphaScale
|
||||||
|
|
||||||
if(ctx->listStats[mDpy].needsAlphaScale
|
|
||||||
&& ctx->mMDP.version < qdutils::MDSS_V5) {
|
&& ctx->mMDP.version < qdutils::MDSS_V5) {
|
||||||
ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
|
ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
|
||||||
return false;
|
ret = false;
|
||||||
}
|
} else if(ctx->isPaddingRound) {
|
||||||
|
|
||||||
if(ctx->isPaddingRound) {
|
|
||||||
ctx->isPaddingRound = false;
|
ctx->isPaddingRound = false;
|
||||||
ALOGD_IF(isDebug(), "%s: padding round",__FUNCTION__);
|
ALOGD_IF(isDebug(), "%s: padding round",__FUNCTION__);
|
||||||
return false;
|
ret = false;
|
||||||
|
} else if(sIdleFallBack) {
|
||||||
|
sIdleFallBack = false;
|
||||||
|
ALOGD_IF(isDebug(), "%s: idle fallback",__FUNCTION__);
|
||||||
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Checks for conditions where all the layers marked for MDP comp cannot be
|
/* Checks for conditions where all the layers marked for MDP comp cannot be
|
||||||
@@ -347,9 +367,7 @@ bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
|
|||||||
bool MDPComp::isFullFrameDoable(hwc_context_t *ctx,
|
bool MDPComp::isFullFrameDoable(hwc_context_t *ctx,
|
||||||
hwc_display_contents_1_t* list){
|
hwc_display_contents_1_t* list){
|
||||||
|
|
||||||
int numAppLayers = ctx->listStats[mDpy].numAppLayers;
|
const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
|
||||||
int mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount;
|
|
||||||
int fbNeeded = int(mCurrentFrame.fbCount != 0);
|
|
||||||
|
|
||||||
if(mDpy > HWC_DISPLAY_PRIMARY){
|
if(mDpy > HWC_DISPLAY_PRIMARY){
|
||||||
ALOGD_IF(isDebug(), "%s: Cannot support External display(s)",
|
ALOGD_IF(isDebug(), "%s: Cannot support External display(s)",
|
||||||
@@ -357,25 +375,10 @@ bool MDPComp::isFullFrameDoable(hwc_context_t *ctx,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mdpCount > (sMaxPipesPerMixer - fbNeeded)) {
|
|
||||||
ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pipesNeeded(ctx, list) > getAvailablePipes(ctx)) {
|
|
||||||
ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes",__FUNCTION__);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isSkipPresent(ctx, mDpy)) {
|
if(isSkipPresent(ctx, mDpy)) {
|
||||||
ALOGD_IF(isDebug(), "%s: Skip layers present",__FUNCTION__);
|
ALOGD_IF(isDebug(),"%s: SKIP present: %d",
|
||||||
return false;
|
__FUNCTION__,
|
||||||
}
|
isSkipPresent(ctx, mDpy));
|
||||||
|
|
||||||
//FB composition on idle timeout
|
|
||||||
if(sIdleFallBack) {
|
|
||||||
sIdleFallBack = false;
|
|
||||||
ALOGD_IF(isDebug(), "%s: idle fallback",__FUNCTION__);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,6 +399,94 @@ bool MDPComp::isFullFrameDoable(hwc_context_t *ctx,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//If all above hard conditions are met we can do full or partial MDP comp.
|
||||||
|
bool ret = false;
|
||||||
|
if(fullMDPComp(ctx, list)) {
|
||||||
|
ret = true;
|
||||||
|
} else if (partialMDPComp(ctx, list)) {
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
||||||
|
//Setup mCurrentFrame
|
||||||
|
mCurrentFrame.mdpCount = mCurrentFrame.layerCount;
|
||||||
|
mCurrentFrame.fbCount = 0;
|
||||||
|
mCurrentFrame.fbZ = -1;
|
||||||
|
memset(&mCurrentFrame.isFBComposed, 0, sizeof(mCurrentFrame.isFBComposed));
|
||||||
|
|
||||||
|
int mdpCount = mCurrentFrame.mdpCount;
|
||||||
|
if(mdpCount > sMaxPipesPerMixer) {
|
||||||
|
ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int numPipesNeeded = pipesNeeded(ctx, list);
|
||||||
|
int availPipes = getAvailablePipes(ctx);
|
||||||
|
|
||||||
|
if(numPipesNeeded > availPipes) {
|
||||||
|
ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes, needed %d, avail %d",
|
||||||
|
__FUNCTION__, numPipesNeeded, availPipes);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
|
||||||
|
{
|
||||||
|
int numAppLayers = ctx->listStats[mDpy].numAppLayers;
|
||||||
|
//Setup mCurrentFrame
|
||||||
|
mCurrentFrame.reset(numAppLayers);
|
||||||
|
updateLayerCache(ctx, list);
|
||||||
|
updateYUV(ctx, list);
|
||||||
|
batchLayers(); //sets up fbZ also
|
||||||
|
|
||||||
|
int mdpCount = mCurrentFrame.mdpCount;
|
||||||
|
if(mdpCount > (sMaxPipesPerMixer - 1)) { // -1 since FB is used
|
||||||
|
ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int numPipesNeeded = pipesNeeded(ctx, list);
|
||||||
|
int availPipes = getAvailablePipes(ctx);
|
||||||
|
|
||||||
|
if(numPipesNeeded > availPipes) {
|
||||||
|
ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes, needed %d, avail %d",
|
||||||
|
__FUNCTION__, numPipesNeeded, availPipes);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MDPComp::isOnlyVideoDoable(hwc_context_t *ctx,
|
||||||
|
hwc_display_contents_1_t* list){
|
||||||
|
int numAppLayers = ctx->listStats[mDpy].numAppLayers;
|
||||||
|
mCurrentFrame.reset(numAppLayers);
|
||||||
|
updateYUV(ctx, list);
|
||||||
|
int mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount;
|
||||||
|
int fbNeeded = int(mCurrentFrame.fbCount != 0);
|
||||||
|
|
||||||
|
if(!isYuvPresent(ctx, mDpy)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mdpCount > (sMaxPipesPerMixer - fbNeeded)) {
|
||||||
|
ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int numPipesNeeded = pipesNeeded(ctx, list);
|
||||||
|
int availPipes = getAvailablePipes(ctx);
|
||||||
|
if(numPipesNeeded > availPipes) {
|
||||||
|
ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes, needed %d, avail %d",
|
||||||
|
__FUNCTION__, numPipesNeeded, availPipes);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,9 +533,14 @@ void MDPComp::batchLayers() {
|
|||||||
int maxBatchCount = 0;
|
int maxBatchCount = 0;
|
||||||
|
|
||||||
/* All or Nothing is cached. No batching needed */
|
/* All or Nothing is cached. No batching needed */
|
||||||
if(!mCurrentFrame.fbCount ||
|
if(!mCurrentFrame.fbCount) {
|
||||||
(mCurrentFrame.fbCount == mCurrentFrame.layerCount))
|
mCurrentFrame.fbZ = -1;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
if(!mCurrentFrame.mdpCount) {
|
||||||
|
mCurrentFrame.fbZ = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Search for max number of contiguous (cached) layers */
|
/* Search for max number of contiguous (cached) layers */
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -456,6 +552,7 @@ void MDPComp::batchLayers() {
|
|||||||
if(count > maxBatchCount) {
|
if(count > maxBatchCount) {
|
||||||
maxBatchCount = count;
|
maxBatchCount = count;
|
||||||
maxBatchStart = i - count;
|
maxBatchStart = i - count;
|
||||||
|
mCurrentFrame.fbZ = maxBatchStart;
|
||||||
}
|
}
|
||||||
if(i < mCurrentFrame.layerCount) i++;
|
if(i < mCurrentFrame.layerCount) i++;
|
||||||
}
|
}
|
||||||
@@ -470,6 +567,8 @@ void MDPComp::batchLayers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mCurrentFrame.fbCount = maxBatchCount;
|
mCurrentFrame.fbCount = maxBatchCount;
|
||||||
|
mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
|
||||||
|
mCurrentFrame.fbCount;
|
||||||
|
|
||||||
ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
|
ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
|
||||||
mCurrentFrame.fbCount);
|
mCurrentFrame.fbCount);
|
||||||
@@ -481,23 +580,19 @@ void MDPComp::updateLayerCache(hwc_context_t* ctx,
|
|||||||
int numAppLayers = ctx->listStats[mDpy].numAppLayers;
|
int numAppLayers = ctx->listStats[mDpy].numAppLayers;
|
||||||
int numCacheableLayers = 0;
|
int numCacheableLayers = 0;
|
||||||
|
|
||||||
if((list->flags & HWC_GEOMETRY_CHANGED) || (isSkipPresent(ctx, mDpy))) {
|
|
||||||
ALOGD_IF(isDebug(),"%s: No Caching: \
|
|
||||||
GEOMETRY change: %d SKIP present: %d", __FUNCTION__,
|
|
||||||
(list->flags & HWC_GEOMETRY_CHANGED),isSkipPresent(ctx, mDpy));
|
|
||||||
mCachedFrame.reset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < numAppLayers; i++) {
|
for(int i = 0; i < numAppLayers; i++) {
|
||||||
if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
|
if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
|
||||||
numCacheableLayers++;
|
numCacheableLayers++;
|
||||||
mCurrentFrame.isFBComposed[i] = true;
|
mCurrentFrame.isFBComposed[i] = true;
|
||||||
} else {
|
} else {
|
||||||
|
mCurrentFrame.isFBComposed[i] = false;
|
||||||
mCachedFrame.hnd[i] = list->hwLayers[i].handle;
|
mCachedFrame.hnd[i] = list->hwLayers[i].handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentFrame.fbCount = numCacheableLayers;
|
mCurrentFrame.fbCount = numCacheableLayers;
|
||||||
|
mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
|
||||||
|
mCurrentFrame.fbCount;
|
||||||
ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, numCacheableLayers);
|
ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, numCacheableLayers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,14 +613,6 @@ int MDPComp::getAvailablePipes(hwc_context_t* ctx) {
|
|||||||
return numAvailable;
|
return numAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MDPComp::resetFrameForFB(hwc_context_t* ctx,
|
|
||||||
hwc_display_contents_1_t* list) {
|
|
||||||
mCurrentFrame.fbCount = mCurrentFrame.layerCount;
|
|
||||||
memset(&mCurrentFrame.isFBComposed, 1,
|
|
||||||
sizeof(mCurrentFrame.isFBComposed));
|
|
||||||
mCurrentFrame.needsRedraw = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
|
void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
|
||||||
|
|
||||||
int nYuvCount = ctx->listStats[mDpy].yuvCount;
|
int nYuvCount = ctx->listStats[mDpy].yuvCount;
|
||||||
@@ -545,22 +632,23 @@ void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
|
||||||
|
mCurrentFrame.fbCount;
|
||||||
ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
|
ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
|
||||||
mCurrentFrame.fbCount);
|
mCurrentFrame.fbCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MDPComp::programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
bool MDPComp::programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
||||||
int fbZOrder = -1;
|
|
||||||
|
|
||||||
if(!allocLayerPipes(ctx, list)) {
|
if(!allocLayerPipes(ctx, list)) {
|
||||||
ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
|
ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
|
||||||
goto fn_exit;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fbBatch = false;
|
||||||
for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
|
for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
|
||||||
index++) {
|
index++) {
|
||||||
if(!mCurrentFrame.isFBComposed[index]) {
|
if(!mCurrentFrame.isFBComposed[index]) {
|
||||||
|
|
||||||
int mdpIndex = mCurrentFrame.layerToMDP[index];
|
int mdpIndex = mCurrentFrame.layerToMDP[index];
|
||||||
hwc_layer_1_t* layer = &list->hwLayers[index];
|
hwc_layer_1_t* layer = &list->hwLayers[index];
|
||||||
|
|
||||||
@@ -570,80 +658,106 @@ int MDPComp::programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
|||||||
if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
|
if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
|
||||||
ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
|
ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
|
||||||
layer %d",__FUNCTION__, index);
|
layer %d",__FUNCTION__, index);
|
||||||
goto fn_exit;
|
return false;
|
||||||
|
}
|
||||||
|
} else if(fbBatch == false) {
|
||||||
|
mdpNextZOrder++;
|
||||||
|
fbBatch = true;
|
||||||
}
|
}
|
||||||
} else if(fbZOrder < 0) {
|
|
||||||
fbZOrder = mdpNextZOrder++;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fbZOrder;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
fn_exit:
|
bool MDPComp::programYUV(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
||||||
//Complete fallback to FB
|
if(!allocLayerPipes(ctx, list)) {
|
||||||
resetFrameForFB(ctx, list);
|
ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
|
||||||
return 0;
|
return false;
|
||||||
|
}
|
||||||
|
//If we are in this block, it means we have yuv + rgb layers both
|
||||||
|
int mdpIdx = 0;
|
||||||
|
for (int index = 0; index < mCurrentFrame.layerCount; index++) {
|
||||||
|
if(!mCurrentFrame.isFBComposed[index]) {
|
||||||
|
hwc_layer_1_t* layer = &list->hwLayers[index];
|
||||||
|
int mdpIndex = mCurrentFrame.layerToMDP[index];
|
||||||
|
MdpPipeInfo* cur_pipe =
|
||||||
|
mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
|
||||||
|
cur_pipe->zOrder = mdpIdx++;
|
||||||
|
|
||||||
|
if(configure(ctx, layer,
|
||||||
|
mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
|
||||||
|
ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
|
||||||
|
layer %d",__FUNCTION__, index);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
||||||
|
|
||||||
//reset old data
|
//reset old data
|
||||||
mCurrentFrame.reset();
|
const int numLayers = ctx->listStats[mDpy].numAppLayers;
|
||||||
|
mCurrentFrame.reset(numLayers);
|
||||||
|
|
||||||
|
//Hard conditions, if not met, cannot do MDP comp
|
||||||
if(!isFrameDoable(ctx)) {
|
if(!isFrameDoable(ctx)) {
|
||||||
ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
|
ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
|
||||||
__FUNCTION__);
|
__FUNCTION__);
|
||||||
|
mCurrentFrame.reset(numLayers);
|
||||||
|
mCachedFrame.cacheAll(list);
|
||||||
|
mCachedFrame.updateCounts(mCurrentFrame);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentFrame.layerCount = ctx->listStats[mDpy].numAppLayers;
|
|
||||||
|
|
||||||
//Iterate layer list for cached layers
|
|
||||||
updateLayerCache(ctx, list);
|
|
||||||
|
|
||||||
//Add YUV layers to cached list
|
|
||||||
updateYUV(ctx, list);
|
|
||||||
|
|
||||||
//Optimze for bypass
|
|
||||||
batchLayers();
|
|
||||||
|
|
||||||
//list is already parsed / batched for optimal mixed mode composition.
|
|
||||||
//Check whether layers marked for MDP Composition is actually doable.
|
//Check whether layers marked for MDP Composition is actually doable.
|
||||||
if(!isFullFrameDoable(ctx, list)){
|
if(isFullFrameDoable(ctx, list)){
|
||||||
|
if(mCurrentFrame.mdpCount) {
|
||||||
|
mCurrentFrame.map();
|
||||||
|
//Acquire and Program MDP pipes
|
||||||
|
if(!programMDP(ctx, list)) {
|
||||||
|
mCurrentFrame.reset(numLayers);
|
||||||
|
mCachedFrame.cacheAll(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(isOnlyVideoDoable(ctx, list)) {
|
||||||
//All layers marked for MDP comp cannot be bypassed.
|
//All layers marked for MDP comp cannot be bypassed.
|
||||||
//Try to compose atleast YUV layers through MDP comp and let
|
//Try to compose atleast YUV layers through MDP comp and let
|
||||||
//all the RGB layers compose in FB
|
//all the RGB layers compose in FB
|
||||||
resetFrameForFB(ctx, list);
|
//Destination over
|
||||||
updateYUV(ctx, list);
|
mCurrentFrame.fbZ = -1;
|
||||||
}
|
if(mCurrentFrame.fbCount)
|
||||||
|
mCurrentFrame.fbZ = ctx->listStats[mDpy].yuvCount;
|
||||||
|
|
||||||
mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
|
mCurrentFrame.map();
|
||||||
mCurrentFrame.fbCount;
|
if(!programYUV(ctx, list)) {
|
||||||
|
mCurrentFrame.reset(numLayers);
|
||||||
if(mCurrentFrame.mdpCount) {
|
mCachedFrame.cacheAll(list);
|
||||||
// populate layer and MDP maps
|
|
||||||
for(int idx = 0, mdpIdx = 0; idx < mCurrentFrame.layerCount; idx++) {
|
|
||||||
if(!mCurrentFrame.isFBComposed[idx]) {
|
|
||||||
mCurrentFrame.mdpToLayer[mdpIdx].listIndex = idx;
|
|
||||||
mCurrentFrame.layerToMDP[idx] = mdpIdx++;
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
//Acquire and Program MDP pipes
|
mCurrentFrame.reset(numLayers);
|
||||||
mCurrentFrame.fbZ = programMDP(ctx, list);
|
mCachedFrame.cacheAll(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Any change in composition types needs an FB refresh*/
|
/* Any change in composition types needs an FB refresh*/
|
||||||
if(mCurrentFrame.fbCount &&
|
if(mCurrentFrame.fbCount &&
|
||||||
((mCurrentFrame.mdpCount != mCachedFrame.mdpCount) ||
|
((mCurrentFrame.mdpCount != mCachedFrame.mdpCount) ||
|
||||||
(mCurrentFrame.fbCount != mCachedFrame.cacheCount) ||
|
(mCurrentFrame.fbCount != mCachedFrame.cacheCount) ||
|
||||||
!mCurrentFrame.mdpCount)) {
|
(mCurrentFrame.fbZ != mCachedFrame.fbZ) ||
|
||||||
|
(!mCurrentFrame.mdpCount) ||
|
||||||
|
(list->flags & HWC_GEOMETRY_CHANGED) ||
|
||||||
|
isSkipPresent(ctx, mDpy) ||
|
||||||
|
(mDpy > HWC_DISPLAY_PRIMARY))) {
|
||||||
mCurrentFrame.needsRedraw = true;
|
mCurrentFrame.needsRedraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//UpdateLayerFlags
|
//UpdateLayerFlags
|
||||||
setMDPCompLayerFlags(ctx, list);
|
setMDPCompLayerFlags(ctx, list);
|
||||||
|
mCachedFrame.updateCounts(mCurrentFrame);
|
||||||
|
|
||||||
if(isDebug()) {
|
if(isDebug()) {
|
||||||
|
ALOGD("GEOMETRY change: %d", (list->flags & HWC_GEOMETRY_CHANGED));
|
||||||
android::String8 sDump("");
|
android::String8 sDump("");
|
||||||
dump(sDump);
|
dump(sDump);
|
||||||
ALOGE("%s",sDump.string());
|
ALOGE("%s",sDump.string());
|
||||||
|
|||||||
@@ -93,7 +93,8 @@ protected:
|
|||||||
/* c'tor */
|
/* c'tor */
|
||||||
FrameInfo();
|
FrameInfo();
|
||||||
/* clear old frame data */
|
/* clear old frame data */
|
||||||
void reset();
|
void reset(const int& numLayers);
|
||||||
|
void map();
|
||||||
};
|
};
|
||||||
|
|
||||||
/* cached data */
|
/* cached data */
|
||||||
@@ -101,12 +102,15 @@ protected:
|
|||||||
int layerCount;
|
int layerCount;
|
||||||
int mdpCount;
|
int mdpCount;
|
||||||
int cacheCount;
|
int cacheCount;
|
||||||
|
int fbZ;
|
||||||
buffer_handle_t hnd[MAX_NUM_LAYERS];
|
buffer_handle_t hnd[MAX_NUM_LAYERS];
|
||||||
|
|
||||||
/* c'tor */
|
/* c'tor */
|
||||||
LayerCache();
|
LayerCache();
|
||||||
/* clear caching info*/
|
/* clear caching info*/
|
||||||
void reset();
|
void reset();
|
||||||
|
void cacheAll(hwc_display_contents_1_t* list);
|
||||||
|
void updateCounts(const FrameInfo&);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* No of pipes needed for Framebuffer */
|
/* No of pipes needed for Framebuffer */
|
||||||
@@ -121,7 +125,6 @@ protected:
|
|||||||
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
||||||
PipeLayerPair& pipeLayerPair) = 0;
|
PipeLayerPair& pipeLayerPair) = 0;
|
||||||
|
|
||||||
|
|
||||||
/* set/reset flags for MDPComp */
|
/* set/reset flags for MDPComp */
|
||||||
void setMDPCompLayerFlags(hwc_context_t *ctx,
|
void setMDPCompLayerFlags(hwc_context_t *ctx,
|
||||||
hwc_display_contents_1_t* list);
|
hwc_display_contents_1_t* list);
|
||||||
@@ -132,6 +135,12 @@ protected:
|
|||||||
bool isFrameDoable(hwc_context_t *ctx);
|
bool isFrameDoable(hwc_context_t *ctx);
|
||||||
/* checks for conditions where RGB layers cannot be bypassed */
|
/* checks for conditions where RGB layers cannot be bypassed */
|
||||||
bool isFullFrameDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
bool isFullFrameDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
||||||
|
/* checks if full MDP comp can be done */
|
||||||
|
bool fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
||||||
|
/* check if we can use layer cache to do at least partial MDP comp */
|
||||||
|
bool partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
||||||
|
/* checks for conditions where only video can be bypassed */
|
||||||
|
bool isOnlyVideoDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
||||||
/* checks for conditions where YUV layers cannot be bypassed */
|
/* checks for conditions where YUV layers cannot be bypassed */
|
||||||
bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
|
bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
|
||||||
|
|
||||||
@@ -145,16 +154,14 @@ protected:
|
|||||||
bool isWidthValid(hwc_context_t *ctx, hwc_layer_1_t *layer);
|
bool isWidthValid(hwc_context_t *ctx, hwc_layer_1_t *layer);
|
||||||
/* tracks non updating layers*/
|
/* tracks non updating layers*/
|
||||||
void updateLayerCache(hwc_context_t* ctx, hwc_display_contents_1_t* list);
|
void updateLayerCache(hwc_context_t* ctx, hwc_display_contents_1_t* list);
|
||||||
/* resets cache for complete fallback */
|
|
||||||
void resetFrameForFB(hwc_context_t* ctx, hwc_display_contents_1_t* list);
|
|
||||||
/* optimize layers for mdp comp*/
|
/* optimize layers for mdp comp*/
|
||||||
void batchLayers();
|
void batchLayers();
|
||||||
/* gets available pipes for mdp comp */
|
/* gets available pipes for mdp comp */
|
||||||
int getAvailablePipes(hwc_context_t* ctx);
|
int getAvailablePipes(hwc_context_t* ctx);
|
||||||
/* updates cache map with YUV info */
|
/* updates cache map with YUV info */
|
||||||
void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list);
|
void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list);
|
||||||
int programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
bool programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
||||||
|
bool programYUV(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
||||||
|
|
||||||
int mDpy;
|
int mDpy;
|
||||||
static bool sEnabled;
|
static bool sEnabled;
|
||||||
|
|||||||
Reference in New Issue
Block a user