hwc/overlay: Add support for pipe priorities, 1 pipe config for FB
If using source split to stage 2 pipes on the same mixer stage,
the left pipe needs to be a higher priority than the right.
Add API in overlay to compare pipe priorities and use this in
source split config to stage pipes accordingly.
Add support for 1 pipe config for FB if updating rect is within 2048
pixels.
Change-Id: I8b33d5ebd0f8765ee842bab128d8abd67a110145
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index b51b2ea..2dd256e 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -426,35 +426,13 @@
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);
@@ -467,46 +445,68 @@
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;
+ hwc_rect_t cropL = fbUpdatingRect;
+ hwc_rect_t cropR = fbUpdatingRect;
+
+ //Request left pipe (or 1 by default)
+ ovutils::eDest 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;
}
- if (!ov.commit(destR)) {
- ALOGE("%s: commit fails for right", __FUNCTION__);
- ret = false;
+
+ ovutils::eDest destR = ovutils::OV_INVALID;
+
+ //Request right pipe (2 pipes needed only if dim > 2048)
+ if((fbUpdatingRect.right - fbUpdatingRect.left) >
+ qdutils::MAX_DISPLAY_DIM) {
+ 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;
+ }
+
+ if(ctx->mOverlay->comparePipePriority(destL, destR) == -1) {
+ qhwc::swap(destL, destR);
+ }
+
+ //Split crop equally when using 2 pipes
+ cropL.right = (fbUpdatingRect.right + fbUpdatingRect.left) / 2;
+ cropR.left = cropL.right;
}
- if(ret == false) {
- ctx->mLayerRotMap[mDpy]->clear();
+
+ mDestLeft = destL;
+ mDestRight = destR;
+
+ if(destL != OV_INVALID) {
+ if(configMdp(ctx->mOverlay, parg, orient,
+ cropL, cropL, NULL /*metadata*/, destL) < 0) {
+ ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
+ ctx->mLayerRotMap[mDpy]->clear();
+ return false;
+ }
}
- return ret;
+
+ //configure right pipe
+ if(destR != OV_INVALID) {
+ if(configMdp(ctx->mOverlay, parg, orient,
+ cropR, cropR, NULL /*metadata*/, destR) < 0) {
+ ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
+ ctx->mLayerRotMap[mDpy]->clear();
+ return false;
+ }
+ }
+
+ return true;
}
//---------------------------------------------------------------------
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index ab175cb..54530e2 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -1848,7 +1848,7 @@
//================MDPCompSrcSplit==============================================
bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
- MdpPipeInfoSplit& pipe_info, ePipeType /*type*/) {
+ 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);
@@ -1858,13 +1858,9 @@
//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);
+ pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
if(pipe_info.lIndex == ovutils::OV_INVALID) {
if(isYuvBuffer(hnd)) {
return false;
@@ -1879,38 +1875,31 @@
//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);
+ pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
if(pipe_info.rIndex == ovutils::OV_INVALID) {
- return false;
+ if(isYuvBuffer(hnd)) {
+ return false;
+ }
+ pipe_info.rIndex = getMdpPipe(ctx, MDPCOMP_OV_ANY,
+ Overlay::MIXER_DEFAULT);
+ if(pipe_info.rIndex == ovutils::OV_INVALID) {
+ return false;
+ }
+ }
+
+ // Return values
+ // 1 Left pipe is higher priority, do nothing.
+ // 0 Pipes of same priority.
+ //-1 Right pipe is of higher priority, needs swap.
+ if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
+ pipe_info.rIndex) == -1) {
+ qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
}
}
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;
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index b6615ad..470ce12 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -308,9 +308,6 @@
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);
};
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 265aa9f..7e7f275 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -175,6 +175,19 @@
return false;
}
+int Overlay::comparePipePriority(utils::eDest pipe1Index,
+ utils::eDest pipe2Index) {
+ validate((int)pipe1Index);
+ validate((int)pipe2Index);
+ uint8_t pipe1Prio = mPipeBook[(int)pipe1Index].mPipe->getPriority();
+ uint8_t pipe2Prio = mPipeBook[(int)pipe2Index].mPipe->getPriority();
+ if(pipe1Prio > pipe2Prio)
+ return 1;
+ if(pipe1Prio < pipe2Prio)
+ return -1;
+ return 0;
+}
+
bool Overlay::commit(utils::eDest dest) {
bool ret = false;
int index = (int)dest;
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index d8615cd..44193be 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -114,6 +114,12 @@
* displays
*/
bool isPipeTypeAttached(utils::eMdpPipeType type);
+ /* Compare pipe priorities and return
+ * 1 if 1st pipe has a higher priority
+ * 0 if both have the same priority
+ *-1 if 2nd pipe has a higher priority
+ */
+ int comparePipePriority(utils::eDest pipe1Index, utils::eDest pipe2Index);
/* Returns pipe dump. Expects a NULL terminated buffer of big enough size
* to populate.
*/
diff --git a/liboverlay/overlayCtrlData.h b/liboverlay/overlayCtrlData.h
index 26202ec..51209a7 100644
--- a/liboverlay/overlayCtrlData.h
+++ b/liboverlay/overlayCtrlData.h
@@ -79,6 +79,8 @@
void setDownscale(int dscale_factor);
/* Update the src format based on rotator's dest */
void updateSrcFormat(const uint32_t& rotDstFormat);
+ /* return pipe priority */
+ uint8_t getPriority() const;
/* dump the state of the object */
void dump() const;
/* Return the dump in the specified buffer */
@@ -208,6 +210,10 @@
mMdp->setDownscale(dscale_factor);
}
+inline uint8_t Ctrl::getPriority() const {
+ return mMdp->getPriority();
+}
+
inline void Ctrl::getDump(char *buf, size_t len) {
mMdp->getDump(buf, len);
}
diff --git a/liboverlay/overlayMdp.h b/liboverlay/overlayMdp.h
index 843556b..d312c2e 100644
--- a/liboverlay/overlayMdp.h
+++ b/liboverlay/overlayMdp.h
@@ -80,6 +80,8 @@
utils::Dim getDstRectDim() const;
/* returns a copy to src rect dim */
utils::Dim getSrcRectDim() const;
+ /* return pipe priority */
+ uint8_t getPriority() const;
/* setVisualParam */
bool setVisualParams(const MetaData_t& data);
@@ -304,6 +306,10 @@
mOVInfo.flags |= MDP_SOURCE_ROTATED_90;
}
+inline uint8_t MdpCtrl::getPriority() const {
+ return mOVInfo.priority;
+}
+
/////// MdpCtrl3D //////
inline MdpCtrl3D::MdpCtrl3D() { reset(); }
diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp
index 9e57223..303cd34 100644
--- a/liboverlay/pipes/overlayGenPipe.cpp
+++ b/liboverlay/pipes/overlayGenPipe.cpp
@@ -106,6 +106,10 @@
return mCtrl->getCrop();
}
+uint8_t GenericPipe::getPriority() const {
+ return mCtrl->getPriority();
+}
+
void GenericPipe::dump() const
{
ALOGE("== Dump Generic pipe start ==");
diff --git a/liboverlay/pipes/overlayGenPipe.h b/liboverlay/pipes/overlayGenPipe.h
index 813a2b3..ee6f9ad 100644
--- a/liboverlay/pipes/overlayGenPipe.h
+++ b/liboverlay/pipes/overlayGenPipe.h
@@ -69,6 +69,8 @@
bool isOpen() const;
/* return Ctrl fd. Used for S3D */
int getCtrlFd() const;
+ /* return pipe priority */
+ uint8_t getPriority() const;
/* dump the state of the object */
void dump() const;
/* Return the dump in the specified buffer */