Merge "hwc: Skip load based composition for video playback."
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index f15a973..b4da363 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -277,6 +277,13 @@
             grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21
     }
 
+    if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
+            (usage & GRALLOC_USAGE_HW_COMPOSER )) {
+        //XXX: If we still haven't set a format, default to
+        //RGBA8888
+        grallocFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+    }
+
     getGrallocInformationFromFormat(grallocFormat, &bufferType);
     size = getBufferSizeAndDimensions(w, h, grallocFormat, alignedw, alignedh);
 
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 22e69f3..eb999f7 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -486,7 +486,7 @@
         //TODO We dont check for SKIP flag on this layer because we need PAN
         //always. Last layer is always FB
         private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
-        if(copybitDone) {
+        if(copybitDone && ctx->mMDP.version >= qdutils::MDP_V4_0) {
             hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
         }
 
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 4695a4f..47b9225 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -199,7 +199,8 @@
     }
 
     //Allocate render buffers if they're not allocated
-    if (useCopybitForYUV || useCopybitForRGB) {
+    if (ctx->mMDP.version != qdutils::MDP_V3_0_4 &&
+            (useCopybitForYUV || useCopybitForRGB)) {
         int ret = allocRenderBuffers(mAlignedFBWidth,
                                      mAlignedFBHeight,
                                      HAL_PIXEL_FORMAT_RGBA_8888);
@@ -223,7 +224,10 @@
         // Mark all layers to be drawn by copybit
         for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
             layerProp[i].mFlags |= HWC_COPYBIT;
-            list->hwLayers[i].compositionType = HWC_OVERLAY;
+            if (ctx->mMDP.version == qdutils::MDP_V3_0_4)
+                list->hwLayers[i].compositionType = HWC_BLIT;
+            else
+                list->hwLayers[i].compositionType = HWC_OVERLAY;
         }
     }
 
@@ -254,13 +258,20 @@
     // draw layers marked for COPYBIT
     int retVal = true;
     int copybitLayerCount = 0;
+    uint32_t last = 0;
     LayerProp *layerProp = ctx->layerProp[dpy];
+    private_handle_t *renderBuffer;
 
     if(mCopyBitDraw == false) // there is no layer marked for copybit
         return false ;
 
     //render buffer
-    private_handle_t *renderBuffer = getCurrentRenderBuffer();
+    if (ctx->mMDP.version == qdutils::MDP_V3_0_4) {
+        last = list->numHwLayers - 1;
+        renderBuffer = (private_handle_t *)list->hwLayers[last].handle;
+    } else {
+        renderBuffer = getCurrentRenderBuffer();
+    }
     if (!renderBuffer) {
         ALOGE("%s: Render buffer layer handle is NULL", __FUNCTION__);
         return false;
@@ -274,9 +285,9 @@
             mRelFd[mCurRenderBufferIndex] = -1;
         }
     } else {
-        if(mRelFd[mCurRenderBufferIndex] >=0) {
+        if(list->hwLayers[last].acquireFenceFd >=0) {
             copybit_device_t *copybit = getCopyBitDevice();
-            copybit->set_sync(copybit, mRelFd[mCurRenderBufferIndex]);
+            copybit->set_sync(copybit, list->hwLayers[last].acquireFenceFd);
         }
     }
 
@@ -316,10 +327,10 @@
         copybit_device_t *copybit = getCopyBitDevice();
         // Async mode
         copybit->flush_get_fence(copybit, fd);
-        if(mRelFd[mCurRenderBufferIndex] >=0 &&
-           ctx->mMDP.version == qdutils::MDP_V3_0_4) {
-            close(mRelFd[mCurRenderBufferIndex]);
-            mRelFd[mCurRenderBufferIndex] = -1;
+        if(ctx->mMDP.version == qdutils::MDP_V3_0_4 &&
+                list->hwLayers[last].acquireFenceFd >= 0) {
+            close(list->hwLayers[last].acquireFenceFd);
+            list->hwLayers[last].acquireFenceFd = -1;
         }
     }
     return true;
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 0ca5ad9..d601f8f 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -176,6 +176,8 @@
         }
         calcExtDisplayPosition(ctx, NULL, mDpy, sourceCrop, displayFrame,
                                    transform, orient);
+        //Store the displayFrame, will be used in getDisplayViewFrame
+        ctx->dpyAttr[mDpy].mDstRect = displayFrame;
         setMdpFlags(layer, mdpFlags, 0, transform);
         // For External use rotator if there is a rotation value set
         ret = preRotateExtDisplay(ctx, layer, info,
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index a3f6b5b..50e94c9 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -140,8 +140,34 @@
     ctx->mBufferMirrorMode = enable;
 }
 
+static status_t getDisplayVisibleRegion(hwc_context_t* ctx, int dpy,
+                                Parcel* outParcel) {
+    // Get the info only if the dpy is valid
+    if(dpy >= HWC_DISPLAY_PRIMARY && dpy <= HWC_DISPLAY_VIRTUAL) {
+        Locker::Autolock _sl(ctx->mDrawLock);
+        if(dpy && (ctx->mExtOrientation || ctx->mBufferMirrorMode)) {
+            // Return the destRect on external, if external orienation
+            // is enabled
+            outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.left);
+            outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.top);
+            outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.right);
+            outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.bottom);
+        } else {
+            outParcel->writeInt32(ctx->mViewFrame[dpy].left);
+            outParcel->writeInt32(ctx->mViewFrame[dpy].top);
+            outParcel->writeInt32(ctx->mViewFrame[dpy].right);
+            outParcel->writeInt32(ctx->mViewFrame[dpy].bottom);
+        }
+        return NO_ERROR;
+    } else {
+        ALOGE("In %s: invalid dpy index %d", __FUNCTION__, dpy);
+        return BAD_VALUE;
+    }
+}
+
 status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
         Parcel* outParcel) {
+    status_t ret = NO_ERROR;
 
     if (command > IQService::VPU_COMMAND_LIST_START &&
         command < IQService::VPU_COMMAND_LIST_END) {
@@ -164,6 +190,10 @@
         case IQService::BUFFER_MIRRORMODE:
             setBufferMirrorMode(mHwcContext, inParcel->readInt32());
             break;
+        case IQService::GET_DISPLAY_VISIBLE_REGION:
+            ret = getDisplayVisibleRegion(mHwcContext, inParcel->readInt32(),
+                                    outParcel);
+            break;
         case IQService::CHECK_EXTERNAL_STATUS:
             isExternalConnected(mHwcContext, outParcel);
             break;
@@ -174,9 +204,9 @@
             setHSIC(mHwcContext, inParcel);
             break;
         default:
-            return NO_ERROR;
+            ret = NO_ERROR;
     }
-    return NO_ERROR;
+    return ret;
 }
 
 
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 10afc92..51e5526 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -121,6 +121,7 @@
 {
     bool bpanelReset = getPanelResetStatus(ctx, udata, len);
     if (bpanelReset) {
+        ctx->proc->invalidate(ctx->proc);
         return;
     }
 
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index f2ab7e6..0663f67 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -1188,7 +1188,8 @@
 
     //Accumulate acquireFenceFds for MDP
     for(uint32_t i = 0; i < list->numHwLayers; i++) {
-        if(list->hwLayers[i].compositionType == HWC_OVERLAY &&
+        if((list->hwLayers[i].compositionType == HWC_OVERLAY  ||
+                        list->hwLayers[i].compositionType == HWC_BLIT) &&
                         list->hwLayers[i].acquireFenceFd >= 0) {
             if(UNLIKELY(swapzero))
                 acquireFd[count++] = -1;
@@ -1230,6 +1231,7 @@
 
     for(uint32_t i = 0; i < list->numHwLayers; i++) {
         if(list->hwLayers[i].compositionType == HWC_OVERLAY ||
+           list->hwLayers[i].compositionType == HWC_BLIT ||
            list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
             //Populate releaseFenceFds.
             if(UNLIKELY(swapzero)) {
@@ -1403,6 +1405,7 @@
     uint32_t color = layer->transform;
     Whf whf(w, h, getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888), 0);
 
+    ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SOLID_FILL);
     if (layer->blending == HWC_BLENDING_PREMULT)
         ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_BLEND_FG_PREMULT);
 
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 872b306..cd84f73 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -87,6 +87,8 @@
     bool isConfiguring;
     // External Display is in MDP Downscale mode indicator
     bool mDownScaleMode;
+    // Ext dst Rect
+    hwc_rect_t mDstRect;
 };
 
 struct ListStats {
diff --git a/libmemtrack/kgsl.c b/libmemtrack/kgsl.c
index 4843742..6dd4e27 100644
--- a/libmemtrack/kgsl.c
+++ b/libmemtrack/kgsl.c
@@ -47,7 +47,7 @@
     size_t allocated_records = min(*num_records, ARRAY_SIZE(record_templates));
     int i;
     FILE *fp;
-    FILE *smaps_fp;
+    FILE *smaps_fp = NULL;
     char line[1024];
     char tmp[128];
     size_t accounted_size = 0;
@@ -74,6 +74,7 @@
         snprintf(tmp, sizeof(tmp), "/proc/%d/smaps", pid);
         smaps_fp = fopen(tmp, "r");
         if (smaps_fp == NULL) {
+            fclose(fp);
             return -errno;
         }
     }
@@ -145,6 +146,8 @@
         records[1].size_in_bytes = unaccounted_size;
     }
 
+    if (smaps_fp)
+        fclose(smaps_fp);
     fclose(fp);
 
     return 0;
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index 55f1767..904d607 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -271,6 +271,7 @@
     OV_MDP_PP_EN = MDP_OVERLAY_PP_CFG_EN,
     OV_MDSS_MDP_BWC_EN = MDP_BWC_EN,
     OV_MDSS_MDP_DUAL_PIPE = MDSS_MDP_DUAL_PIPE,
+    OV_MDP_SOLID_FILL = MDP_SOLID_FILL,
 };
 
 enum eZorder {
diff --git a/libqdutils/display_config.cpp b/libqdutils/display_config.cpp
index eaf5384..45b0211 100644
--- a/libqdutils/display_config.cpp
+++ b/libqdutils/display_config.cpp
@@ -91,4 +91,26 @@
         ALOGE("%s: Failed to get external status err=%d", __FUNCTION__, err);
     return err;
 }
+
+int getDisplayVisibleRegion(int dpy, hwc_rect_t &rect) {
+    status_t err = FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    Parcel inParcel, outParcel;
+    inParcel.writeInt32(dpy);
+    if(binder != NULL) {
+        err = binder->dispatch(IQService::GET_DISPLAY_VISIBLE_REGION,
+                &inParcel, &outParcel);
+    }
+    if(!err) {
+        rect.left = outParcel.readInt32();
+        rect.top = outParcel.readInt32();
+        rect.right = outParcel.readInt32();
+        rect.bottom = outParcel.readInt32();
+    } else {
+        ALOGE("%s: Failed to getVisibleRegion for dpy =%d: err = %d",
+              __FUNCTION__, dpy, err);
+    }
+    return err;
+}
+
 }; //namespace
diff --git a/libqdutils/display_config.h b/libqdutils/display_config.h
index c7d8ce9..29edbef 100644
--- a/libqdutils/display_config.h
+++ b/libqdutils/display_config.h
@@ -29,6 +29,7 @@
 #include <gralloc_priv.h>
 #include <qdMetaData.h>
 #include <mdp_version.h>
+#include <hardware/hwcomposer.h>
 
 // This header is for clients to use to set/get global display configuration
 // The functions in this header run in the client process and wherever necessary
@@ -69,4 +70,7 @@
 // Returns 0 on success, negative values on errors
 int setHSIC(int dpy, const HSICData_t& hsic_data);
 
+// get the active visible region for the display
+// Returns 0 on success, negative values on errors
+int getDisplayVisibleRegion(int dpy, hwc_rect_t &rect);
 }; //namespace
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index d6e525a..f8e58ab 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -48,6 +48,7 @@
         CHECK_EXTERNAL_STATUS,   // Check status of external display
         GET_DISPLAY_ATTRIBUTES,  // Get display attributes
         SET_HSIC_DATA,           // Set HSIC on dspp
+        GET_DISPLAY_VISIBLE_REGION,  // Get the visibleRegion for dpy
         VPU_COMMAND_LIST_START = 100, //Reserved block for VPU commands
         VPU_COMMAND_LIST_END   = 200,
         COMMAND_LIST_END = 400,