Merge "hwc: metadata API to set 3D format."
diff --git a/displayengine/include/core/layer_stack.h b/displayengine/include/core/layer_stack.h
index 0a37c79..96ec20f 100644
--- a/displayengine/include/core/layer_stack.h
+++ b/displayengine/include/core/layer_stack.h
@@ -124,7 +124,11 @@
   uint64_t secure_present : 1;    //!< This flag will be set to true, if the current layer stack
                                   //!< contains secure layers.
 
-  LayerStackFlags() : geometry_changed(0), skip_present(0), video_present(0), secure_present(0) { }
+  uint64_t animating : 1;         //!< This flag shall be set by client to indicate that the current
+                                  //!< frame is animating.
+
+  LayerStackFlags()
+    : geometry_changed(0), skip_present(0), video_present(0), secure_present(0), animating(0) { }
 };
 
 /*! @brief This structure defines a rectanglular area inside a display layer.
diff --git a/displayengine/include/utils/rect.h b/displayengine/include/utils/rect.h
new file mode 100644
index 0000000..39494c2
--- /dev/null
+++ b/displayengine/include/utils/rect.h
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2015, 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
+* met:
+*   * Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   * Redistributions in binary form must reproduce the above
+*     copyright notice, this list of conditions and the following
+*     disclaimer in the documentation and/or other materials provided
+*     with the distribution.
+*   * Neither the name of The Linux Foundation nor the names of its
+*     contributors may be used to endorse or promote products derived
+*     from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __RECT_H__
+#define __RECT_H__
+
+#include <stdint.h>
+#include <core/sde_types.h>
+#include <core/layer_stack.h>
+
+namespace sde {
+
+  bool IsValidRect(const LayerRect &rect);
+  LayerRect GetIntersection(const LayerRect &rect1, const LayerRect &rect2);
+
+}  // namespace sde
+
+#endif  // __RECT_H__
+
diff --git a/displayengine/libs/hwc/hwc_display.cpp b/displayengine/libs/hwc/hwc_display.cpp
index 452bff1..dd1beac 100644
--- a/displayengine/libs/hwc/hwc_display.cpp
+++ b/displayengine/libs/hwc/hwc_display.cpp
@@ -361,6 +361,10 @@
     layer.flags.skip = ((hwc_layer.flags & HWC_SKIP_LAYER) > 0);
     layer.flags.updating = (layer_stack_cache_.layer_cache[i].handle != hwc_layer.handle);
 
+    if (hwc_layer.flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
+      layer_stack_.flags.animating = true;
+    }
+
     if (layer.flags.skip) {
       layer_stack_.flags.skip_present = true;
     }
@@ -462,17 +466,31 @@
     Layer &layer = layer_stack_.layers[i];
     LayerBuffer *layer_buffer = layer_stack_.layers[i].input_buffer;
 
-    if (!flush_ && (layer.composition == kCompositionSDE ||
-                         layer.composition == kCompositionGPUTarget)) {
-      hwc_layer.releaseFenceFd = layer_buffer->release_fence_fd;
+    if (!flush_) {
+      if (layer.composition != kCompositionGPU) {
+        hwc_layer.releaseFenceFd = layer_buffer->release_fence_fd;
+      }
+
+      // During animation on external/virtual display, Display Engine will use the cached
+      // framebuffer layer throughout animation and do not allow framework to do eglswapbuffer on
+      // framebuffer target. So graphics doesn't close the release fence fd of framebuffer target,
+      // Hence close the release fencefd of framebuffer target here.
+      if (layer.composition == kCompositionGPUTarget && layer_stack_cache_.animating) {
+        close(hwc_layer.releaseFenceFd);
+        hwc_layer.releaseFenceFd = -1;
+      }
     }
 
     if (hwc_layer.acquireFenceFd >= 0) {
       close(hwc_layer.acquireFenceFd);
+      hwc_layer.acquireFenceFd = -1;
     }
   }
 
+
   if (!flush_) {
+    layer_stack_cache_.animating = layer_stack_.flags.animating;
+
     content_list->retireFenceFd = layer_stack_.retire_fence_fd;
 
     if (dump_frame_count_) {
@@ -495,8 +513,8 @@
   // 2. Any layer is added/removed/layer properties changes in the current layer stack.
   // 3. Any layer handle is changed and it is marked for GPU composition
   // 4. Any layer's current composition is different from previous composition.
-  if ((layer_stack_cache_.layer_count != layer_count) || layer_stack_.flags.skip_present ||
-       layer_stack_.flags.geometry_changed) {
+  if (((layer_stack_cache_.layer_count != layer_count) || layer_stack_.flags.skip_present ||
+      layer_stack_.flags.geometry_changed) && !layer_stack_cache_.animating) {
     return true;
   }
 
@@ -513,7 +531,8 @@
       return true;
     }
 
-    if ((layer.composition == kCompositionGPU) && (layer_cache.handle != hwc_layer.handle)) {
+    if ((layer.composition == kCompositionGPU) && (layer_cache.handle != hwc_layer.handle) &&
+        !layer_stack_cache_.animating) {
       return true;
     }
   }
diff --git a/displayengine/libs/hwc/hwc_display.h b/displayengine/libs/hwc/hwc_display.h
index 3934078..a574d6b 100644
--- a/displayengine/libs/hwc/hwc_display.h
+++ b/displayengine/libs/hwc/hwc_display.h
@@ -69,8 +69,9 @@
   struct LayerStackCache {
     LayerCache layer_cache[kMaxLayerCount];
     uint32_t layer_count;
+    bool animating;
 
-    LayerStackCache() : layer_count(0) { }
+    LayerStackCache() : layer_count(0), animating(false) { }
   };
 
   HWCDisplay(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DisplayType type, int id);
diff --git a/displayengine/libs/utils/Android.mk b/displayengine/libs/utils/Android.mk
index db97dd5..264c40a 100644
--- a/displayengine/libs/utils/Android.mk
+++ b/displayengine/libs/utils/Android.mk
@@ -8,6 +8,6 @@
                                  -Wconversion -Wall -Werror \
                                  -DLOG_TAG=\"SDE\"
 LOCAL_SHARED_LIBRARIES        := libcutils
-LOCAL_SRC_FILES               := debug_android.cpp
+LOCAL_SRC_FILES               := debug_android.cpp rect.cpp
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/displayengine/libs/utils/rect.cpp b/displayengine/libs/utils/rect.cpp
new file mode 100644
index 0000000..11131c3
--- /dev/null
+++ b/displayengine/libs/utils/rect.cpp
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2015, 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
+* met:
+*   * Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   * Redistributions in binary form must reproduce the above
+*     copyright notice, this list of conditions and the following
+*     disclaimer in the documentation and/or other materials provided
+*     with the distribution.
+*   * Neither the name of The Linux Foundation nor the names of its
+*     contributors may be used to endorse or promote products derived
+*     from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <utils/rect.h>
+
+namespace sde {
+
+bool IsValidRect(const LayerRect &rect) {
+  return ((rect.bottom > rect.top) && (rect.right > rect.left));
+}
+
+
+LayerRect GetIntersection(const LayerRect &rect1, const LayerRect &rect2) {
+  LayerRect res;
+
+  if (!IsValidRect(rect1) || !IsValidRect(rect2)) {
+    return LayerRect();
+  }
+
+  res.left = MAX(rect1.left, rect2.left);
+  res.top = MAX(rect1.top, rect2.top);
+  res.right = MIN(rect1.right, rect2.right);
+  res.bottom = MIN(rect1.bottom, rect2.bottom);
+
+  if (!IsValidRect(res)) {
+    return LayerRect();
+  }
+
+  return res;
+}
+
+}  // namespace sde
+