Merge "libgralloc: Add support to use CAMERA_HEAP"
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 6dbc42f..46acd56 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -182,6 +182,12 @@
 IonController::IonController()
 {
     mIonAlloc = new IonAlloc();
+    mUseTZProtection = false;
+    char property[PROPERTY_VALUE_MAX];
+    if ((property_get("persist.gralloc.cp.level3", property, NULL) <= 0) ||
+                            (atoi(property) != 1)) {
+        mUseTZProtection = true;
+    }
 }
 
 int IonController::allocate(alloc_data& data, int usage)
@@ -201,20 +207,22 @@
     if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
         ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
 
-    //MM Heap is exclusively a secure heap.
-    if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
-        //XXX: Right now the MM heap is the only secure heap we have. When we
-        //have other secure heaps, we can change this.
-        if(usage & GRALLOC_USAGE_PROTECTED) {
+    if(usage & GRALLOC_USAGE_PROTECTED) {
+        if ((mUseTZProtection) && (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP)) {
             ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
             ionFlags |= ION_SECURE;
-        }
-        else {
-            ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
-                  cannot be used as an insecure heap!\
-                  trying to use IOMMU instead !!");
+        } else {
+            // for targets/OEMs which do not need HW level protection
+            // do not set ion secure flag & MM heap. Fallback to IOMMU heap.
             ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
         }
+    } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
+        //MM Heap is exclusively a secure heap.
+        //If it is used for non secure cases, fallback to IOMMU heap
+        ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
+                                cannot be used as an insecure heap!\
+                                trying to use IOMMU instead !!");
+        ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
     }
 
     if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
@@ -223,7 +231,7 @@
     if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
         ionFlags |= ION_HEAP(ION_ADSP_HEAP_ID);
 
-    if(usage & GRALLOC_USAGE_PROTECTED)
+    if(ionFlags & ION_SECURE)
          data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
 
     // if no flags are set, default to
diff --git a/libgralloc/alloc_controller.h b/libgralloc/alloc_controller.h
index 5fe81fa..8954d39 100644
--- a/libgralloc/alloc_controller.h
+++ b/libgralloc/alloc_controller.h
@@ -65,6 +65,7 @@
 
     private:
     IonAlloc* mIonAlloc;
+    bool mUseTZProtection;
 
 };
 } //end namespace gralloc
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index a2ccb12..e812c01 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -252,6 +252,7 @@
             ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
                       (enable)?"ENABLED":"DISABLED");
             break;
+#ifdef QCOM_BSP
         case  HWC_EVENT_ORIENTATION:
             if(dpy == HWC_DISPLAY_PRIMARY) {
                 // store the primary display orientation
@@ -260,6 +261,7 @@
                 ctx->deviceOrientation = enable;
             }
             break;
+#endif
         default:
             ret = -EINVAL;
     }
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 23eed45..8589204 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -121,7 +121,9 @@
     //Calculates total rendering area for RGB layers
     unsigned int renderArea = 0;
     unsigned int w=0, h=0;
-    for (unsigned int i=0; i<list->numHwLayers; i++) {
+    // Skipping last layer since FrameBuffer layer should not affect
+    // which composition to choose
+    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) {
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 4dbc3fc..0911248 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -829,7 +829,7 @@
 
         if(isYuvBuffer(hnd)) {
             type = MDPCOMP_OV_VG;
-        } else if(!qhwc::needsScaling(layer)
+        } else if(!qhwc::needsScaling(ctx, layer, mDpy)
             && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
             && ctx->mMDP.version >= qdutils::MDSS_V5) {
             type = MDPCOMP_OV_DMA;
@@ -979,7 +979,7 @@
 
         if(isYuvBuffer(hnd)) {
             type = MDPCOMP_OV_VG;
-        } else if(!qhwc::needsScaling(layer)
+        } else if(!qhwc::needsScaling(ctx, layer, mDpy)
             && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
             && ctx->mMDP.version >= qdutils::MDSS_V5) {
             type = MDPCOMP_OV_DMA;
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 16c2c8f..aa68467 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -109,6 +109,13 @@
     ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
     ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period = 1000000000l / fps;
 
+    //Unblank primary on first boot
+    if(ioctl(fb_fd, FBIOBLANK,FB_BLANK_UNBLANK) < 0) {
+        ALOGE("%s: Failed to unblank display", __FUNCTION__);
+        return -errno;
+    }
+    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive = true;
+
     return 0;
 }
 
@@ -306,15 +313,16 @@
 }
 
 
-bool needsScaling(hwc_layer_1_t const* layer) {
+bool needsScaling(hwc_context_t* ctx, hwc_layer_1_t const* layer,
+        const int& dpy) {
     int dst_w, dst_h, src_w, src_h;
 
     hwc_rect_t displayFrame  = layer->displayFrame;
     hwc_rect_t sourceCrop = layer->sourceCrop;
+    trimLayer(ctx, dpy, layer->transform, sourceCrop, displayFrame);
 
     dst_w = displayFrame.right - displayFrame.left;
     dst_h = displayFrame.bottom - displayFrame.top;
-
     src_w = sourceCrop.right - sourceCrop.left;
     src_h = sourceCrop.bottom - sourceCrop.top;
 
@@ -324,8 +332,9 @@
     return false;
 }
 
-bool isAlphaScaled(hwc_layer_1_t const* layer) {
-    if(needsScaling(layer) && isAlphaPresent(layer)) {
+bool isAlphaScaled(hwc_context_t* ctx, hwc_layer_1_t const* layer,
+        const int& dpy) {
+    if(needsScaling(ctx, layer, dpy) && isAlphaPresent(layer)) {
         return true;
     }
     return false;
@@ -390,14 +399,17 @@
             ctx->listStats[dpy].preMultipliedAlpha = true;
 
         if(!ctx->listStats[dpy].needsAlphaScale)
-            ctx->listStats[dpy].needsAlphaScale = isAlphaScaled(layer);
+            ctx->listStats[dpy].needsAlphaScale =
+                    isAlphaScaled(ctx, layer, dpy);
 
         if(UNLIKELY(isExtOnly(hnd))){
             ctx->listStats[dpy].extOnlyLayerIndex = i;
         }
+#ifdef QCOM_BSP
         if (layer->flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
             ctx->listStats[dpy].isDisplayAnimating = true;
         }
+#endif
     }
     if(ctx->listStats[dpy].yuvCount > 0) {
         if (property_get("hw.cabl.yuv", property, NULL) > 0) {
@@ -763,6 +775,9 @@
         if (ovutils::isYuv(whf.format)) {
             ovutils::normalizeCrop((uint32_t&)crop.left, crop_w);
             ovutils::normalizeCrop((uint32_t&)crop.top, crop_h);
+            // For interlaced, crop.h should be 4-aligned
+            if ((mdpFlags & ovutils::OV_MDP_DEINTERLACE) && (crop_h % 4))
+                crop_h = ovutils::aligndown(crop_h, 4);
             crop.right = crop.left + crop_w;
             crop.bottom = crop.top + crop_h;
         }
@@ -860,6 +875,7 @@
             crop = ctx->mPrevCropVideo;
             dst = ctx->mPrevDestVideo;
             transform = ctx->mPrevTransformVideo;
+            orient = static_cast<eTransform>(transform);
             //In you tube use case when a device rotated from landscape to
             // portrait, set the isFg flag and zOrder to avoid displaying UI on
             // hdmi during animation
@@ -961,6 +977,7 @@
             crop = ctx->mPrevCropVideo;
             dst = ctx->mPrevDestVideo;
             transform = ctx->mPrevTransformVideo;
+            orient = static_cast<eTransform>(transform);
             //In you tube use case when a device rotated from landscape to
             // portrait, set the isFg flag and zOrder to avoid displaying UI on
             // hdmi during animation
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 40bf352..fb5e871 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -130,7 +130,7 @@
 bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer);
 bool isSecureModePolicy(int mdpVersion);
 bool isExternalActive(hwc_context_t* ctx);
-bool needsScaling(hwc_layer_1_t const* layer);
+bool needsScaling(hwc_context_t* ctx, hwc_layer_1_t const* layer, const int& dpy);
 bool isAlphaPresent(hwc_layer_1_t const* layer);
 int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable);
 
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 9b91760..a15d0a8 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -143,11 +143,15 @@
         ret = true;
         PipeBook::setUse((int)dest);
     } else {
-        PipeBook::resetUse((int)dest);
         int dpy = mPipeBook[index].mDisplay;
         for(int i = 0; i < PipeBook::NUM_PIPES; i++)
-            if (mPipeBook[i].mDisplay == dpy)
+            if (mPipeBook[i].mDisplay == dpy) {
                 PipeBook::resetAllocation(i);
+                PipeBook::resetUse(i);
+                if(mPipeBook[i].valid()) {
+                    mPipeBook[i].mPipe->forceSet();
+                }
+            }
     }
     return ret;
 }
@@ -317,6 +321,9 @@
             // Mark as available for this round
             PipeBook::resetUse(i);
             PipeBook::resetAllocation(i);
+            if(mPipeBook[i].valid()) {
+                mPipeBook[i].mPipe->forceSet();
+            }
         }
     }
 }
diff --git a/liboverlay/overlayCtrlData.h b/liboverlay/overlayCtrlData.h
index 513ebb9..c3a7aa3 100644
--- a/liboverlay/overlayCtrlData.h
+++ b/liboverlay/overlayCtrlData.h
@@ -85,6 +85,7 @@
     void dump() const;
     /* Return the dump in the specified buffer */
     void getDump(char *buf, size_t len);
+    void forceSet();
 
 private:
     // mdp ctrl struct(info e.g.)
@@ -224,6 +225,10 @@
     mMdp.getDump(buf, len);
 }
 
+inline void Ctrl::forceSet() {
+    mMdp.forceSet();
+}
+
 inline Data::Data() {
     mMdp.reset();
 }
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index 4c77f2e..0de6276 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -54,6 +54,7 @@
     mLkgo.id = MSMFB_NEW_REQUEST;
     mOrientation = utils::OVERLAY_TRANSFORM_0;
     mDownscale = 0;
+    mForceSet = false;
 #ifdef USES_POST_PROCESSING
     mPPChanged = false;
     memset(&mParams, 0, sizeof(struct compute_params));
@@ -180,10 +181,16 @@
         if(mdpVersion < MDSS_V5) {
             utils::even_floor(mOVInfo.dst_rect.w);
             utils::even_floor(mOVInfo.dst_rect.h);
+        } else if (mOVInfo.flags & MDP_DEINTERLACE) {
+            // For interlaced, crop.h should be 4-aligned
+            if (!(mOVInfo.flags & MDP_SOURCE_ROTATED_90) &&
+                (mOVInfo.src_rect.h % 4))
+                mOVInfo.src_rect.h = utils::aligndown(mOVInfo.src_rect.h, 4);
         }
     }
 
-    if(this->ovChanged()) {
+    if(this->ovChanged() || mForceSet) {
+        mForceSet = false;
         if(!mdp_wrapper::setOverlay(mFd.getFD(), mOVInfo)) {
             ALOGE("MdpCtrl failed to setOverlay, restoring last known "
                   "good ov info");
diff --git a/liboverlay/overlayMdp.h b/liboverlay/overlayMdp.h
index f77ffae..056d982 100644
--- a/liboverlay/overlayMdp.h
+++ b/liboverlay/overlayMdp.h
@@ -81,6 +81,7 @@
     utils::Dim getSrcRectDim() const;
     /* setVisualParam */
     bool setVisualParams(const MetaData_t& data);
+    void forceSet();
 
 private:
     /* Perform transformation calculations */
@@ -125,6 +126,8 @@
     /* FD for the mdp fbnum */
     OvFD          mFd;
     int mDownscale;
+    bool mForceSet;
+
 #ifdef USES_POST_PROCESSING
     /* PP Compute Params */
     struct compute_params mParams;
@@ -319,6 +322,10 @@
         mOVInfo.flags |= MDP_SOURCE_ROTATED_90;
 }
 
+inline void MdpCtrl::forceSet() {
+    mForceSet = true;
+}
+
 ///////    MdpCtrl3D //////
 
 inline MdpCtrl3D::MdpCtrl3D() { reset(); }
diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp
index 90697a7..f5d4475 100644
--- a/liboverlay/pipes/overlayGenPipe.cpp
+++ b/liboverlay/pipes/overlayGenPipe.cpp
@@ -236,5 +236,8 @@
     return true;
 }
 
+void GenericPipe::forceSet() {
+    mCtrlData.ctrl.forceSet();
+}
 
 } //namespace overlay
diff --git a/liboverlay/pipes/overlayGenPipe.h b/liboverlay/pipes/overlayGenPipe.h
index 63ffd32..5463eb8 100644
--- a/liboverlay/pipes/overlayGenPipe.h
+++ b/liboverlay/pipes/overlayGenPipe.h
@@ -74,6 +74,10 @@
     void dump() const;
     /* Return the dump in the specified buffer */
     void getDump(char *buf, size_t len);
+    /* Marks the pipe for forcible setting of params
+     * even if they haven't changed
+     */
+    void forceSet();
 
 private:
     /* set Closed pipe */