Merge "hwc: vds: Add support to dump layers, FB and WB output buffer"
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 4708368..59e39bb 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -2080,6 +2080,24 @@
     return true;
 }
 
+void dumpBuffer(private_handle_t *ohnd, char *bufferName) {
+    if (ohnd != NULL && ohnd->base) {
+        char dumpFilename[PATH_MAX];
+        bool bResult = false;
+        snprintf(dumpFilename, sizeof(dumpFilename), "/data/%s.%s.%dx%d.raw",
+            bufferName,
+            overlay::utils::getFormatString(utils::getMdpFormat(ohnd->format)),
+            getWidth(ohnd), getHeight(ohnd));
+        FILE* fp = fopen(dumpFilename, "w+");
+        if (NULL != fp) {
+            bResult = (bool) fwrite((void*)ohnd->base, ohnd->size, 1, fp);
+            fclose(fp);
+        }
+        ALOGD("Buffer[%s] Dump to %s: %s",
+        bufferName, dumpFilename, bResult ? "Success" : "Fail");
+    }
+}
+
 bool isGLESComp(hwc_context_t *ctx,
                      hwc_display_contents_1_t* list) {
     int numAppLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index c7b7ded..5086d72 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -257,6 +257,7 @@
 
 bool canUseMDPforVirtualDisplay(hwc_context_t* ctx,
                                 const hwc_display_contents_1_t *list);
+void dumpBuffer(private_handle_t *ohnd, char *bufferName);
 
 //Helper function to dump logs
 void dumpsys_log(android::String8& buf, const char* fmt, ...);
diff --git a/libhwcomposer/hwc_virtual.cpp b/libhwcomposer/hwc_virtual.cpp
index adda35b..01c0873 100644
--- a/libhwcomposer/hwc_virtual.cpp
+++ b/libhwcomposer/hwc_virtual.cpp
@@ -29,6 +29,7 @@
 #include "hwc_dump_layers.h"
 #include "hwc_copybit.h"
 #include "hwc_virtual.h"
+#include "sync/sync.h"
 
 #define HWCVIRTUAL_LOG 0
 
@@ -48,6 +49,16 @@
     }
 }
 
+HWCVirtualVDS::HWCVirtualVDS() {
+    char value[PROPERTY_VALUE_MAX];
+    mVDSDumpEnabled = false;
+    if((property_get("debug.hwc.enable_vds_dump", value, NULL) > 0)) {
+        if(atoi(value) != 0) {
+            mVDSDumpEnabled = true;
+        }
+    }
+}
+
 void HWCVirtualVDS::init(hwc_context_t *ctx) {
     const int dpy = HWC_DISPLAY_VIRTUAL;
     ctx->mFBUpdate[dpy] =
@@ -178,6 +189,10 @@
             int fd = -1; //FenceFD from the Copybit
             hwc_sync(ctx, list, dpy, fd);
 
+            // Dump the layers for virtual
+            if(ctx->mHwcDebug[dpy])
+                ctx->mHwcDebug[dpy]->dumpLayers(list);
+
             if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
                 ALOGE("%s: MDPComp draw failed", __FUNCTION__);
                 ret = -1;
@@ -201,6 +216,19 @@
                 ret = -1;
             }
 
+            if(mVDSDumpEnabled) {
+                char bufferName[128];
+                // Dumping frame buffer
+                sync_wait(fbLayer->acquireFenceFd, 1000);
+                snprintf(bufferName, sizeof(bufferName), "vds.fb");
+                dumpBuffer((private_handle_t *)fbLayer->handle, bufferName);
+                // Dumping WB output for non-secure session
+                if(!isSecureBuffer(ohnd)) {
+                    sync_wait(list->retireFenceFd, 1000);
+                    snprintf(bufferName, sizeof(bufferName), "vds.wb");
+                    dumpBuffer(ohnd, bufferName);
+                }
+            }
         } else if(list->outbufAcquireFenceFd >= 0) {
             //If we dont handle the frame, set retireFenceFd to outbufFenceFd,
             //which will make sure, the framework waits on it and closes it.
diff --git a/libhwcomposer/hwc_virtual.h b/libhwcomposer/hwc_virtual.h
index 87004c3..26d89c9 100644
--- a/libhwcomposer/hwc_virtual.h
+++ b/libhwcomposer/hwc_virtual.h
@@ -46,7 +46,7 @@
 
 class HWCVirtualVDS : public HWCVirtualBase {
 public:
-    explicit HWCVirtualVDS(){};
+    explicit HWCVirtualVDS();
     virtual ~HWCVirtualVDS(){};
     // Chooses composition type and configures pipe for each layer in virtual
     // display list
@@ -64,6 +64,12 @@
                        hwc_display_contents_1_t** displays);
     virtual void pause(hwc_context_t* ctx, int dpy);
     virtual void resume(hwc_context_t* ctx, int dpy);
+private:
+    // If WFD is enabled through VDS solution
+    // we can dump the frame buffer and WB
+    // output buffer by setting the property
+    // debug.hwc.enable_vds_dump
+    bool mVDSDumpEnabled;
 };
 
 class HWCVirtualV4L2 : public HWCVirtualBase {