hwc: Handle multiple videos with priority to secure
In video handling this patch makes sure:
1) Sufficient VG pipes are available, not just any pipes
2) If VG pipes are insufficient in multi-video scenarios
preference is given to secure videos
Change-Id: I170592463a1c28348108a1b12d60908cf3063d7d
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index d388ebb..6e44234 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -482,7 +482,7 @@
//Setup mCurrentFrame
mCurrentFrame.reset(numAppLayers);
updateLayerCache(ctx, list);
- updateYUV(ctx, list);
+ updateYUV(ctx, list, false /*secure only*/);
batchLayers(); //sets up fbZ also
int mdpCount = mCurrentFrame.mdpCount;
@@ -505,10 +505,10 @@
}
bool MDPComp::isOnlyVideoDoable(hwc_context_t *ctx,
- hwc_display_contents_1_t* list){
+ hwc_display_contents_1_t* list, bool secureOnly) {
int numAppLayers = ctx->listStats[mDpy].numAppLayers;
mCurrentFrame.reset(numAppLayers);
- updateYUV(ctx, list);
+ updateYUV(ctx, list, secureOnly);
int mdpCount = mCurrentFrame.mdpCount;
int fbNeeded = int(mCurrentFrame.fbCount != 0);
@@ -644,8 +644,8 @@
ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, numCacheableLayers);
}
-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,
+ bool secureOnly) {
int nYuvCount = ctx->listStats[mDpy].yuvCount;
if(!nYuvCount && mDpy) {
//Reset "No animation on external display" related parameters.
@@ -667,8 +667,11 @@
}
} else {
if(mCurrentFrame.isFBComposed[nYuvIndex]) {
- mCurrentFrame.isFBComposed[nYuvIndex] = false;
- mCurrentFrame.fbCount--;
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+ if(!secureOnly || isSecureBuffer(hnd)) {
+ mCurrentFrame.isFBComposed[nYuvIndex] = false;
+ mCurrentFrame.fbCount--;
+ }
}
}
}
@@ -839,7 +842,8 @@
mCurrentFrame.needsRedraw = true;
}
}
- } else if(isOnlyVideoDoable(ctx, list)) {
+ } else if(isOnlyVideoDoable(ctx, list, false /*secure only*/) ||
+ isOnlyVideoDoable(ctx, list, true /*secure only*/)) {
//All layers marked for MDP comp cannot be bypassed.
//Try to compose atleast YUV layers through MDP comp and let
//all the RGB layers compose in FB
@@ -926,6 +930,36 @@
return false;
}
+ if(not areVGPipesAvailable(ctx, list)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool MDPCompNonSplit::areVGPipesAvailable(hwc_context_t *ctx,
+ hwc_display_contents_1_t* list) {
+ overlay::Overlay& ov = *ctx->mOverlay;
+ int pipesNeeded = 0;
+ for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
+ if(!mCurrentFrame.isFBComposed[i]) {
+ hwc_layer_1_t* layer = &list->hwLayers[i];
+ hwc_rect_t dst = layer->displayFrame;
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+ if(isYuvBuffer(hnd)) {
+ pipesNeeded++;
+ }
+ }
+ }
+
+ int availableVGPipes = ov.availablePipes(mDpy, ovutils::OV_MDP_PIPE_VG);
+ if(pipesNeeded > availableVGPipes) {
+ ALOGD_IF(isDebug(), "%s: Insufficient VG pipes for video layers"
+ "dpy %d needed %d, avail %d",
+ __FUNCTION__, mDpy, pipesNeeded, availableVGPipes);
+ return false;
+ }
+
return true;
}
@@ -1094,6 +1128,42 @@
return false;
}
+ if(not areVGPipesAvailable(ctx, list)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool MDPCompSplit::areVGPipesAvailable(hwc_context_t *ctx,
+ hwc_display_contents_1_t* list) {
+ overlay::Overlay& ov = *ctx->mOverlay;
+ int pipesNeeded = 0;
+ const int lSplit = getLeftSplit(ctx, mDpy);
+ for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
+ if(!mCurrentFrame.isFBComposed[i]) {
+ hwc_layer_1_t* layer = &list->hwLayers[i];
+ hwc_rect_t dst = layer->displayFrame;
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+ if(isYuvBuffer(hnd)) {
+ if(dst.left < lSplit) {
+ pipesNeeded++;
+ }
+ if(dst.right > lSplit) {
+ pipesNeeded++;
+ }
+ }
+ }
+ }
+
+ int availableVGPipes = ov.availablePipes(mDpy, ovutils::OV_MDP_PIPE_VG);
+ if(pipesNeeded > availableVGPipes) {
+ ALOGD_IF(isDebug(), "%s: Insufficient VG pipes for video layers"
+ "dpy %d needed %d, avail %d",
+ __FUNCTION__, mDpy, pipesNeeded, availableVGPipes);
+ return false;
+ }
+
return true;
}
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index da4b330..7fb0968 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -139,7 +139,8 @@
/* 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);
+ bool isOnlyVideoDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list,
+ bool secureOnly);
/* checks for conditions where YUV layers cannot be bypassed */
bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
/* calcs bytes read by MDP for a given frame */
@@ -159,7 +160,8 @@
/* optimize layers for mdp comp*/
void batchLayers();
/* 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,
+ bool secureOnly);
bool programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list);
bool programYUV(hwc_context_t *ctx, hwc_display_contents_1_t* list);
void reset(const int& numAppLayers, hwc_display_contents_1_t* list);
@@ -203,6 +205,10 @@
/* Checks for pipes needed versus pipes available */
virtual bool arePipesAvailable(hwc_context_t *ctx,
hwc_display_contents_1_t* list);
+
+ /* Checks for video pipes needed versus pipes available */
+ virtual bool areVGPipesAvailable(hwc_context_t *ctx,
+ hwc_display_contents_1_t* list);
};
class MDPCompSplit : public MDPComp {
@@ -232,6 +238,10 @@
virtual bool arePipesAvailable(hwc_context_t *ctx,
hwc_display_contents_1_t* list);
+ /* Checks for video pipes needed versus pipes available */
+ virtual bool areVGPipesAvailable(hwc_context_t *ctx,
+ hwc_display_contents_1_t* list);
+
int pipesNeeded(hwc_context_t *ctx, hwc_display_contents_1_t* list,
int mixer);
};
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 4b91038..9d7f5c8 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -86,6 +86,8 @@
int availablePipes(int dpy, int mixer);
/* Returns available ("unallocated") pipes for a display */
int availablePipes(int dpy);
+ /* Returns available ("unallocated") pipe of given type for a display */
+ int availablePipes(int dpy, utils::eMdpPipeType type);
/* Returns if any of the requested pipe type is attached to any of the
* displays
*/
@@ -215,6 +217,19 @@
return avail;
}
+inline int Overlay::availablePipes(int dpy, utils::eMdpPipeType type) {
+ int avail = 0;
+ for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
+ if((mPipeBook[i].mDisplay == DPY_UNUSED ||
+ mPipeBook[i].mDisplay == dpy) &&
+ PipeBook::isNotAllocated(i) &&
+ type == PipeBook::getPipeType((utils::eDest)i)) {
+ avail++;
+ }
+ }
+ return avail;
+}
+
inline void Overlay::setDMAMode(const int& mode) {
if(mode == DMA_LINE_MODE || mode == DMA_BLOCK_MODE)
sDMAMode = mode;