Merge "libgralloc: Don't pad if debug.gralloc.map_fb_memory is set"
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 703a2e6..0e7576e 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -103,6 +103,23 @@
             }
         }
 
+        if (bufferType == BUFFER_TYPE_VIDEO) {
+            if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
+                if ((qdutils::MDPVersion::getInstance().getMDPVersion() <
+                     qdutils::MDSS_V5)) { //A-Family
+                    flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
+                } else {
+                    if (usage & (GRALLOC_USAGE_HW_TEXTURE |
+                                 GRALLOC_USAGE_HW_VIDEO_ENCODER))
+                        flags |= private_handle_t::PRIV_FLAGS_ITU_R_709;
+                    else if (usage & GRALLOC_USAGE_HW_CAMERA_ZSL)
+                        flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
+                }
+            } else {
+                flags |= private_handle_t::PRIV_FLAGS_ITU_R_601;
+            }
+        }
+
         if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER ) {
             flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
         }
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 511e81f..08d95be 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -159,6 +159,9 @@
             PRIV_FLAGS_CAMERA_READ        = 0x00040000,
             PRIV_FLAGS_HW_COMPOSER        = 0x00080000,
             PRIV_FLAGS_HW_TEXTURE         = 0x00100000,
+            PRIV_FLAGS_ITU_R_601          = 0x00200000,
+            PRIV_FLAGS_ITU_R_601_FR       = 0x00400000,
+            PRIV_FLAGS_ITU_R_709          = 0x00800000,
         };
 
         // file-descriptors
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index f7bb192..7398295 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -158,7 +158,9 @@
 
 static int hwc_prepare_external(hwc_composer_device_1 *dev,
         hwc_display_contents_1_t *list, int dpy) {
+
     hwc_context_t* ctx = (hwc_context_t*)(dev);
+    Locker::Autolock _l(ctx->mExtLock);
 
     if (LIKELY(list && list->numHwLayers > 1) &&
             ctx->dpyAttr[dpy].isActive &&
@@ -399,7 +401,7 @@
 {
     ATRACE_CALL();
     int ret = 0;
-    Locker::Autolock _l(ctx->mExtSetLock);
+    Locker::Autolock _l(ctx->mExtLock);
 
     if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
         !ctx->dpyAttr[dpy].isPause &&
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 3d351d0..8ccf362 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -84,11 +84,6 @@
         return false;
     }
 
-    if(!setupBasePipe(ctx)) {
-        ALOGE("%s: Failed to setup primary base pipe", __FUNCTION__);
-        return false;
-    }
-
     char property[PROPERTY_VALUE_MAX];
 
     sEnabled = false;
@@ -96,6 +91,10 @@
        (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
         (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
         sEnabled = true;
+        if(!setupBasePipe(ctx)) {
+            ALOGE("%s: Failed to setup primary base pipe", __FUNCTION__);
+            return false;
+        }
     }
 
     sDebugLogs = false;
@@ -803,52 +802,23 @@
 }
 
 bool MDPCompLowRes::allocLayerPipes(hwc_context_t *ctx,
-                                    hwc_display_contents_1_t* list) {
-    if(isYuvPresent(ctx, mDpy)) {
-        int nYuvCount = ctx->listStats[mDpy].yuvCount;
+        hwc_display_contents_1_t* list) {
+    for(int index = 0; index < mCurrentFrame.layerCount; index++) {
 
-        for(int index = 0; index < nYuvCount ; index ++) {
-            int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
-
-            if(mCurrentFrame.isFBComposed[nYuvIndex])
-                continue;
-
-            hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
-
-            int mdpIndex = mCurrentFrame.layerToMDP[nYuvIndex];
-
-            PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
-            info.pipeInfo = new MdpPipeInfoLowRes;
-            info.rot = NULL;
-            MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo;
-
-            pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG);
-            if(pipe_info.index == ovutils::OV_INVALID) {
-                ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos",
-                         __FUNCTION__);
-                return false;
-            }
-        }
-    }
-
-    for(int index = 0 ; index < mCurrentFrame.layerCount; index++ ) {
         if(mCurrentFrame.isFBComposed[index]) continue;
+
         hwc_layer_1_t* layer = &list->hwLayers[index];
         private_handle_t *hnd = (private_handle_t *)layer->handle;
-
-        if(isYuvBuffer(hnd))
-            continue;
-
         int mdpIndex = mCurrentFrame.layerToMDP[index];
-
         PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
         info.pipeInfo = new MdpPipeInfoLowRes;
         info.rot = NULL;
         MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo;
-
         ePipeType type = MDPCOMP_OV_ANY;
 
-        if(!qhwc::needsScaling(layer)
+        if(isYuvBuffer(hnd)) {
+            type = MDPCOMP_OV_VG;
+        } else if(!qhwc::needsScaling(layer)
             && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
             && ctx->mMDP.version >= qdutils::MDSS_V5) {
             type = MDPCOMP_OV_DMA;
@@ -856,7 +826,8 @@
 
         pipe_info.index = getMdpPipe(ctx, type);
         if(pipe_info.index == ovutils::OV_INVALID) {
-            ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
+            ALOGD_IF(isDebug(), "%s: Unable to get pipe type = %d",
+                __FUNCTION__, (int) type);
             return false;
         }
     }
@@ -982,55 +953,32 @@
 }
 
 bool MDPCompHighRes::allocLayerPipes(hwc_context_t *ctx,
-                                     hwc_display_contents_1_t* list) {
-    overlay::Overlay& ov = *ctx->mOverlay;
-    int layer_count = ctx->listStats[mDpy].numAppLayers;
+        hwc_display_contents_1_t* list) {
+    for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
 
-    if(isYuvPresent(ctx, mDpy)) {
-        int nYuvCount = ctx->listStats[mDpy].yuvCount;
+        if(mCurrentFrame.isFBComposed[index]) continue;
 
-        for(int index = 0; index < nYuvCount; index ++) {
-            int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
-            hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
-            PipeLayerPair& info = mCurrentFrame.mdpToLayer[nYuvIndex];
-            info.pipeInfo = new MdpPipeInfoHighRes;
-            info.rot = NULL;
-            MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo;
-            if(!acquireMDPPipes(ctx, layer, pipe_info,MDPCOMP_OV_VG)) {
-                ALOGD_IF(isDebug(),"%s: Unable to get pipe for videos",
-                         __FUNCTION__);
-                //TODO: windback pipebook data on fail
-                return false;
-            }
-            pipe_info.zOrder = nYuvIndex;
-        }
-    }
-
-    for(int index = 0 ; index < layer_count ; index++ ) {
         hwc_layer_1_t* layer = &list->hwLayers[index];
         private_handle_t *hnd = (private_handle_t *)layer->handle;
-
-        if(isYuvBuffer(hnd))
-            continue;
-
         PipeLayerPair& info = mCurrentFrame.mdpToLayer[index];
         info.pipeInfo = new MdpPipeInfoHighRes;
         info.rot = NULL;
         MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo;
-
         ePipeType type = MDPCOMP_OV_ANY;
 
-        if(!qhwc::needsScaling(layer)
+        if(isYuvBuffer(hnd)) {
+            type = MDPCOMP_OV_VG;
+        } else if(!qhwc::needsScaling(layer)
             && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
-            && ctx->mMDP.version >= qdutils::MDSS_V5)
+            && ctx->mMDP.version >= qdutils::MDSS_V5) {
             type = MDPCOMP_OV_DMA;
+        }
 
         if(!acquireMDPPipes(ctx, layer, pipe_info, type)) {
-            ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
-            //TODO: windback pipebook data on fail
+            ALOGD_IF(isDebug(), "%s: Unable to get pipe for type = %d",
+                    __FUNCTION__, (int) type);
             return false;
         }
-        pipe_info.zOrder = index;
     }
     return true;
 }
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index eb525a6..b314317 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -148,7 +148,7 @@
                 }else if(!strncmp(s1,"wfd",strlen(s1))) {
                     ctx->mExtDisplay->teardownWFDDisplay();
                 }
-                Locker::Autolock _l(ctx->mExtSetLock);
+                Locker::Autolock _l(ctx->mExtLock);
                 clear(ctx, dpy);
                 ALOGD("%s sending hotplug: connected = %d and dpy:%d",
                       __FUNCTION__, connected, dpy);
@@ -170,7 +170,7 @@
                         // teardown Active WFD Display
                         ctx->mExtDisplay->teardownWFDDisplay();
                         {
-                            Locker::Autolock _l(ctx->mExtSetLock);
+                            Locker::Autolock _l(ctx->mExtLock);
                             clear(ctx, dpy);
                             //send hotplug disconnect event
                             ALOGD_IF(UEVENT_DEBUG, "sending hotplug: disconnect"
@@ -195,7 +195,7 @@
                 ALOGD("%s sending hotplug: connected = %d", __FUNCTION__,
                         connected);
                 ctx->dpyAttr[dpy].connected = true;
-                Locker::Autolock _l(ctx->mExtSetLock); //hwc comp could be on
+                Locker::Autolock _l(ctx->mExtLock); //hwc comp could be on
                 ctx->proc->hotplug(ctx->proc, dpy, connected);
                 break;
             }
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index ca6136a..a310679 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -325,6 +325,7 @@
     ctx->listStats[dpy].needsAlphaScale = false;
     ctx->listStats[dpy].preMultipliedAlpha = false;
     ctx->listStats[dpy].yuvCount = 0;
+    char property[PROPERTY_VALUE_MAX];
 
     for (size_t i = 0; i < list->numHwLayers; i++) {
         hwc_layer_1_t const* layer = &list->hwLayers[i];
@@ -356,6 +357,19 @@
         if(!ctx->listStats[dpy].needsAlphaScale)
             ctx->listStats[dpy].needsAlphaScale = isAlphaScaled(layer);
     }
+    if(ctx->listStats[dpy].yuvCount > 0) {
+        if (property_get("hw.cabl.yuv", property, NULL) > 0) {
+            if (atoi(property) != 1) {
+                property_set("hw.cabl.yuv", "1");
+            }
+        }
+    } else {
+        if (property_get("hw.cabl.yuv", property, NULL) > 0) {
+            if (atoi(property) != 0) {
+                property_set("hw.cabl.yuv", "0");
+            }
+        }
+    }
 }
 
 
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index e0fff77..6e95703 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -269,8 +269,8 @@
     bool mSecureMode;
     //Lock to prevent set from being called while blanking
     mutable Locker mBlankLock;
-    //Lock to protect set when detaching external disp
-    mutable Locker mExtSetLock;
+    //Lock to protect prepare & set when detaching external disp
+    mutable Locker mExtLock;
     //Vsync
     struct vsync_state vstate;
     //Drawing round when we use GPU
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 8aca0f6..97905d5 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -243,7 +243,7 @@
         }
     }
 
-    if (mdpVersion < qdutils::MDSS_V5) {
+    if (mdpVersion < qdutils::MDSS_V5 && mdpVersion != qdutils::MDP_V3_0_4) {
         msmfb_mixer_info_req  req;
         mdp_mixer_info *minfo = NULL;
         char name[64];
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index e3e78ca..86e744d 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -85,6 +85,9 @@
                 mVGPipes = metadata.data.caps.vig_pipes;
                 mDMAPipes = metadata.data.caps.dma_pipes;
                 mFeatures = metadata.data.caps.features;
+                if (metadata.data.caps.mdp_rev == MDP_V3_0_4){
+                    mdp_version = MDP_V3_0_4;
+                }
             }
 #endif
         } else {
@@ -99,7 +102,9 @@
     close(fb_fd);
     mMDPVersion = mdp_version;
     mHasOverlay = false;
-    if((mMDPVersion >= MDP_V4_0) || (mMDPVersion == MDP_V_UNKNOWN))
+    if((mMDPVersion >= MDP_V4_0) ||
+       (mMDPVersion == MDP_V_UNKNOWN) ||
+       (mMDPVersion == MDP_V3_0_4))
         mHasOverlay = true;
     if(mMDPVersion >= MDSS_V5) {
         //TODO get this from driver
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index 0586001..c34c0a4 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -43,6 +43,7 @@
     MDP_V2_2    = 220,
     MDP_V3_0    = 300,
     MDP_V3_0_3  = 303,
+    MDP_V3_0_4  = 304,
     MDP_V3_1    = 310,
     MDP_V4_0    = 400,
     MDP_V4_1    = 410,
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index cc7e44a..1316e59 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -75,6 +75,9 @@
         case PP_PARAM_SHARP2:
             memcpy((void *)&data->Sharp2Data, param, sizeof(Sharp2Data_t));
             break;
+        case PP_PARAM_TIMESTAMP:
+            data->timestamp = *((int64_t *)param);
+            break;
         default:
             ALOGE("Unknown paramType %d", paramType);
             break;
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index bbca4b6..9f10cf8 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -60,6 +60,7 @@
     int32_t video_interface;
     IGCData_t igcData;
     Sharp2Data_t Sharp2Data;
+    int64_t timestamp;
 };
 
 typedef enum {
@@ -69,6 +70,7 @@
     PP_PARAM_VID_INTFC  = 0x0008,
     PP_PARAM_IGC        = 0x0010,
     PP_PARAM_SHARP2     = 0x0020,
+    PP_PARAM_TIMESTAMP  = 0x0040
 } DispParamType;
 
 int setMetaData(private_handle_t *handle, DispParamType paramType, void *param);