overlay: Support for returning pipe based on capability
Add support for returning pipes based on capabilities. getPipe() API takes in pipe specifications like format class, scaling, display, mixer, fb and decides what pipe to return. The nextPipe() API is now just a private helper. Change-Id: I0ab809662c0ad6297e19a44f39264ee929944d13
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
parent
8118d4b5b9
commit
c62f39861a
@@ -182,8 +182,12 @@ bool AssertiveDisplay::prepare(hwc_context_t *ctx,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ovutils::eDest dest = ctx->mOverlay->nextPipe(ovutils::OV_MDP_PIPE_VG,
|
Overlay::PipeSpecs pipeSpecs;
|
||||||
overlay::Overlay::DPY_WRITEBACK, Overlay::MIXER_DEFAULT);
|
pipeSpecs.formatClass = Overlay::FORMAT_YUV;
|
||||||
|
pipeSpecs.dpy = overlay::Overlay::DPY_WRITEBACK;
|
||||||
|
pipeSpecs.fb = false;
|
||||||
|
|
||||||
|
ovutils::eDest dest = ctx->mOverlay->getPipe(pipeSpecs);
|
||||||
if(dest == OV_INVALID) {
|
if(dest == OV_INVALID) {
|
||||||
ALOGE("%s failed: No VG pipe available", __func__);
|
ALOGE("%s failed: No VG pipe available", __func__);
|
||||||
mDoable = false;
|
mDoable = false;
|
||||||
|
|||||||
@@ -139,14 +139,14 @@ bool FBUpdateNonSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *lis
|
|||||||
ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
|
ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
|
||||||
mTileEnabled));
|
mTileEnabled));
|
||||||
|
|
||||||
//Request a pipe
|
Overlay::PipeSpecs pipeSpecs;
|
||||||
ovutils::eMdpPipeType type = ovutils::OV_MDP_PIPE_ANY;
|
pipeSpecs.formatClass = Overlay::FORMAT_RGB;
|
||||||
if((qdutils::MDPVersion::getInstance().is8x26() ||
|
pipeSpecs.needsScaling = qhwc::needsScaling(layer);
|
||||||
qdutils::MDPVersion::getInstance().is8x16()) && mDpy) {
|
pipeSpecs.dpy = mDpy;
|
||||||
//For 8x26 external always use DMA pipe
|
pipeSpecs.mixer = Overlay::MIXER_DEFAULT;
|
||||||
type = ovutils::OV_MDP_PIPE_DMA;
|
pipeSpecs.fb = true;
|
||||||
}
|
|
||||||
ovutils::eDest dest = ov.nextPipe(type, mDpy, Overlay::MIXER_DEFAULT);
|
ovutils::eDest dest = ov.getPipe(pipeSpecs);
|
||||||
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",
|
ALOGE("%s: No pipes available to configure fb for dpy %d",
|
||||||
__FUNCTION__, mDpy);
|
__FUNCTION__, mDpy);
|
||||||
@@ -308,10 +308,16 @@ bool FBUpdateSplit::configure(hwc_context_t *ctx,
|
|||||||
hwc_rect_t displayFrame = fbUpdatingRect;
|
hwc_rect_t displayFrame = fbUpdatingRect;
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
|
Overlay::PipeSpecs pipeSpecs;
|
||||||
|
pipeSpecs.formatClass = Overlay::FORMAT_RGB;
|
||||||
|
pipeSpecs.needsScaling = qhwc::needsScaling(layer);
|
||||||
|
pipeSpecs.dpy = mDpy;
|
||||||
|
pipeSpecs.fb = true;
|
||||||
|
|
||||||
/* Configure left pipe */
|
/* Configure left pipe */
|
||||||
if(displayFrame.left < lSplit) {
|
if(displayFrame.left < lSplit) {
|
||||||
ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
|
pipeSpecs.mixer = Overlay::MIXER_LEFT;
|
||||||
Overlay::MIXER_LEFT);
|
ovutils::eDest destL = ov.getPipe(pipeSpecs);
|
||||||
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"
|
ALOGE("%s: No pipes available to configure fb for dpy %d's left"
|
||||||
" mixer", __FUNCTION__, mDpy);
|
" mixer", __FUNCTION__, mDpy);
|
||||||
@@ -344,8 +350,8 @@ bool FBUpdateSplit::configure(hwc_context_t *ctx,
|
|||||||
|
|
||||||
/* Configure right pipe */
|
/* Configure right pipe */
|
||||||
if(displayFrame.right > lSplit) {
|
if(displayFrame.right > lSplit) {
|
||||||
ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
|
pipeSpecs.mixer = Overlay::MIXER_RIGHT;
|
||||||
Overlay::MIXER_RIGHT);
|
ovutils::eDest destR = ov.getPipe(pipeSpecs);
|
||||||
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"
|
ALOGE("%s: No pipes available to configure fb for dpy %d's"
|
||||||
" right mixer", __FUNCTION__, mDpy);
|
" right mixer", __FUNCTION__, mDpy);
|
||||||
@@ -455,8 +461,13 @@ bool FBSrcSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
|
|||||||
hwc_rect_t cropR = fbUpdatingRect;
|
hwc_rect_t cropR = fbUpdatingRect;
|
||||||
|
|
||||||
//Request left pipe (or 1 by default)
|
//Request left pipe (or 1 by default)
|
||||||
ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
|
Overlay::PipeSpecs pipeSpecs;
|
||||||
Overlay::MIXER_DEFAULT);
|
pipeSpecs.formatClass = Overlay::FORMAT_RGB;
|
||||||
|
pipeSpecs.needsScaling = qhwc::needsScaling(layer);
|
||||||
|
pipeSpecs.dpy = mDpy;
|
||||||
|
pipeSpecs.mixer = Overlay::MIXER_DEFAULT;
|
||||||
|
pipeSpecs.fb = true;
|
||||||
|
ovutils::eDest destL = ov.getPipe(pipeSpecs);
|
||||||
if(destL == ovutils::OV_INVALID) {
|
if(destL == ovutils::OV_INVALID) {
|
||||||
ALOGE("%s: No pipes available to configure fb for dpy %d's left"
|
ALOGE("%s: No pipes available to configure fb for dpy %d's left"
|
||||||
" mixer", __FUNCTION__, mDpy);
|
" mixer", __FUNCTION__, mDpy);
|
||||||
@@ -468,8 +479,7 @@ bool FBSrcSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
|
|||||||
//Request right pipe (2 pipes needed only if dim > 2048)
|
//Request right pipe (2 pipes needed only if dim > 2048)
|
||||||
if((fbUpdatingRect.right - fbUpdatingRect.left) >
|
if((fbUpdatingRect.right - fbUpdatingRect.left) >
|
||||||
qdutils::MAX_DISPLAY_DIM) {
|
qdutils::MAX_DISPLAY_DIM) {
|
||||||
destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
|
destR = ov.getPipe(pipeSpecs);
|
||||||
Overlay::MIXER_DEFAULT);
|
|
||||||
if(destR == ovutils::OV_INVALID) {
|
if(destR == ovutils::OV_INVALID) {
|
||||||
ALOGE("%s: No pipes available to configure fb for dpy %d's right"
|
ALOGE("%s: No pipes available to configure fb for dpy %d's right"
|
||||||
" mixer", __FUNCTION__, mDpy);
|
" mixer", __FUNCTION__, mDpy);
|
||||||
|
|||||||
@@ -393,37 +393,6 @@ bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ovutils::eDest MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type,
|
|
||||||
int mixer) {
|
|
||||||
overlay::Overlay& ov = *ctx->mOverlay;
|
|
||||||
ovutils::eDest mdp_pipe = ovutils::OV_INVALID;
|
|
||||||
|
|
||||||
switch(type) {
|
|
||||||
case MDPCOMP_OV_DMA:
|
|
||||||
mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, mDpy, mixer);
|
|
||||||
if(mdp_pipe != ovutils::OV_INVALID) {
|
|
||||||
return mdp_pipe;
|
|
||||||
}
|
|
||||||
case MDPCOMP_OV_ANY:
|
|
||||||
case MDPCOMP_OV_RGB:
|
|
||||||
mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy, mixer);
|
|
||||||
if(mdp_pipe != ovutils::OV_INVALID) {
|
|
||||||
return mdp_pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(type == MDPCOMP_OV_RGB) {
|
|
||||||
//Requested only for RGB pipe
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MDPCOMP_OV_VG:
|
|
||||||
return ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy, mixer);
|
|
||||||
default:
|
|
||||||
ALOGE("%s: Invalid pipe type",__FUNCTION__);
|
|
||||||
return ovutils::OV_INVALID;
|
|
||||||
};
|
|
||||||
return ovutils::OV_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
|
bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
@@ -1342,18 +1311,23 @@ bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
|
|||||||
info.pipeInfo = new MdpYUVPipeInfo;
|
info.pipeInfo = new MdpYUVPipeInfo;
|
||||||
info.rot = NULL;
|
info.rot = NULL;
|
||||||
MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
|
MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
|
||||||
ePipeType type = MDPCOMP_OV_VG;
|
|
||||||
|
|
||||||
pipe_info.lIndex = ovutils::OV_INVALID;
|
pipe_info.lIndex = ovutils::OV_INVALID;
|
||||||
pipe_info.rIndex = ovutils::OV_INVALID;
|
pipe_info.rIndex = ovutils::OV_INVALID;
|
||||||
|
|
||||||
pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
|
Overlay::PipeSpecs pipeSpecs;
|
||||||
|
pipeSpecs.formatClass = Overlay::FORMAT_YUV;
|
||||||
|
pipeSpecs.needsScaling = true;
|
||||||
|
pipeSpecs.dpy = mDpy;
|
||||||
|
pipeSpecs.fb = false;
|
||||||
|
|
||||||
|
pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
|
||||||
if(pipe_info.lIndex == ovutils::OV_INVALID){
|
if(pipe_info.lIndex == ovutils::OV_INVALID){
|
||||||
bRet = false;
|
bRet = false;
|
||||||
ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
|
ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
|
||||||
__FUNCTION__);
|
__FUNCTION__);
|
||||||
}
|
}
|
||||||
pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
|
pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
|
||||||
if(pipe_info.rIndex == ovutils::OV_INVALID){
|
if(pipe_info.rIndex == ovutils::OV_INVALID){
|
||||||
bRet = false;
|
bRet = false;
|
||||||
ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
|
ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
|
||||||
@@ -1423,28 +1397,20 @@ bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
|
|||||||
info.pipeInfo = new MdpPipeInfoNonSplit;
|
info.pipeInfo = new MdpPipeInfoNonSplit;
|
||||||
info.rot = NULL;
|
info.rot = NULL;
|
||||||
MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
|
MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
|
||||||
ePipeType type = MDPCOMP_OV_ANY;
|
|
||||||
|
|
||||||
if(isYuvBuffer(hnd)) {
|
Overlay::PipeSpecs pipeSpecs;
|
||||||
type = MDPCOMP_OV_VG;
|
pipeSpecs.formatClass = isYuvBuffer(hnd) ?
|
||||||
} else if(qdutils::MDPVersion::getInstance().is8x26() &&
|
Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
|
||||||
(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024)) {
|
pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
|
||||||
if(qhwc::needsScaling(layer))
|
(qdutils::MDPVersion::getInstance().is8x26() and
|
||||||
type = MDPCOMP_OV_RGB;
|
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
|
||||||
} else if(!qhwc::needsScaling(layer)
|
pipeSpecs.dpy = mDpy;
|
||||||
&& Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
|
pipeSpecs.fb = false;
|
||||||
&& ctx->mMDP.version >= qdutils::MDSS_V5) {
|
|
||||||
type = MDPCOMP_OV_DMA;
|
pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
|
||||||
} else if(qhwc::needsScaling(layer) &&
|
|
||||||
!(ctx->listStats[mDpy].yuvCount) &&
|
|
||||||
! qdutils::MDPVersion::getInstance().isRGBScalarSupported()){
|
|
||||||
type = MDPCOMP_OV_VG;
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe_info.index = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
|
|
||||||
if(pipe_info.index == ovutils::OV_INVALID) {
|
if(pipe_info.index == ovutils::OV_INVALID) {
|
||||||
ALOGD_IF(isDebug(), "%s: Unable to get pipe type = %d",
|
ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
|
||||||
__FUNCTION__, (int) type);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1607,22 +1573,31 @@ void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
|
bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
|
||||||
MdpPipeInfoSplit& pipe_info,
|
MdpPipeInfoSplit& pipe_info) {
|
||||||
ePipeType type) {
|
|
||||||
const int lSplit = getLeftSplit(ctx, mDpy);
|
|
||||||
|
|
||||||
|
const int lSplit = getLeftSplit(ctx, mDpy);
|
||||||
|
private_handle_t *hnd = (private_handle_t *)layer->handle;
|
||||||
hwc_rect_t dst = layer->displayFrame;
|
hwc_rect_t dst = layer->displayFrame;
|
||||||
pipe_info.lIndex = ovutils::OV_INVALID;
|
pipe_info.lIndex = ovutils::OV_INVALID;
|
||||||
pipe_info.rIndex = ovutils::OV_INVALID;
|
pipe_info.rIndex = ovutils::OV_INVALID;
|
||||||
|
|
||||||
|
Overlay::PipeSpecs pipeSpecs;
|
||||||
|
pipeSpecs.formatClass = isYuvBuffer(hnd) ?
|
||||||
|
Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
|
||||||
|
pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
|
||||||
|
pipeSpecs.dpy = mDpy;
|
||||||
|
pipeSpecs.mixer = Overlay::MIXER_LEFT;
|
||||||
|
pipeSpecs.fb = false;
|
||||||
|
|
||||||
if (dst.left < lSplit) {
|
if (dst.left < lSplit) {
|
||||||
pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_LEFT);
|
pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
|
||||||
if(pipe_info.lIndex == ovutils::OV_INVALID)
|
if(pipe_info.lIndex == ovutils::OV_INVALID)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dst.right > lSplit) {
|
if(dst.right > lSplit) {
|
||||||
pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_RIGHT);
|
pipeSpecs.mixer = Overlay::MIXER_RIGHT;
|
||||||
|
pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
|
||||||
if(pipe_info.rIndex == ovutils::OV_INVALID)
|
if(pipe_info.rIndex == ovutils::OV_INVALID)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1652,19 +1627,10 @@ bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
|
|||||||
info.pipeInfo = new MdpPipeInfoSplit;
|
info.pipeInfo = new MdpPipeInfoSplit;
|
||||||
info.rot = NULL;
|
info.rot = NULL;
|
||||||
MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
|
MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
|
||||||
ePipeType type = MDPCOMP_OV_ANY;
|
|
||||||
|
|
||||||
if(isYuvBuffer(hnd)) {
|
if(!acquireMDPPipes(ctx, layer, pipe_info)) {
|
||||||
type = MDPCOMP_OV_VG;
|
ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
|
||||||
} else if(!qhwc::needsScalingWithSplit(ctx, layer, mDpy)
|
__FUNCTION__);
|
||||||
&& Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
|
|
||||||
&& ctx->mMDP.version >= qdutils::MDSS_V5) {
|
|
||||||
type = MDPCOMP_OV_DMA;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!acquireMDPPipes(ctx, layer, pipe_info, type)) {
|
|
||||||
ALOGD_IF(isDebug(), "%s: Unable to get pipe for type = %d",
|
|
||||||
__FUNCTION__, (int) type);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1848,7 +1814,7 @@ bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
|||||||
|
|
||||||
//================MDPCompSrcSplit==============================================
|
//================MDPCompSrcSplit==============================================
|
||||||
bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
|
bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
|
||||||
MdpPipeInfoSplit& pipe_info, ePipeType type) {
|
MdpPipeInfoSplit& pipe_info) {
|
||||||
private_handle_t *hnd = (private_handle_t *)layer->handle;
|
private_handle_t *hnd = (private_handle_t *)layer->handle;
|
||||||
hwc_rect_t dst = layer->displayFrame;
|
hwc_rect_t dst = layer->displayFrame;
|
||||||
hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
|
hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
|
||||||
@@ -1859,32 +1825,25 @@ bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
|
|||||||
//should have a higher priority than the right one. Pipe priorities are
|
//should have a higher priority than the right one. Pipe priorities are
|
||||||
//starting with VG0, VG1 ... , RGB0 ..., DMA1
|
//starting with VG0, VG1 ... , RGB0 ..., DMA1
|
||||||
|
|
||||||
|
Overlay::PipeSpecs pipeSpecs;
|
||||||
|
pipeSpecs.formatClass = isYuvBuffer(hnd) ?
|
||||||
|
Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
|
||||||
|
pipeSpecs.needsScaling = qhwc::needsScaling(layer);
|
||||||
|
pipeSpecs.dpy = mDpy;
|
||||||
|
pipeSpecs.fb = false;
|
||||||
|
|
||||||
//1 pipe by default for a layer
|
//1 pipe by default for a layer
|
||||||
pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
|
pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
|
||||||
if(pipe_info.lIndex == ovutils::OV_INVALID) {
|
if(pipe_info.lIndex == ovutils::OV_INVALID) {
|
||||||
if(isYuvBuffer(hnd)) {
|
return false;
|
||||||
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 layer's crop width or dest width > 2048, use 2 pipes
|
||||||
if((dst.right - dst.left) > qdutils::MAX_DISPLAY_DIM or
|
if((dst.right - dst.left) > qdutils::MAX_DISPLAY_DIM or
|
||||||
(crop.right - crop.left) > qdutils::MAX_DISPLAY_DIM) {
|
(crop.right - crop.left) > qdutils::MAX_DISPLAY_DIM) {
|
||||||
pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
|
pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
|
||||||
if(pipe_info.rIndex == ovutils::OV_INVALID) {
|
if(pipe_info.rIndex == ovutils::OV_INVALID) {
|
||||||
if(isYuvBuffer(hnd)) {
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
pipe_info.rIndex = getMdpPipe(ctx, MDPCOMP_OV_ANY,
|
|
||||||
Overlay::MIXER_DEFAULT);
|
|
||||||
if(pipe_info.rIndex == ovutils::OV_INVALID) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return values
|
// Return values
|
||||||
|
|||||||
@@ -132,8 +132,6 @@ protected:
|
|||||||
/* allocates pipe from pipe book */
|
/* allocates pipe from pipe book */
|
||||||
virtual bool allocLayerPipes(hwc_context_t *ctx,
|
virtual bool allocLayerPipes(hwc_context_t *ctx,
|
||||||
hwc_display_contents_1_t* list) = 0;
|
hwc_display_contents_1_t* list) = 0;
|
||||||
/* allocate MDP pipes from overlay */
|
|
||||||
ovutils::eDest getMdpPipe(hwc_context_t *ctx, ePipeType type, int mixer);
|
|
||||||
/* 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;
|
||||||
@@ -279,7 +277,7 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
virtual 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);
|
MdpPipeInfoSplit& pipe_info);
|
||||||
|
|
||||||
/* configure's overlay pipes for the frame */
|
/* configure's overlay pipes for the frame */
|
||||||
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
||||||
@@ -306,7 +304,7 @@ public:
|
|||||||
virtual ~MDPCompSrcSplit(){};
|
virtual ~MDPCompSrcSplit(){};
|
||||||
private:
|
private:
|
||||||
virtual 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);
|
MdpPipeInfoSplit& pipe_info);
|
||||||
|
|
||||||
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);
|
PipeLayerPair& pipeLayerPair);
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ using namespace scale;
|
|||||||
|
|
||||||
namespace overlay {
|
namespace overlay {
|
||||||
using namespace utils;
|
using namespace utils;
|
||||||
|
using namespace qdutils;
|
||||||
|
|
||||||
Overlay::Overlay() {
|
Overlay::Overlay() {
|
||||||
int numPipes = qdutils::MDPVersion::getInstance().getTotalPipes();
|
int numPipes = qdutils::MDPVersion::getInstance().getTotalPipes();
|
||||||
@@ -158,6 +158,103 @@ eDest Overlay::nextPipe(eMdpPipeType type, int dpy, int mixer) {
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
utils::eDest Overlay::getPipe(const PipeSpecs& pipeSpecs) {
|
||||||
|
if(MDPVersion::getInstance().is8x26()) {
|
||||||
|
return getPipe_8x26(pipeSpecs);
|
||||||
|
} else if(MDPVersion::getInstance().is8x16()) {
|
||||||
|
return getPipe_8x16(pipeSpecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
eDest dest = OV_INVALID;
|
||||||
|
|
||||||
|
//The default behavior is to assume RGB and VG pipes have scalars
|
||||||
|
if(pipeSpecs.formatClass == FORMAT_YUV) {
|
||||||
|
return nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
} else if(pipeSpecs.fb == false) { //RGB App layers
|
||||||
|
if(not pipeSpecs.needsScaling) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
}
|
||||||
|
if(dest == OV_INVALID) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
}
|
||||||
|
if(dest == OV_INVALID) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
}
|
||||||
|
} else { //FB layer
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
if(dest == OV_INVALID) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
}
|
||||||
|
//Some features can cause FB to have scaling as well.
|
||||||
|
//If we ever come to this block with FB needing scaling,
|
||||||
|
//the screen will be black for a frame, since the FB won't get a pipe
|
||||||
|
//but atleast this will prevent a hang
|
||||||
|
if(dest == OV_INVALID and (not pipeSpecs.needsScaling)) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::eDest Overlay::getPipe_8x26(const PipeSpecs& pipeSpecs) {
|
||||||
|
//Use this to hide all the 8x26 requirements that cannot be humanly
|
||||||
|
//described in a generic way
|
||||||
|
eDest dest = OV_INVALID;
|
||||||
|
if(pipeSpecs.formatClass == FORMAT_YUV) { //video
|
||||||
|
return nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
} else if(pipeSpecs.fb == false) { //RGB app layers
|
||||||
|
if(not pipeSpecs.needsScaling) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
}
|
||||||
|
if(dest == OV_INVALID) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
}
|
||||||
|
if(dest == OV_INVALID) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
}
|
||||||
|
} else { //FB layer
|
||||||
|
//For 8x26 Secondary we use DMA always for FB for inline rotation
|
||||||
|
if(pipeSpecs.dpy == DPY_PRIMARY) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
if(dest == OV_INVALID) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(dest == OV_INVALID and (not pipeSpecs.needsScaling)) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::eDest Overlay::getPipe_8x16(const PipeSpecs& pipeSpecs) {
|
||||||
|
//Having such functions help keeping the interface generic but code specific
|
||||||
|
//and rife with assumptions
|
||||||
|
eDest dest = OV_INVALID;
|
||||||
|
if(pipeSpecs.formatClass == FORMAT_YUV or pipeSpecs.needsScaling) {
|
||||||
|
return nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
} else if(pipeSpecs.fb == false) { //RGB app layers
|
||||||
|
//Since this is a specific func, we can assume stuff like RGB pipe not
|
||||||
|
//having scalar blocks
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
if(dest == OV_INVALID) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//For 8x16 Secondary we use DMA always for FB for inline rotation
|
||||||
|
if(pipeSpecs.dpy == DPY_PRIMARY) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
if(dest == OV_INVALID) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(dest == OV_INVALID) {
|
||||||
|
dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
void Overlay::endAllSessions() {
|
void Overlay::endAllSessions() {
|
||||||
for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
|
for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
|
||||||
if(mPipeBook[i].valid() && mPipeBook[i].mSession==PipeBook::START)
|
if(mPipeBook[i].valid() && mPipeBook[i].mSession==PipeBook::START)
|
||||||
|
|||||||
@@ -53,6 +53,17 @@ public:
|
|||||||
enum { MIXER_LEFT, MIXER_RIGHT, MIXER_UNUSED };
|
enum { MIXER_LEFT, MIXER_RIGHT, MIXER_UNUSED };
|
||||||
enum { MIXER_DEFAULT = MIXER_LEFT, MIXER_MAX = MIXER_UNUSED };
|
enum { MIXER_DEFAULT = MIXER_LEFT, MIXER_MAX = MIXER_UNUSED };
|
||||||
enum { MAX_FB_DEVICES = DPY_MAX };
|
enum { MAX_FB_DEVICES = DPY_MAX };
|
||||||
|
enum { FORMAT_YUV, FORMAT_RGB };
|
||||||
|
|
||||||
|
struct PipeSpecs {
|
||||||
|
PipeSpecs() : formatClass(FORMAT_RGB), needsScaling(false), fb(false),
|
||||||
|
dpy(DPY_PRIMARY), mixer(MIXER_DEFAULT) {}
|
||||||
|
int formatClass;
|
||||||
|
bool needsScaling;
|
||||||
|
bool fb;
|
||||||
|
int dpy;
|
||||||
|
int mixer;
|
||||||
|
};
|
||||||
|
|
||||||
/* dtor close */
|
/* dtor close */
|
||||||
~Overlay();
|
~Overlay();
|
||||||
@@ -69,14 +80,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
void configDone();
|
void configDone();
|
||||||
|
|
||||||
/* Returns an available pipe based on the type of pipe requested. When ANY
|
/* Get a pipe that supported the specified format class (yuv, rgb) and has
|
||||||
* is requested, the first available VG or RGB is returned. If no pipe is
|
* scaling capabilities.
|
||||||
* available for the display "dpy" then INV is returned. Note: If a pipe is
|
*/
|
||||||
* assigned to a certain display, then it cannot be assigned to another
|
utils::eDest getPipe(const PipeSpecs& pipeSpecs);
|
||||||
* display without being garbage-collected once. To add if a pipe is
|
|
||||||
* asisgned to a mixer within a display it cannot be reused for another
|
|
||||||
* mixer without being UNSET once*/
|
|
||||||
utils::eDest nextPipe(utils::eMdpPipeType, int dpy, int mixer);
|
|
||||||
/* Returns the eDest corresponding to an already allocated pipeid.
|
/* Returns the eDest corresponding to an already allocated pipeid.
|
||||||
* Useful for the reservation case, when libvpu reserves the pipe at its
|
* Useful for the reservation case, when libvpu reserves the pipe at its
|
||||||
* end, and expect the overlay to allocate a given pipe for a layer.
|
* end, and expect the overlay to allocate a given pipe for a layer.
|
||||||
@@ -147,6 +154,18 @@ private:
|
|||||||
void validate(int index);
|
void validate(int index);
|
||||||
static void setDMAMultiplexingSupported();
|
static void setDMAMultiplexingSupported();
|
||||||
void dump() const;
|
void dump() const;
|
||||||
|
/* Returns an available pipe based on the type of pipe requested. When ANY
|
||||||
|
* is requested, the first available VG or RGB is returned. If no pipe is
|
||||||
|
* available for the display "dpy" then INV is returned. Note: If a pipe is
|
||||||
|
* assigned to a certain display, then it cannot be assigned to another
|
||||||
|
* display without being garbage-collected once. To add if a pipe is
|
||||||
|
* asisgned to a mixer within a display it cannot be reused for another
|
||||||
|
* mixer without being UNSET once*/
|
||||||
|
utils::eDest nextPipe(utils::eMdpPipeType, int dpy, int mixer);
|
||||||
|
/* Helpers that enfore target specific policies while returning pipes */
|
||||||
|
utils::eDest getPipe_8x26(const PipeSpecs& pipeSpecs);
|
||||||
|
utils::eDest getPipe_8x16(const PipeSpecs& pipeSpecs);
|
||||||
|
|
||||||
/* Returns the scalar object */
|
/* Returns the scalar object */
|
||||||
static scale::Scale *getScalar();
|
static scale::Scale *getScalar();
|
||||||
/* Creates a scalar object using libscale.so */
|
/* Creates a scalar object using libscale.so */
|
||||||
|
|||||||
Reference in New Issue
Block a user