Merge "display: Use fences for all targets"
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index a05ea16..f9ee94c 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (C) 2010 The Android Open Source Project
  * Copyright (C) 2012, The Linux Foundation. All rights reserved.
@@ -37,37 +36,142 @@
 #include "hwc_utils.h"
 #include "external.h"
 #include "overlayUtils.h"
+#include "overlay.h"
 
 using namespace android;
 
 namespace qhwc {
 
+#define MAX_FRAME_BUFFER_NAME_SIZE      (80)
+#define MAX_DISPLAY_DEVICES             (3)
 
-#define DEVICE_ROOT "/sys/devices/virtual/graphics"
-#define DEVICE_NODE "fb1"
 
-#define SYSFS_EDID_MODES        DEVICE_ROOT "/" DEVICE_NODE "/edid_modes"
-#define SYSFS_HPD               DEVICE_ROOT "/" DEVICE_NODE "/hpd"
+const char* msmFbDevicePath[] = {  "/dev/graphics/fb1",
+                                   "/dev/graphics/fb2"};
 
+/*
+ * Updates extDeviceFbIndex Array with the correct frame buffer indices
+ * of avaiable external devices
+ *
+ */
+void ExternalDisplay::updateExtDispDevFbIndex()
+{
+    FILE *displayDeviceFP = NULL;
+    char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
+    char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
+
+    for(int j = 1; j < MAX_DISPLAY_DEVICES; j++) {
+        sprintf (msmFbTypePath,"/sys/class/graphics/fb%d/msm_fb_type", j);
+        displayDeviceFP = fopen(msmFbTypePath, "r");
+        if(displayDeviceFP){
+            fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
+                    displayDeviceFP);
+            if(strncmp(fbType, "dtv panel", strlen("dtv panel")) == 0){
+                ALOGD_IF(DEBUG,"hdmi framebuffer index is %d",j);
+                mHdmiFbNum = j;
+            } else if(strncmp(fbType, "writeback panel",
+                                    strlen("writeback panel")) == 0){
+                ALOGD_IF(DEBUG,"wfd framebuffer index is %d",j);
+                mWfdFbNum = j;
+            }
+            fclose(displayDeviceFP);
+        }
+    }
+    ALOGD_IF(DEBUG,"%s: mHdmiFbNum: %d mWfdFbNum: %d ",__FUNCTION__,
+                                                       mHdmiFbNum, mWfdFbNum);
+}
+
+int ExternalDisplay::configureHDMIDisplay() {
+    openFrameBuffer(mHdmiFbNum);
+    if(mFd == -1)
+        return -1;
+    readResolution();
+    //Get the best mode and set
+    // TODO: Move this to activate
+    setResolution(getBestMode());
+    setDpyHdmiAttr();
+    setExternalDisplay(true, mHdmiFbNum);
+    return 0;
+}
+
+int ExternalDisplay::configureWFDDisplay() {
+    int ret = 0;
+    if(mConnectedFbNum == mHdmiFbNum) {
+        ALOGE("%s: Cannot process WFD connection while HDMI is active",
+                     __FUNCTION__);
+        return -1;
+    }
+    openFrameBuffer(mWfdFbNum);
+    if(mFd == -1)
+        return -1;
+    ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
+    if(ret < 0) {
+        ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__,
+                strerror(errno));
+    }
+    setDpyWfdAttr();
+    setExternalDisplay(true, mWfdFbNum);
+    return 0;
+}
+
+int ExternalDisplay::teardownHDMIDisplay() {
+    if(mConnectedFbNum == mHdmiFbNum) {
+        // hdmi offline event..!
+        closeFrameBuffer();
+        resetInfo();
+        setExternalDisplay(false);
+    }
+    return 0;
+}
+
+int ExternalDisplay::teardownWFDDisplay() {
+    if(mConnectedFbNum == mWfdFbNum) {
+        // wfd offline event..!
+        closeFrameBuffer();
+        memset(&mVInfo, 0, sizeof(mVInfo));
+        setExternalDisplay(false);
+    }
+    return 0;
+}
+
+void ExternalDisplay::processUEventOnline(const char *str) {
+    const char *s1 = str + strlen("change@/devices/virtual/switch/");
+    if(!strncmp(s1,"hdmi",strlen(s1))) {
+        // hdmi online event..!
+        configureHDMIDisplay();
+    }else if(!strncmp(s1,"wfd",strlen(s1))) {
+        // wfd online event..!
+        configureWFDDisplay();
+    }
+}
+
+void ExternalDisplay::processUEventOffline(const char *str) {
+    const char *s1 = str + strlen("change@/devices/virtual/switch/");
+    if(!strncmp(s1,"hdmi",strlen(s1))) {
+        teardownHDMIDisplay();
+    }else if(!strncmp(s1,"wfd",strlen(s1))) {
+        teardownWFDDisplay();
+    }
+}
 
 ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
-    mCurrentMode(-1), mExternalDisplay(0), mModeCount(0), mHwcContext(ctx)
+    mCurrentMode(-1), mConnected(0), mConnectedFbNum(0), mModeCount(0),
+    mHwcContext(ctx), mHdmiFbNum(-1), mWfdFbNum(-1)
 {
     memset(&mVInfo, 0, sizeof(mVInfo));
-    //Enable HPD for HDMI
-    writeHPDOption(1);
+    //Determine the fb index for external display devices.
+    updateExtDispDevFbIndex();
 }
 
 void ExternalDisplay::setEDIDMode(int resMode) {
     ALOGD_IF(DEBUG,"resMode=%d ", resMode);
-    int extDispType;
     {
         Mutex::Autolock lock(mExtDispLock);
-        extDispType = mExternalDisplay;
-        setExternalDisplay(0);
+        setExternalDisplay(false);
+        openFrameBuffer(mHdmiFbNum);
         setResolution(resMode);
     }
-    setExternalDisplay(extDispType);
+    setExternalDisplay(true, mHdmiFbNum);
 }
 
 void ExternalDisplay::setHPD(uint32_t startEnd) {
@@ -79,7 +183,7 @@
     ALOGD_IF(DEBUG,"ActionSafe w=%d h=%d", w, h);
     Mutex::Autolock lock(mExtDispLock);
     overlay::utils::ActionSafe::getInstance()->setDimension(w, h);
-    setExternalDisplay(mExternalDisplay);
+    setExternalDisplay(true, mHdmiFbNum);
 }
 
 int ExternalDisplay::getModeCount() const {
@@ -206,12 +310,16 @@
 
 bool ExternalDisplay::readResolution()
 {
-    int hdmiEDIDFile = open(SYSFS_EDID_MODES, O_RDONLY, 0);
+    char sysFsEDIDFilePath[255];
+    sprintf(sysFsEDIDFilePath , "/sys/devices/virtual/graphics/fb%d/edid_modes",
+            mHdmiFbNum);
+
+    int hdmiEDIDFile = open(sysFsEDIDFilePath, O_RDONLY, 0);
     int len = -1;
 
     if (hdmiEDIDFile < 0) {
         ALOGE("%s: edid_modes file '%s' not found",
-                 __FUNCTION__, SYSFS_EDID_MODES);
+                 __FUNCTION__, sysFsEDIDFilePath);
         return false;
     } else {
         len = read(hdmiEDIDFile, mEDIDs, sizeof(mEDIDs)-1);
@@ -219,7 +327,7 @@
                  __FUNCTION__, mEDIDs, len);
         if ( len <= 0) {
             ALOGE("%s: edid_modes file empty '%s'",
-                     __FUNCTION__, SYSFS_EDID_MODES);
+                     __FUNCTION__, sysFsEDIDFilePath);
         }
         else {
             while (len > 1 && isspace(mEDIDs[len-1]))
@@ -229,7 +337,7 @@
     }
     close(hdmiEDIDFile);
     if(len > 0) {
-        // GEt EDID modes from the EDID strings
+        // Get EDID modes from the EDID strings
         mModeCount = parseResolution(mEDIDs, mEDIDModes);
         ALOGD_IF(DEBUG, "%s: mModeCount = %d", __FUNCTION__,
                  mModeCount);
@@ -238,15 +346,16 @@
     return (strlen(mEDIDs) > 0);
 }
 
-bool ExternalDisplay::openFramebuffer()
+bool ExternalDisplay::openFrameBuffer(int fbNum)
 {
     if (mFd == -1) {
-        mFd = open("/dev/graphics/fb1", O_RDWR);
+        mFd = open(msmFbDevicePath[fbNum-1], O_RDWR);
         if (mFd < 0)
-            ALOGE("%s: /dev/graphics/fb1 not available", __FUNCTION__);
-    }
-    if(mHwcContext) {
-        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].fd = mFd;
+            ALOGE("%s: %s is not available", __FUNCTION__,
+                                            msmFbDevicePath[fbNum-1]);
+        if(mHwcContext) {
+            mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].fd = mFd;
+        }
     }
     return (mFd > 0);
 }
@@ -341,8 +450,6 @@
 {
     struct fb_var_screeninfo info;
     int ret = 0;
-    if (!openFramebuffer())
-        return;
     ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
     if(ret < 0) {
         ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__,
@@ -384,54 +491,49 @@
     }
 }
 
-void ExternalDisplay::setExternalDisplay(int connected)
+void ExternalDisplay::setExternalDisplay(bool connected, int extFbNum)
 {
-
     hwc_context_t* ctx = mHwcContext;
     if(ctx) {
-        ALOGD_IF(DEBUG, "%s: status = %d", __FUNCTION__,
-                 connected);
-        if(connected) {
-            readResolution();
-            //Get the best mode and set
-            // TODO: Move this to activate
-            setResolution(getBestMode());
-            setDpyAttr();
-            //enable hdmi vsync
-        } else {
-            // Disable the hdmi vsync
-            closeFrameBuffer();
-            resetInfo();
-        }
+        ALOGD_IF(DEBUG, "%s: connected = %d", __FUNCTION__, connected);
         // Store the external display
-        mExternalDisplay = connected;
-        const char* prop = (connected) ? "1" : "0";
-        // set system property
-        property_set("hw.hdmiON", prop);
+        mConnected = connected;
+        mConnectedFbNum = extFbNum;
+        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
+        // Update external fb number in Overlay context
+        overlay::Overlay::getInstance()->setExtFbNum(extFbNum);
     }
-    return;
+}
+
+int ExternalDisplay::getExtFbNum(int &fbNum) {
+    int ret = -1;
+    if(mConnected) {
+        fbNum = mConnectedFbNum;
+        ret = 0;
+    }
+    return ret;
 }
 
 bool ExternalDisplay::writeHPDOption(int userOption) const
 {
     bool ret = true;
-    int hdmiHPDFile = open(SYSFS_HPD,O_RDWR, 0);
+    char sysFsHPDFilePath[255];
+    sprintf(sysFsHPDFilePath ,"/sys/devices/virtual/graphics/fb%d/hpd",
+                                mHdmiFbNum);
+    int hdmiHPDFile = open(sysFsHPDFilePath,O_RDWR, 0);
     if (hdmiHPDFile < 0) {
-        ALOGE("%s: state file '%s' not found : ret%d"
-                           "err str: %s",  __FUNCTION__, SYSFS_HPD, hdmiHPDFile,
-                           strerror(errno));
+        ALOGE("%s: state file '%s' not found : ret%d err str: %s", __FUNCTION__,
+                                sysFsHPDFilePath, hdmiHPDFile, strerror(errno));
         ret = false;
     } else {
         int err = -1;
-        ALOGD_IF(DEBUG, "%s: option = %d", __FUNCTION__,
-                 userOption);
+        ALOGD_IF(DEBUG, "%s: option = %d", __FUNCTION__, userOption);
         if(userOption)
             err = write(hdmiHPDFile, "1", 2);
         else
             err = write(hdmiHPDFile, "0" , 2);
         if (err <= 0) {
-            ALOGE("%s: file write failed '%s'",
-                     __FUNCTION__, SYSFS_HPD);
+            ALOGE("%s: file write failed '%s'", __FUNCTION__, sysFsHPDFilePath);
             ret = false;
         }
         close(hdmiHPDFile);
@@ -441,25 +543,32 @@
 
 /*
  * commits the changes to the external display
- * mExternalDisplay has the mixer number(1-> HDMI 2-> WFD)
  */
 bool ExternalDisplay::post()
 {
     if(mFd == -1)
         return false;
-
     struct mdp_display_commit ext_commit;
     ext_commit.flags |= MDP_DISPLAY_COMMIT_OVERLAY;
     if (ioctl(mFd, MSMFB_DISPLAY_COMMIT, &ext_commit) == -1) {
-         ALOGE("%s: MSMFB_DISPLAY_COMMIT for external failed, str: %s",
-                                                __FUNCTION__, strerror(errno));
-         return false;
+        ALOGE("%s: MSMFB_DISPLAY_COMMIT for external failed, str: %s",
+                __FUNCTION__, strerror(errno));
+        return false;
     }
-
     return true;
 }
 
-void ExternalDisplay::setDpyAttr() {
+void ExternalDisplay::setDpyWfdAttr() {
+    if(mHwcContext) {
+        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = mVInfo.xres;
+        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = mVInfo.yres;
+        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period =
+                1000000000l /60;
+        ALOGD_IF(DEBUG,"%s: wfd...connected..!",__FUNCTION__);
+    }
+}
+
+void ExternalDisplay::setDpyHdmiAttr() {
     int width = 0, height = 0, fps = 0;
     getAttrForMode(width, height, fps);
     if(mHwcContext) {
@@ -471,8 +580,7 @@
     }
 }
 
-void ExternalDisplay::getAttrForMode(int& width, int& height,
-int& fps) {
+void ExternalDisplay::getAttrForMode(int& width, int& height, int& fps) {
     switch (mCurrentMode) {
         case m640x480p60_4_3:
             width = 640;
@@ -530,4 +638,3 @@
 }
 
 };
-
diff --git a/libexternal/external.h b/libexternal/external.h
index da3ccd5..46c982d 100644
--- a/libexternal/external.h
+++ b/libexternal/external.h
@@ -28,6 +28,7 @@
 
 namespace qhwc {
 
+
 class ExternalDisplay
 {
 public:
@@ -35,37 +36,50 @@
     ~ExternalDisplay();
     int getModeCount() const;
     void getEDIDModes(int *out) const;
-    void setExternalDisplay(int connected);
+    void setExternalDisplay(bool connected, int extFbNum = 0);
+    bool isExternalConnected() { return mConnected;};
     bool post();
     void setHPD(uint32_t startEnd);
     void setEDIDMode(int resMode);
     void setActionSafeDimension(int w, int h);
+    void processUEventOnline(const char *str);
+    void processUEventOffline(const char *str);
 
 private:
     bool readResolution();
-    int parseResolution(char* edidStr, int* edidModes);
+    int  parseResolution(char* edidStr, int* edidModes);
     void setResolution(int ID);
-    bool openFramebuffer();
+    bool openFrameBuffer(int fbNum);
     bool closeFrameBuffer();
     bool writeHPDOption(int userOption) const;
     bool isValidMode(int ID);
     void handleUEvent(char* str, int len);
-    int getModeOrder(int mode);
-    int getBestMode();
+    int  getModeOrder(int mode);
+    int  getBestMode();
     void resetInfo();
-    void setDpyAttr();
+    void setDpyHdmiAttr();
+    void setDpyWfdAttr();
     void getAttrForMode(int& width, int& height, int& fps);
+    void updateExtDispDevFbIndex();
+    int  configureHDMIDisplay();
+    int  configureWFDDisplay();
+    int  teardownHDMIDisplay();
+    int  teardownWFDDisplay();
+    int  getExtFbNum(int &fbNum);
 
     mutable android::Mutex mExtDispLock;
     int mFd;
     int mCurrentMode;
-    int mExternalDisplay;
+    int mConnected;
+    int mConnectedFbNum;
     int mResolutionMode;
     char mEDIDs[128];
     int mEDIDModes[64];
     int mModeCount;
     hwc_context_t *mHwcContext;
     fb_var_screeninfo mVInfo;
+    int mHdmiFbNum;
+    int mWfdFbNum;
 };
 
 }; //qhwc
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 20ac9a5..23ffa42 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -236,6 +236,9 @@
         default:
             return -EINVAL;
     }
+    // Enable HPD here, as during bootup unblank is called
+    // when SF is completely initialized
+    ctx->mExtDisplay->setHPD(1);
 
     if(ret < 0) {
         ALOGE("%s: failed. Dpy=%d, blank=%d : %s",
@@ -451,6 +454,18 @@
     return 0;
 }
 
+void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
+{
+    hwc_context_t* ctx = (hwc_context_t*)(dev);
+    android::String8 buf("");
+    dumpsys_log(buf, "Qualcomm HWC state:\n");
+    dumpsys_log(buf, "  MDPVersion=%d\n", ctx->mMDP.version);
+    dumpsys_log(buf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
+    MDPComp::dump(buf);
+    //XXX: Call Other dump functions
+    strlcpy(buff, buf.string(), buff_len);
+}
+
 static int hwc_device_close(struct hw_device_t *dev)
 {
     if(!dev) {
@@ -487,7 +502,7 @@
         dev->device.blank               = hwc_blank;
         dev->device.query               = hwc_query;
         dev->device.registerProcs       = hwc_registerProcs;
-        dev->device.dump                = NULL;
+        dev->device.dump                = hwc_dump;
         dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
         dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
         *device = &dev->device.common;
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 8616719..4200be9 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -628,5 +628,15 @@
 
      return isMDPCompUsed;
 }
+
+void MDPComp::dump(android::String8& buf)
+{
+    dumpsys_log(buf, "  MDP Composition: ");
+    dumpsys_log(buf, "MDPCompState=%d\n", sMDPCompState);
+    //XXX: Log more info
+
+}
+
+
 }; //namespace
 
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 2821f07..6ff6385 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -82,6 +82,8 @@
     /* draw */
     static bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
 
+    static void dump(android::String8& buf);
+
 private:
     /* set/reset flags for MDPComp */
     static void setMDPCompLayerFlags(hwc_context_t *ctx,
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 89b27aa..78f6788 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (C) 2010 The Android Open Source Project
  * Copyright (C) 2012, The Linux Foundation. All rights reserved.
@@ -31,46 +32,47 @@
 
 #define HWC_UEVENT_THREAD_NAME "hwcUeventThread"
 
-const char* MSMFB_HDMI_NODE = "fb1";
-
 static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
 {
     int vsync = 0;
-    char* hdmi;
     int64_t timestamp = 0;
     const char *str = udata;
 
-    if(!strcasestr(str, "@/devices/virtual/graphics/fb")) {
+    if(!strcasestr(str, "change@/devices/virtual/switch/hdmi") &&
+       !strcasestr(str, "change@/devices/virtual/switch/wfd")) {
         ALOGD_IF(UEVENT_DEBUG, "%s: Not Ext Disp Event ", __FUNCTION__);
         return;
     }
-    hdmi = strcasestr(str, MSMFB_HDMI_NODE);
-    // parse HDMI events
+
+    int connected = -1; // initial value - will be set to  1/0 based on hotplug
+    // parse HDMI/WFD switch state for connect/disconnect
+    // for HDMI:
     // The event will be of the form:
-    // change@/devices/virtual/graphics/fb1 ACTION=change
-    // DEVPATH=/devices/virtual/graphics/fb1
-    // SUBSYSTEM=graphics HDCP_STATE=FAIL MAJOR=29
-    // for now just parsing onlin/offline info is enough
-    if (hdmi) {
-        str = udata;
-        int connected = -1; //some event other than online and offline .. e.g
-        if(!(strncmp(str,"online@",strlen("online@")))) {
+    // change@/devices/virtual/switch/hdmi ACTION=change
+    // SWITCH_STATE=1 or SWITCH_STATE=0
+
+    while(*str) {
+        if (!strncmp(str, "SWITCH_STATE=", strlen("SWITCH_STATE="))) {
+            connected = atoi(str + strlen("SWITCH_STATE="));
             //Disabled until SF calls unblank
             ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
-            connected = 1;
-        } else if(!(strncmp(str,"offline@",strlen("offline@")))) {
-            //Disabled until SF calls unblank
-            ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
-            connected = 0;
+            break;
         }
-        if(connected != -1) { //either we got online or offline
-            ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
-            ctx->mExtDisplay->setExternalDisplay(connected);
-            ALOGD("%s sending hotplug: connected = %d", __FUNCTION__,connected);
-            Locker::Autolock _l(ctx->mExtSetLock); //hwc comp could be on
-            //TODO ideally should be done on "connected" not "online"
-            ctx->proc->hotplug(ctx->proc, HWC_DISPLAY_EXTERNAL, connected);
+        str += strlen(str) + 1;
+        if (str - udata >= len)
+            break;
+    }
+
+    if(connected != -1) { //either we got switch_state connected or disconnect
+        ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
+        if(connected) {
+            ctx->mExtDisplay->processUEventOnline(udata);
+        }else {
+            ctx->mExtDisplay->processUEventOffline(udata);
         }
+        ALOGD("%s sending hotplug: connected = %d", __FUNCTION__, connected);
+        Locker::Autolock _l(ctx->mExtSetLock); //hwc comp could be on
+        ctx->proc->hotplug(ctx->proc, HWC_DISPLAY_EXTERNAL, connected);
     }
 }
 
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 3656971..0ae64da 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -92,22 +92,15 @@
 
     pthread_mutex_destroy(&(ctx->vstate.lock));
     pthread_cond_destroy(&(ctx->vstate.cond));
-
 }
 
-void dumpLayer(hwc_layer_1_t const* l)
+
+void dumpsys_log(android::String8& buf, const char* fmt, ...)
 {
-    ALOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}"
-          ", {%d,%d,%d,%d}",
-          l->compositionType, l->flags, l->handle, l->transform, l->blending,
-          l->sourceCrop.left,
-          l->sourceCrop.top,
-          l->sourceCrop.right,
-          l->sourceCrop.bottom,
-          l->displayFrame.left,
-          l->displayFrame.top,
-          l->displayFrame.right,
-          l->displayFrame.bottom);
+    va_list varargs;
+    va_start(varargs, fmt);
+    buf.appendFormatV(fmt, varargs);
+    va_end(varargs);
 }
 
 static inline bool isAlphaScaled(hwc_layer_1_t const* layer) {
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index a7de804..256b840 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -23,6 +23,7 @@
 #include <hardware/hwcomposer.h>
 #include <gr.h>
 #include <gralloc_priv.h>
+#include <utils/String8.h>
 
 #define ALIGN_TO(x, align)     (((x) + ((align)-1)) & ~((align)-1))
 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
@@ -125,6 +126,9 @@
 bool isSecuring(hwc_context_t* ctx);
 bool isExternalActive(hwc_context_t* ctx);
 
+//Helper function to dump logs
+void dumpsys_log(android::String8& buf, const char* fmt, ...);
+
 //Sync point impl.
 int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy);
 
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 7b7719c..04deee5 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -220,6 +220,7 @@
 }
 
 Overlay* Overlay::sInstance = 0;
+int Overlay::sExtFbIndex = 1;
 int Overlay::PipeBook::NUM_PIPES = 0;
 int Overlay::PipeBook::sPipeUsageBitmap = 0;
 int Overlay::PipeBook::sLastUsageBitmap = 0;
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 523e3f7..2378889 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -31,6 +31,7 @@
 #define OVERLAY_H
 
 #include "overlayUtils.h"
+#include "utils/threads.h"
 
 namespace overlay {
 class GenericPipe;
@@ -72,6 +73,10 @@
     static Overlay* getInstance();
     /* Returns total of available ("unallocated") pipes */
     static int availablePipes();
+    /* set the framebuffer index for external display */
+    void setExtFbNum(int fbNum);
+    /* Returns framebuffer index of the current external display */
+    int getExtFbNum();
 
 private:
     /* Ctor setup */
@@ -130,8 +135,11 @@
     /* Dump string */
     char mDumpStr[256];
 
+    mutable android::Mutex mOvExtFbLock;
+
     /* Singleton Instance*/
     static Overlay *sInstance;
+    static int sExtFbIndex;
 };
 
 inline void Overlay::validate(int index) {
@@ -145,6 +153,16 @@
     return PipeBook::availablePipes();
 }
 
+inline void Overlay::setExtFbNum(int fbNum) {
+    android::Mutex::Autolock lock(mOvExtFbLock);
+    sExtFbIndex = fbNum;
+}
+
+inline int Overlay::getExtFbNum() {
+    android::Mutex::Autolock lock(mOvExtFbLock);
+    return sExtFbIndex;
+}
+
 inline int Overlay::PipeBook::availablePipes() {
     int used = 0;
     int bmp = sAllocatedBitmap;
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index 207531a..d0f9457 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -153,44 +153,47 @@
 
 /* clears any VG pipes allocated to the fb devices */
 int initOverlay() {
-    msmfb_mixer_info_req  req;
-    mdp_mixer_info *minfo = NULL;
-    char name[64];
-    int fd = -1;
-    for(int i = 0; i < NUM_FB_DEVICES; i++) {
-        snprintf(name, 64, FB_DEVICE_TEMPLATE, i);
-        ALOGD("initoverlay:: opening the device:: %s", name);
-        fd = ::open(name, O_RDWR, 0);
-        if(fd < 0) {
-            ALOGE("cannot open framebuffer(%d)", i);
-            return -1;
-        }
-        //Get the mixer configuration */
-        req.mixer_num = i;
-        if (ioctl(fd, MSMFB_MIXER_INFO, &req) == -1) {
-            ALOGE("ERROR: MSMFB_MIXER_INFO ioctl failed");
-            close(fd);
-            return -1;
-        }
-        minfo = req.info;
-        for (int j = 0; j < req.cnt; j++) {
-            ALOGD("ndx=%d num=%d z_order=%d", minfo->pndx, minfo->pnum,
-                    minfo->z_order);
-            // except the RGB base layer with z_order of -1, clear any
-            // other pipes connected to mixer.
-            if((minfo->z_order) != -1) {
-                int index = minfo->pndx;
-                ALOGD("Unset overlay with index: %d at mixer %d", index, i);
-                if(ioctl(fd, MSMFB_OVERLAY_UNSET, &index) == -1) {
-                    ALOGE("ERROR: MSMFB_OVERLAY_UNSET failed");
-                    close(fd);
-                    return -1;
-                }
+    int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
+    if (mdpVersion < qdutils::MDSS_V5) {
+        msmfb_mixer_info_req  req;
+        mdp_mixer_info *minfo = NULL;
+        char name[64];
+        int fd = -1;
+        for(int i = 0; i < NUM_FB_DEVICES; i++) {
+            snprintf(name, 64, FB_DEVICE_TEMPLATE, i);
+            ALOGD("initoverlay:: opening the device:: %s", name);
+            fd = ::open(name, O_RDWR, 0);
+            if(fd < 0) {
+                ALOGE("cannot open framebuffer(%d)", i);
+                return -1;
             }
-            minfo++;
+            //Get the mixer configuration */
+            req.mixer_num = i;
+            if (ioctl(fd, MSMFB_MIXER_INFO, &req) == -1) {
+                ALOGE("ERROR: MSMFB_MIXER_INFO ioctl failed");
+                close(fd);
+                return -1;
+            }
+            minfo = req.info;
+            for (int j = 0; j < req.cnt; j++) {
+                ALOGD("ndx=%d num=%d z_order=%d", minfo->pndx, minfo->pnum,
+                      minfo->z_order);
+                // except the RGB base layer with z_order of -1, clear any
+                // other pipes connected to mixer.
+                if((minfo->z_order) != -1) {
+                    int index = minfo->pndx;
+                    ALOGD("Unset overlay with index: %d at mixer %d", index, i);
+                    if(ioctl(fd, MSMFB_OVERLAY_UNSET, &index) == -1) {
+                        ALOGE("ERROR: MSMFB_OVERLAY_UNSET failed");
+                        close(fd);
+                        return -1;
+                    }
+                }
+                minfo++;
+            }
+            close(fd);
+            fd = -1;
         }
-        close(fd);
-        fd = -1;
     }
     return 0;
 }
diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp
index ecb3b16..9f08c14 100644
--- a/liboverlay/pipes/overlayGenPipe.cpp
+++ b/liboverlay/pipes/overlayGenPipe.cpp
@@ -28,6 +28,7 @@
 */
 
 #include "overlayGenPipe.h"
+#include "overlay.h"
 
 namespace overlay {
 
@@ -44,6 +45,10 @@
 {
     ALOGE_IF(DEBUG_OVERLAY, "GenericPipe init");
     mRotUsed = false;
+    if(mFbNum)
+        mFbNum = Overlay::getInstance()->getExtFbNum();
+
+    ALOGD_IF(DEBUG_OVERLAY,"%s: mFbNum:%d",__FUNCTION__, mFbNum);
 
     if(!mCtrlData.ctrl.init(mFbNum)) {
         ALOGE("GenericPipe failed to init ctrl");