hwc: Refactor disable animation on external

Fall back to GPU for one cycle at the start of animation and display
the frame buffer for the subsequent cycle till animation ends.

Change-Id: I6c651cebaf4694f326d6e32ae485e014f391577c
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index a805486..10a0161 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -179,15 +179,6 @@
                 const int fbZ = 0;
                 ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZ);
             }
-
-            if(ctx->listStats[dpy].isDisplayAnimating) {
-                // Mark all app layers as HWC_OVERLAY for external during
-                // animation, so that SF doesnt draw it on FB
-                for(int i = 0 ;i < ctx->listStats[dpy].numAppLayers; i++) {
-                    hwc_layer_1_t *layer = &list->hwLayers[i];
-                    layer->compositionType = HWC_OVERLAY;
-                }
-            }
         } else {
             // External Display is in Pause state.
             // ToDo:
@@ -217,15 +208,6 @@
                 const int fbZ = 0;
                 ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZ);
             }
-
-            if(ctx->listStats[dpy].isDisplayAnimating) {
-                // Mark all app layers as HWC_OVERLAY for virtual during
-                // animation, so that SF doesnt draw it on FB
-                for(int i = 0 ;i < ctx->listStats[dpy].numAppLayers; i++) {
-                    hwc_layer_1_t *layer = &list->hwLayers[i];
-                    layer->compositionType = HWC_OVERLAY;
-                }
-            }
         } else {
             // Virtual Display is in Pause state.
             // ToDo:
@@ -303,8 +285,6 @@
             if(dpy == HWC_DISPLAY_PRIMARY) {
                 Locker::Autolock _l(ctx->mDrawLock);
                 // store the primary display orientation
-                // will be used in hwc_video::configure to disable
-                // rotation animation on external display
                 ctx->deviceOrientation = enable;
             }
             break;
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 48d9575..4f4584e 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -847,9 +847,7 @@
 
 /* Checks for conditions where YUV layers cannot be bypassed */
 bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
-    bool extAnimBlockFeature = mDpy && ctx->listStats[mDpy].isDisplayAnimating;
-
-    if(isSkipLayer(layer) && !extAnimBlockFeature) {
+    if(isSkipLayer(layer)) {
         ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
         return false;
     }
@@ -1069,15 +1067,6 @@
 void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
         bool secureOnly) {
     int nYuvCount = ctx->listStats[mDpy].yuvCount;
-    if(!nYuvCount && mDpy) {
-        //Reset "No animation on external display" related  parameters.
-        ctx->mPrevCropVideo.left = ctx->mPrevCropVideo.top =
-            ctx->mPrevCropVideo.right = ctx->mPrevCropVideo.bottom = 0;
-        ctx->mPrevDestVideo.left = ctx->mPrevDestVideo.top =
-            ctx->mPrevDestVideo.right = ctx->mPrevDestVideo.bottom = 0;
-        ctx->mPrevTransformVideo = 0;
-        return;
-     }
     for(int index = 0;index < nYuvCount; index++){
         int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
         hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
@@ -1242,6 +1231,22 @@
         return ret;
     }
 
+    // Detect the start of animation and fall back to GPU only once to cache
+    // all the layers in FB and display FB content untill animation completes.
+    if(ctx->listStats[mDpy].isDisplayAnimating) {
+        mCurrentFrame.needsRedraw = false;
+        if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
+            mCurrentFrame.needsRedraw = true;
+            ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
+        }
+        setMDPCompLayerFlags(ctx, list);
+        mCachedFrame.updateCounts(mCurrentFrame);
+        ret = -1;
+        return ret;
+    } else {
+        ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
+    }
+
     //Hard conditions, if not met, cannot do MDP comp
     if(!isFrameDoable(ctx)) {
         ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 6f2cb9c..a36a944 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -172,6 +172,7 @@
     for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
         ctx->mHwcDebug[i] = new HwcDebug(i);
         ctx->mLayerRotMap[i] = new LayerRotMap();
+        ctx->mAnimationState[i] = ANIMATION_STOPPED;
     }
 
     MDPComp::init(ctx);
@@ -189,13 +190,8 @@
             defaultServiceManager()->getService(
             String16("display.qservice")))->connect(client);
 
-    // Initialize "No animation on external display" related  parameters.
+    // Initialize device orientation to its default orientation
     ctx->deviceOrientation = 0;
-    ctx->mPrevCropVideo.left = ctx->mPrevCropVideo.top =
-        ctx->mPrevCropVideo.right = ctx->mPrevCropVideo.bottom = 0;
-    ctx->mPrevDestVideo.left = ctx->mPrevDestVideo.top =
-        ctx->mPrevDestVideo.right = ctx->mPrevDestVideo.bottom = 0;
-    ctx->mPrevTransformVideo = 0;
     ctx->mBufferMirrorMode = false;
 #ifdef VPU_TARGET
     ctx->mVPUClient = new VPUClient();
@@ -1218,12 +1214,7 @@
             } else if(isExtAnimating) {
                 // Release all the app layer fds immediately,
                 // if animation is in progress.
-                hwc_layer_1_t const* layer = &list->hwLayers[i];
-                private_handle_t *hnd = (private_handle_t *)layer->handle;
-                if(isYuvBuffer(hnd)) {
-                    list->hwLayers[i].releaseFenceFd = dup(releaseFd);
-                } else
-                    list->hwLayers[i].releaseFenceFd = -1;
+                list->hwLayers[i].releaseFenceFd = -1;
             } else if(list->hwLayers[i].releaseFenceFd < 0) {
                 //If rotator has not already populated this field.
                 list->hwLayers[i].releaseFenceFd = dup(releaseFd);
@@ -1471,25 +1462,6 @@
     }
 
     if(dpy && isYuvBuffer(hnd)) {
-        if(!ctx->listStats[dpy].isDisplayAnimating) {
-            ctx->mPrevCropVideo = crop;
-            ctx->mPrevDestVideo = dst;
-            ctx->mPrevTransformVideo = transform;
-        } else {
-            // Restore the previous crop, dest rect and transform values, during
-            // animation to avoid displaying videos at random coordinates.
-            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
-            if(ctx->deviceOrientation) {
-                isFg = ovutils::IS_FG_SET;
-                z = ZORDER_1;
-            }
-        }
         calcExtDisplayPosition(ctx, hnd, dpy, crop, dst,
                                            transform, orient);
     }
@@ -1603,28 +1575,6 @@
             whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
     }
 
-    if(dpy && isYuvBuffer(hnd)) {
-        if(!ctx->listStats[dpy].isDisplayAnimating) {
-            ctx->mPrevCropVideo = crop;
-            ctx->mPrevDestVideo = dst;
-            ctx->mPrevTransformVideo = transform;
-        } else {
-            // Restore the previous crop, dest rect and transform values, during
-            // animation to avoid displaying videos at random coordinates.
-            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
-            if(ctx->deviceOrientation) {
-                isFg = ovutils::IS_FG_SET;
-                z = ZORDER_1;
-            }
-        }
-    }
-
     setMdpFlags(layer, mdpFlagsL, 0, transform);
 
     if(lDest != OV_INVALID && rDest != OV_INVALID) {
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 2503e43..1eb6610 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -410,6 +410,11 @@
 
 }; //qhwc namespace
 
+enum eAnimationState{
+    ANIMATION_STOPPED,
+    ANIMATION_STARTED,
+};
+
 // -----------------------------------------------------------------------------
 // HWC context
 // This structure contains overall state
@@ -439,14 +444,10 @@
     qhwc::HwcDebug *mHwcDebug[HWC_NUM_DISPLAY_TYPES];
     qhwc::AssertiveDisplay *mAD;
     qhwc::VPUClient *mVPUClient;
+    eAnimationState mAnimationState[HWC_NUM_DISPLAY_TYPES];
 
-    // No animation on External display feature
-    // Notifies hwcomposer about the device orientation before animation.
+    // stores the primary device orientation
     int deviceOrientation;
-    // Stores the crop, dest rect and transform value of video before animation.
-    hwc_rect_t mPrevCropVideo;
-    hwc_rect_t mPrevDestVideo;
-    int mPrevTransformVideo;
     //Securing in progress indicator
     bool mSecuring;
     //WFD on proprietary stack