Merge "hwc: Full MDP Composition mode with overlap region removal"
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 6af0eea..77c9922 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -566,8 +566,7 @@
         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
-            ystride = hnd->width;
-            cstride = hnd->width/2;
+            ystride = cstride = hnd->width;
             ycbcr->y  = (void*)hnd->base;
             ycbcr->cb = (void*)(hnd->base + ystride * hnd->height);
             ycbcr->cr = (void*)(hnd->base + ystride * hnd->height + 1);
@@ -581,8 +580,7 @@
         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
         case HAL_PIXEL_FORMAT_NV21_ZSL:
         case HAL_PIXEL_FORMAT_RAW_SENSOR:
-            ystride = hnd->width;
-            cstride = hnd->width/2;
+            ystride = cstride = hnd->width;
             ycbcr->y  = (void*)hnd->base;
             ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
             ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1);
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index f04bd76..3d88b3b 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -424,7 +424,11 @@
         ctx->mOverlay->configBegin();
         ctx->mOverlay->configDone();
         ctx->mRotMgr->clear();
-        overlay::Writeback::clear();
+        // If VDS is connected, do not clear WB object as it
+        // will end up detaching IOMMU. This is required
+        // to send black frame to WFD sink on power suspend.
+        // Note: With this change, we keep the WriteBack object
+        // alive on power suspend for AD use case.
     }
     switch(dpy) {
     case HWC_DISPLAY_PRIMARY:
@@ -478,13 +482,6 @@
                     ret = -1;
                 }
             }
-            value = blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK;
-            if(ioctl(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].fd, FBIOBLANK, value) < 0
-                    ) {
-                ALOGE("%s: Failed to handle blank event(%d) for virtual!!",
-                        __FUNCTION__, blank );
-                return -1;
-            }
             ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = !blank;
         }
         break;
@@ -837,7 +834,7 @@
     dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
     for(int dpy = 0; dpy < HWC_NUM_DISPLAY_TYPES; dpy++) {
         if(ctx->mMDPComp[dpy])
-            ctx->mMDPComp[dpy]->dump(aBuf);
+            ctx->mMDPComp[dpy]->dump(aBuf, ctx);
     }
     char ovDump[2048] = {'\0'};
     ctx->mOverlay->getDump(ovDump, 2048);
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 204d275..8b64193 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -59,7 +59,7 @@
 
 MDPComp::MDPComp(int dpy):mDpy(dpy){};
 
-void MDPComp::dump(android::String8& buf)
+void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
 {
     if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
         return;
@@ -73,6 +73,21 @@
     dumpsys_log(buf,"needsFBRedraw:%3s  pipesUsed:%2d  MaxPipesPerMixer: %d \n",
                 (mCurrentFrame.needsRedraw? "YES" : "NO"),
                 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
+    if(isDisplaySplit(ctx, mDpy)) {
+        dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
+                "Right: [%d, %d, %d, %d] \n",
+                ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
+                ctx->listStats[mDpy].lRoi.right,
+                ctx->listStats[mDpy].lRoi.bottom,
+                ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
+                ctx->listStats[mDpy].rRoi.right,
+                ctx->listStats[mDpy].rRoi.bottom);
+    } else {
+        dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
+                ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
+                ctx->listStats[mDpy].lRoi.right,
+                ctx->listStats[mDpy].lRoi.bottom);
+    }
     dumpsys_log(buf," ---------------------------------------------  \n");
     dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype  |  Z  \n");
     dumpsys_log(buf," ---------------------------------------------  \n");
@@ -1585,7 +1600,7 @@
         ALOGD("GEOMETRY change: %d",
                 (list->flags & HWC_GEOMETRY_CHANGED));
         android::String8 sDump("");
-        dump(sDump);
+        dump(sDump, ctx);
         ALOGD("%s",sDump.string());
     }
 
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 66d0b0b..520c176 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -44,7 +44,7 @@
     /* draw */
     virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list) = 0;
     /* dumpsys */
-    void dump(android::String8& buf);
+    void dump(android::String8& buf, hwc_context_t *ctx);
     bool isGLESOnlyComp() { return (mCurrentFrame.mdpCount == 0); }
     bool isPTORActive() { return (mOverlapIndex != -1); }
     int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list);
diff --git a/libhwcomposer/hwc_virtual.cpp b/libhwcomposer/hwc_virtual.cpp
index 97b19ea..df471a6 100644
--- a/libhwcomposer/hwc_virtual.cpp
+++ b/libhwcomposer/hwc_virtual.cpp
@@ -137,6 +137,7 @@
              * Mark all application layers as OVERLAY so that
              * GPU will not compose.
              */
+            Writeback::getInstance(); //Ensure that WB is active during pause
             for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) {
                 hwc_layer_1_t *layer = &list->hwLayers[i];
                 layer->compositionType = HWC_OVERLAY;
@@ -224,6 +225,16 @@
     }
     usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
             * 2 / 1000);
+    // At this point all the pipes used by External have been
+    // marked as UNSET.
+    {
+        Locker::Autolock _l(ctx->mDrawLock);
+        // Perform commit to unstage the pipes.
+        if (!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
+            ALOGE("%s: display commit fail! for %d dpy",
+                    __FUNCTION__, dpy);
+        }
+    }
     return;
 }
 
diff --git a/libqservice/QService.cpp b/libqservice/QService.cpp
index e4af422..12dd995 100644
--- a/libqservice/QService.cpp
+++ b/libqservice/QService.cpp
@@ -28,6 +28,8 @@
  */
 
 #include <QService.h>
+#include <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
 
 #define QSERVICE_DEBUG 0
 
@@ -55,6 +57,10 @@
 status_t QService::dispatch(uint32_t command, const Parcel* inParcel,
         Parcel* outParcel) {
     status_t err = (status_t) FAILED_TRANSACTION;
+    IPCThreadState* ipc = IPCThreadState::self();
+    //Rewind parcel in case we're calling from the same process
+    if (ipc->getCallingPid() == getpid())
+        inParcel->setDataPosition(0);
     if (mClient.get()) {
         ALOGD_IF(QSERVICE_DEBUG, "Dispatching command: %d", command);
         err = mClient->notifyCallback(command, inParcel, outParcel);