Merge "hwc: Fix swap interval zero"
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index 84d7620..2302d64 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -37,6 +37,7 @@
 
 #include "gralloc_priv.h"
 #include "software_converter.h"
+#include <qdMetaData.h>
 
 #define DEBUG_MDP_ERRORS 1
 
@@ -504,6 +505,13 @@
                 flags |=  MDP_BLIT_NON_CACHED;
             }
 
+            // Set Color Space for MDP to configure CSC matrix
+            req->color_space = ITU_R_601;
+            MetaData_t *metadata = (MetaData_t *)src_hnd->base_metadata;
+            if (metadata && (metadata->operation & UPDATE_COLOR_SPACE)) {
+                req->color_space = metadata->colorSpace;
+            }
+
             set_infos(ctx, req, flags);
             set_image(&req->dst, dst);
             set_image(&req->src, src);
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 5ba737a..943e64f 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -63,12 +63,15 @@
         return -EINVAL;
 
     private_handle_t* hnd = (private_handle_t*)handle;
+    unsigned int size = 0;
+    int err = 0;
+    IMemAlloc* memalloc = getAllocator(hnd->flags) ;
     void *mappedAddress;
+    // Dont map FRAMEBUFFER and SECURE_BUFFERS
     if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
         !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) {
-        unsigned int size = hnd->size;
-        IMemAlloc* memalloc = getAllocator(hnd->flags) ;
-        int err = memalloc->map_buffer(&mappedAddress, size,
+        size = hnd->size;
+        err = memalloc->map_buffer(&mappedAddress, size,
                                        hnd->offset, hnd->fd);
         if(err || mappedAddress == MAP_FAILED) {
             ALOGE("Could not mmap handle %p, fd=%d (%s)",
@@ -78,6 +81,10 @@
         }
 
         hnd->base = uint64_t(mappedAddress) + hnd->offset;
+    }
+
+    //Allow mapping of metadata for all buffers and SECURE_BUFFER
+    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
         mappedAddress = MAP_FAILED;
         size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
         err = memalloc->map_buffer(&mappedAddress, size,
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 8164fd3..67cca88 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -96,7 +96,7 @@
         int fbWidth =  ctx->dpyAttr[dpy].xres;
         int fbHeight =  ctx->dpyAttr[dpy].yres;
         unsigned int fbArea = (fbWidth * fbHeight);
-        unsigned int renderArea = getRGBRenderingArea(list);
+        unsigned int renderArea = getRGBRenderingArea(ctx, list);
             ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u",
                                   __FUNCTION__, renderArea, fbArea);
         if (renderArea < (mDynThreshold * fbArea)) {
@@ -112,8 +112,8 @@
     return false;
 }
 
-unsigned int CopyBit::getRGBRenderingArea
-                                    (const hwc_display_contents_1_t *list) {
+unsigned int CopyBit::getRGBRenderingArea (const hwc_context_t *ctx,
+                                     const hwc_display_contents_1_t *list) {
     //Calculates total rendering area for RGB layers
     unsigned int renderArea = 0;
     unsigned int w=0, h=0;
@@ -122,7 +122,7 @@
     for (unsigned int i=0; i<list->numHwLayers -1; i++) {
          private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
          if (hnd) {
-             if (BUFFER_TYPE_UI == hnd->bufferType) {
+             if (BUFFER_TYPE_UI == hnd->bufferType && !ctx->copybitDrop[i]) {
                  getLayerResolution(&list->hwLayers[i], w, h);
                  renderArea += (w*h);
              }
@@ -316,6 +316,9 @@
         for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
             int dst_h, dst_w, src_h, src_w;
             float dx, dy;
+            if(ctx->copybitDrop[i]) {
+                continue;
+            }
             hwc_layer_1_t *layer = (hwc_layer_1_t *) &list->hwLayers[i];
             if (layer->planeAlpha != 0xFF)
                 return true;
@@ -349,7 +352,8 @@
     }
 
     //Allocate render buffers if they're not allocated
-    if (ctx->mMDP.version != qdutils::MDP_V3_0_4 &&
+    if ((ctx->mMDP.version != qdutils::MDP_V3_0_4 &&
+        ctx->mMDP.version != qdutils::MDP_V3_0_5) &&
             (useCopybitForYUV || useCopybitForRGB)) {
         int ret = allocRenderBuffers(mAlignedWidth,
                                      mAlignedHeight,
@@ -375,7 +379,8 @@
         for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
             layerProp[i].mFlags |= HWC_COPYBIT;
 #ifdef QCOM_BSP
-            if (ctx->mMDP.version == qdutils::MDP_V3_0_4)
+            if (ctx->mMDP.version == qdutils::MDP_V3_0_4 ||
+               ctx->mMDP.version == qdutils::MDP_V3_0_5)
                 list->hwLayers[i].compositionType = HWC_BLIT;
             else
 #endif
@@ -496,7 +501,8 @@
        return true;
     }
     //render buffer
-    if (ctx->mMDP.version == qdutils::MDP_V3_0_4) {
+    if (ctx->mMDP.version == qdutils::MDP_V3_0_4 ||
+        ctx->mMDP.version == qdutils::MDP_V3_0_5) {
         last = (uint32_t)list->numHwLayers - 1;
         renderBuffer = (private_handle_t *)list->hwLayers[last].handle;
     } else {
@@ -541,6 +547,9 @@
             ALOGD_IF(DEBUG_COPYBIT, "%s: Not Marked for copybit", __FUNCTION__);
             continue;
         }
+        if(ctx->copybitDrop[i]) {
+            continue;
+        }
         //skip non updating layers
         if((mDirtyLayerIndex != -1) && (mDirtyLayerIndex != i) )
             continue;
@@ -568,7 +577,8 @@
         copybit_device_t *copybit = getCopyBitDevice();
         // Async mode
         copybit->flush_get_fence(copybit, fd);
-        if(ctx->mMDP.version == qdutils::MDP_V3_0_4 &&
+        if((ctx->mMDP.version == qdutils::MDP_V3_0_4 ||
+           ctx->mMDP.version == qdutils::MDP_V3_0_5) &&
                 list->hwLayers[last].acquireFenceFd >= 0) {
             close(list->hwLayers[last].acquireFenceFd);
             list->hwLayers[last].acquireFenceFd = -1;
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 99a39c8..a7ce43e 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -101,8 +101,8 @@
     // flag that indicates whether CopyBit composition is enabled for this cycle
     bool mCopyBitDraw;
 
-    unsigned int getRGBRenderingArea
-                            (const hwc_display_contents_1_t *list);
+    unsigned int getRGBRenderingArea (const hwc_context_t *ctx,
+                                         const hwc_display_contents_1_t *list);
 
     void getLayerResolution(const hwc_layer_1_t* layer,
                                    unsigned int &width, unsigned int& height);
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index bf764e6..aed9e3c 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -46,6 +46,7 @@
 int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
 bool MDPComp::sEnableYUVsplit = false;
 bool MDPComp::sSrcSplitEnabled = false;
+bool MDPComp::enablePartialUpdateForMDP3 = false;
 MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
     if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
         sSrcSplitEnabled = true;
@@ -149,13 +150,32 @@
         sEnableYUVsplit = true;
     }
 
-    if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
-            ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
-             (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
+    bool defaultPTOR = false;
+    //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
+    //8x16 and 8x39 targets by default
+    if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
+            (qdutils::MDPVersion::getInstance().is8x16() ||
+                qdutils::MDPVersion::getInstance().is8x39())) {
+        defaultPTOR = true;
+    }
+
+    if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
+                (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
         ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
                                                     HWC_DISPLAY_PRIMARY);
     }
 
+    if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
+          (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
+       enablePartialUpdateForMDP3 = true;
+    }
+
+    if(!enablePartialUpdateForMDP3 &&
+          (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+           (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+       enablePartialUpdateForMDP3 = true;
+    }
+
     return true;
 }
 
@@ -1870,6 +1890,13 @@
                     "MDP Composition Strategies Failed");
         }
     } else {
+        if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
+                enablePartialUpdateForMDP3) {
+            generateROI(ctx, list);
+            for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
+                ctx->copybitDrop[i] = mCurrentFrame.drop[i];
+            }
+        }
         ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
                 __FUNCTION__);
         ret = -1;
@@ -1888,6 +1915,8 @@
     if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
         FrameInfo frame;
         frame.reset(mCurrentFrame.layerCount);
+        memset(&frame.drop, 0, sizeof(frame.drop));
+        frame.dropCount = 0;
         ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
                  __FUNCTION__);
         updateLayerCache(ctx, list, frame);
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 268e9aa..3ed9186 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -262,6 +262,8 @@
     static bool sEnableYUVsplit;
     bool mModeOn; // if prepare happened
     bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index);
+    //Enable Partial Update for MDP3 targets
+    static bool enablePartialUpdateForMDP3;
 };
 
 class MDPCompNonSplit : public MDPComp {
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 65e041b..6b2316b 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -107,10 +107,11 @@
                 break;
             }
 
-            Locker::Autolock _l(ctx->mDrawLock);
+            ctx->mDrawLock.lock();
             destroyCompositionResources(ctx, dpy);
             ctx->mHDMIDisplay->teardown();
             resetDisplayInfo(ctx, dpy);
+            ctx->mDrawLock.unlock();
 
             /* We need to send hotplug to SF only when we are disconnecting
              * HDMI */
@@ -127,19 +128,19 @@
                          "for display: %d", __FUNCTION__, dpy);
                 break;
             }
-            {
-                //Force composition to give up resources like pipes and
-                //close fb. For example if assertive display is going on,
-                //fb2 could be open, thus connecting Layer Mixer#0 to
-                //WriteBack module. If HDMI attempts to open fb1, the driver
-                //will try to attach Layer Mixer#0 to HDMI INT, which will
-                //fail, since Layer Mixer#0 is still connected to WriteBack.
-                //This block will force composition to close fb2 in above
-                //example.
-                Locker::Autolock _l(ctx->mDrawLock);
-                ctx->dpyAttr[dpy].isConfiguring = true;
-                ctx->proc->invalidate(ctx->proc);
-            }
+            ctx->mDrawLock.lock();
+            //Force composition to give up resources like pipes and
+            //close fb. For example if assertive display is going on,
+            //fb2 could be open, thus connecting Layer Mixer#0 to
+            //WriteBack module. If HDMI attempts to open fb1, the driver
+            //will try to attach Layer Mixer#0 to HDMI INT, which will
+            //fail, since Layer Mixer#0 is still connected to WriteBack.
+            //This block will force composition to close fb2 in above
+            //example.
+            ctx->dpyAttr[dpy].isConfiguring = true;
+            ctx->mDrawLock.unlock();
+
+            ctx->proc->invalidate(ctx->proc);
             //2 cycles for slower content
             usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
                    * 2 / 1000);
@@ -166,12 +167,13 @@
             ctx->mHDMIDisplay->configure();
             ctx->mHDMIDisplay->activateDisplay();
 
-            Locker::Autolock _l(ctx->mDrawLock);
+            ctx->mDrawLock.lock();
             updateDisplayInfo(ctx, dpy);
             initCompositionResources(ctx, dpy);
             ctx->dpyAttr[dpy].isPause = false;
             ctx->dpyAttr[dpy].connected = true;
             ctx->dpyAttr[dpy].isConfiguring = true;
+            ctx->mDrawLock.unlock();
 
             /* External display is HDMI */
             ALOGE_IF(UEVENT_DEBUG, "%s: Sending EXTERNAL ONLINE"
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 997af75..e7e6535 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -283,8 +283,10 @@
     // Only MDP copybit is used
     if ((compositionType & (qdutils::COMPOSITION_TYPE_DYN |
             qdutils::COMPOSITION_TYPE_MDP)) &&
+            ((qdutils::MDPVersion::getInstance().getMDPVersion() ==
+            qdutils::MDP_V3_0_4) ||
             (qdutils::MDPVersion::getInstance().getMDPVersion() ==
-            qdutils::MDP_V3_0_4)) {
+            qdutils::MDP_V3_0_5))) {
         ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
                                                          HWC_DISPLAY_PRIMARY);
     }
@@ -2191,7 +2193,8 @@
         if(dpy == HWC_DISPLAY_PRIMARY)
             return false;
     }
-    if(ctx->mMDP.version == qdutils::MDP_V3_0_4)
+    if((ctx->mMDP.version == qdutils::MDP_V3_0_4)
+          ||(ctx->mMDP.version == qdutils::MDP_V3_0_5))
         return false;
     return true;
 }
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index cae22f1..3d97319 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -596,6 +596,8 @@
     qhwc::PtorInfo mPtorInfo;
     //Running in Thermal burst mode
     bool mThermalBurstMode;
+    //Layers out of ROI
+    bool copybitDrop[MAX_NUM_APP_LAYERS];
 };
 
 namespace qhwc {
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 85c9b78..96c057f 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -387,7 +387,7 @@
         }
     }
 
-    if (mdpVersion < qdutils::MDSS_V5 && mdpVersion != qdutils::MDP_V3_0_4) {
+    if (mdpVersion < qdutils::MDSS_V5 && mdpVersion > qdutils::MDP_V3_0_5) {
         msmfb_mixer_info_req  req;
         mdp_mixer_info *minfo = NULL;
         char name[64];
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index ddc40ee..b8bb33e 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -218,6 +218,13 @@
 
 bool MdpCtrl::setVisualParams(const MetaData_t& data) {
     ALOGD_IF(0, "In %s: data.operation = %d", __FUNCTION__, data.operation);
+
+    // Set Color Space for MDP to configure CSC matrix
+    mOVInfo.color_space = ITU_R_601;
+    if (data.operation & UPDATE_COLOR_SPACE) {
+        mOVInfo.color_space = data.colorSpace;
+    }
+
 #ifdef USES_POST_PROCESSING
     bool needUpdate = false;
     /* calculate the data */
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index de94591..88109c9 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -90,6 +90,9 @@
         case UPDATE_COLOR_SPACE:
             data->colorSpace = *((ColorSpace_t *)param);
             break;
+        case MAP_SECURE_BUFFER:
+            data->mapSecureBuffer = *((int32_t *)param);
+            break;
         default:
             ALOGE("Unknown paramType %d", paramType);
             break;
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index a71ee8b..32d788e 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -79,6 +79,13 @@
     int64_t timestamp;
     uint32_t refreshrate;
     enum ColorSpace_t colorSpace;
+     /* Gralloc sets PRIV_SECURE_BUFFER flag to inform that the buffers are from
+      * ION_SECURE. which should not be mapped. However, for GPU post proc
+      * feature, GFX needs to map this buffer, in the client context and in SF
+      * context, it should not. Hence to differentiate, add this metadata field
+      * for clients to set, and GPU will to read and know when to map the
+      * SECURE_BUFFER(ION) */
+    int32_t mapSecureBuffer;
 };
 
 enum DispParamType {
@@ -92,6 +99,7 @@
     UPDATE_BUFFER_GEOMETRY = 0x0080,
     UPDATE_REFRESH_RATE = 0x0100,
     UPDATE_COLOR_SPACE = 0x0200,
+    MAP_SECURE_BUFFER = 0x400,
 };
 
 struct private_handle_t;