h/q/d: Optimize framebuffer layer update
While doing mixed mode composition, update only the region of the
framebuffer where layer contents are cached or updated. Avoids
MDP fetch for non-visible contents of FB.
Change-Id: I20997d79e02a6bac60d7333c28c6dde134263197
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 78a05e9..cc9e3b9 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -62,7 +62,8 @@
bool IFBUpdate::prepareAndValidate(hwc_context_t *ctx,
hwc_display_contents_1 *list, int fbZorder) {
- return prepare(ctx, list, fbZorder) &&
+ hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
+ return prepare(ctx, list, layer->displayFrame, fbZorder) &&
ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd);
}
@@ -106,19 +107,19 @@
}
bool FBUpdateNonSplit::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
- int fbZorder) {
+ hwc_rect_t fbUpdatingRect, int fbZorder) {
if(!ctx->mMDP.hasOverlay) {
ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
__FUNCTION__);
return false;
}
- mModeOn = configure(ctx, list, fbZorder);
+ mModeOn = configure(ctx, list, fbUpdatingRect, fbZorder);
return mModeOn;
}
// Configure
bool FBUpdateNonSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
- int fbZorder) {
+ hwc_rect_t fbUpdatingRect, int fbZorder) {
bool ret = false;
hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
if (LIKELY(ctx->mOverlay)) {
@@ -159,6 +160,15 @@
hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
hwc_rect_t displayFrame = layer->displayFrame;
+
+ // No FB update optimization on (1) Custom FB resolution,
+ // (2) External Mirror mode, (3) External orientation
+ if(!ctx->dpyAttr[mDpy].customFBSize && !ctx->mBufferMirrorMode
+ && !ctx->mExtOrientation) {
+ sourceCrop = fbUpdatingRect;
+ displayFrame = fbUpdatingRect;
+ }
+
int transform = layer->transform;
int rotFlags = ovutils::ROT_FLAGS_NONE;
@@ -251,20 +261,20 @@
}
bool FBUpdateSplit::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
- int fbZorder) {
+ hwc_rect_t fbUpdatingRect, int fbZorder) {
if(!ctx->mMDP.hasOverlay) {
ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
__FUNCTION__);
return false;
}
ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
- mModeOn = configure(ctx, list, fbZorder);
+ mModeOn = configure(ctx, list, fbUpdatingRect, fbZorder);
return mModeOn;
}
// Configure
bool FBUpdateSplit::configure(hwc_context_t *ctx,
- hwc_display_contents_1 *list, int fbZorder) {
+ hwc_display_contents_1 *list, hwc_rect_t fbUpdatingRect, int fbZorder) {
bool ret = false;
hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
if (LIKELY(ctx->mOverlay)) {
@@ -328,8 +338,8 @@
getBlending(layer->blending));
ov.setSource(pargR, destR);
- hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t displayFrame = layer->displayFrame;
+ hwc_rect_t sourceCrop = fbUpdatingRect;
+ hwc_rect_t displayFrame = fbUpdatingRect;
const float xres = ctx->dpyAttr[mDpy].xres;
const int lSplit = getLeftSplit(ctx, mDpy);