hwc: Add DMA pipe support in MDP composition.
This change adds support to MDP composition to use DMA pipes when layer scaling is not needed. Also makes sure not to invoke MDP rotator when DMA pipes are configured since MDP rotator will expect both the DMA pipes to available for performing rotation. In such cases, we let the first frame of rotated video frame to fall back to FB. Change-Id: I3c3697dd2713ce9b86ba1e23192ec5841abd25ec
This commit is contained in:
@@ -200,6 +200,7 @@ static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
|
|||||||
|
|
||||||
ctx->mOverlay->configBegin();
|
ctx->mOverlay->configBegin();
|
||||||
ctx->mRotMgr->configBegin();
|
ctx->mRotMgr->configBegin();
|
||||||
|
ctx->mNeedsRotator = false;
|
||||||
|
|
||||||
for (int32_t i = numDisplays; i >= 0; i--) {
|
for (int32_t i = numDisplays; i >= 0; i--) {
|
||||||
hwc_display_contents_1_t *list = displays[i];
|
hwc_display_contents_1_t *list = displays[i];
|
||||||
|
|||||||
@@ -250,6 +250,7 @@ ovutils::eDest MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type) {
|
|||||||
case MDPCOMP_OV_DMA:
|
case MDPCOMP_OV_DMA:
|
||||||
mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, dpy);
|
mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, dpy);
|
||||||
if(mdp_pipe != ovutils::OV_INVALID) {
|
if(mdp_pipe != ovutils::OV_INVALID) {
|
||||||
|
ctx->mDMAInUse = true;
|
||||||
return mdp_pipe;
|
return mdp_pipe;
|
||||||
}
|
}
|
||||||
case MDPCOMP_OV_ANY:
|
case MDPCOMP_OV_ANY:
|
||||||
@@ -277,10 +278,14 @@ bool MDPComp::isDoable(hwc_context_t *ctx,
|
|||||||
//Number of layers
|
//Number of layers
|
||||||
const int dpy = HWC_DISPLAY_PRIMARY;
|
const int dpy = HWC_DISPLAY_PRIMARY;
|
||||||
int numAppLayers = ctx->listStats[dpy].numAppLayers;
|
int numAppLayers = ctx->listStats[dpy].numAppLayers;
|
||||||
|
int numDMAPipes = qdutils::MDPVersion::getInstance().getDMAPipes();
|
||||||
|
|
||||||
overlay::Overlay& ov = *ctx->mOverlay;
|
overlay::Overlay& ov = *ctx->mOverlay;
|
||||||
int availablePipes = ov.availablePipes(dpy);
|
int availablePipes = ov.availablePipes(dpy);
|
||||||
|
|
||||||
|
if(ctx->mNeedsRotator)
|
||||||
|
availablePipes -= numDMAPipes;
|
||||||
|
|
||||||
if(numAppLayers < 1 || numAppLayers > MAX_PIPES_PER_MIXER ||
|
if(numAppLayers < 1 || numAppLayers > MAX_PIPES_PER_MIXER ||
|
||||||
pipesNeeded(ctx, list) > availablePipes) {
|
pipesNeeded(ctx, list) > availablePipes) {
|
||||||
ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__);
|
ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__);
|
||||||
@@ -320,14 +325,19 @@ bool MDPComp::isDoable(hwc_context_t *ctx,
|
|||||||
return false;
|
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.
|
//MDP composition is not efficient if layer needs rotator.
|
||||||
for(int i = 0; i < numAppLayers; ++i) {
|
for(int i = 0; i < numAppLayers; ++i) {
|
||||||
// As MDP h/w supports flip operation, use MDP comp only for
|
// As MDP h/w supports flip operation, use MDP comp only for
|
||||||
// 180 transforms. Fail for any transform involving 90 (90, 270).
|
// 180 transforms. Fail for any transform involving 90 (90, 270).
|
||||||
hwc_layer_1_t* layer = &list->hwLayers[i];
|
hwc_layer_1_t* layer = &list->hwLayers[i];
|
||||||
private_handle_t *hnd = (private_handle_t *)layer->handle;
|
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__);
|
ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -347,6 +357,7 @@ bool MDPComp::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx->mDMAInUse = false;
|
||||||
if(!allocLayerPipes(ctx, list, mCurrentFrame)) {
|
if(!allocLayerPipes(ctx, list, mCurrentFrame)) {
|
||||||
ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
|
ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
@@ -468,7 +479,14 @@ bool MDPCompLowRes::allocLayerPipes(hwc_context_t *ctx,
|
|||||||
info.rot = NULL;
|
info.rot = NULL;
|
||||||
MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo;
|
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) {
|
if(pipe_info.index == ovutils::OV_INVALID) {
|
||||||
ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
|
ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
@@ -637,7 +655,7 @@ bool MDPCompHighRes::allocLayerPipes(hwc_context_t *ctx,
|
|||||||
|
|
||||||
ePipeType type = MDPCOMP_OV_ANY;
|
ePipeType type = MDPCOMP_OV_ANY;
|
||||||
|
|
||||||
if(!qhwc::needsScaling(layer) && !ctx->mDMAInUse
|
if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator
|
||||||
&& ctx->mMDP.version >= qdutils::MDSS_V5)
|
&& ctx->mMDP.version >= qdutils::MDSS_V5)
|
||||||
type = MDPCOMP_OV_DMA;
|
type = MDPCOMP_OV_DMA;
|
||||||
|
|
||||||
|
|||||||
@@ -88,8 +88,6 @@ protected:
|
|||||||
/* configures MPD pipes */
|
/* configures MPD pipes */
|
||||||
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;
|
||||||
/* Is rotation supported */
|
|
||||||
virtual bool canRotate(){ return true; };
|
|
||||||
|
|
||||||
|
|
||||||
/* set/reset flags for MDPComp */
|
/* set/reset flags for MDPComp */
|
||||||
@@ -173,7 +171,6 @@ private:
|
|||||||
FrameInfo& current_frame);
|
FrameInfo& current_frame);
|
||||||
|
|
||||||
virtual int pipesNeeded(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
virtual int pipesNeeded(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
||||||
virtual bool canRotate(){ return false; };
|
|
||||||
};
|
};
|
||||||
}; //namespace
|
}; //namespace
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -299,7 +299,6 @@ void setListStats(hwc_context_t *ctx,
|
|||||||
ctx->listStats[dpy].skipCount = 0;
|
ctx->listStats[dpy].skipCount = 0;
|
||||||
ctx->listStats[dpy].needsAlphaScale = false;
|
ctx->listStats[dpy].needsAlphaScale = false;
|
||||||
ctx->listStats[dpy].yuvCount = 0;
|
ctx->listStats[dpy].yuvCount = 0;
|
||||||
ctx->mDMAInUse = false;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < list->numHwLayers; i++) {
|
for (size_t i = 0; i < list->numHwLayers; i++) {
|
||||||
hwc_layer_1_t const* layer = &list->hwLayers[i];
|
hwc_layer_1_t const* layer = &list->hwLayers[i];
|
||||||
@@ -318,8 +317,8 @@ void setListStats(hwc_context_t *ctx,
|
|||||||
ctx->listStats[dpy].yuvIndices[yuvCount] = i;
|
ctx->listStats[dpy].yuvIndices[yuvCount] = i;
|
||||||
yuvCount++;
|
yuvCount++;
|
||||||
|
|
||||||
if((layer->transform & HWC_TRANSFORM_ROT_90) && !ctx->mDMAInUse)
|
if(layer->transform & HWC_TRANSFORM_ROT_90)
|
||||||
ctx->mDMAInUse = true;
|
ctx->mNeedsRotator = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ctx->listStats[dpy].needsAlphaScale)
|
if(!ctx->listStats[dpy].needsAlphaScale)
|
||||||
|
|||||||
@@ -296,6 +296,8 @@ struct hwc_context_t {
|
|||||||
struct vsync_state vstate;
|
struct vsync_state vstate;
|
||||||
//DMA used for rotator
|
//DMA used for rotator
|
||||||
bool mDMAInUse;
|
bool mDMAInUse;
|
||||||
|
//MDP rotater needed
|
||||||
|
bool mNeedsRotator;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace qhwc {
|
namespace qhwc {
|
||||||
|
|||||||
@@ -94,6 +94,13 @@ bool VideoOverlayLowRes::prepare(hwc_context_t *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)) {
|
if(configure(ctx, layer)) {
|
||||||
markFlags(layer);
|
markFlags(layer);
|
||||||
mModeOn = true;
|
mModeOn = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user