hwc/overlay: Implement rotator caching

* A non-updating layer requiring rotation, can make use of
the older rotator buffer written when the layer got first
updated, rather than invoking a new rotator cycle.

* A rotator play is avoided in cases where incoming layer
buffer fd, offset, whf, src-rect, dst-rect, etc are similar
to that of the previous input layer to the rotator.

* For ex: In a usecase where video layer updates happen at
30fps and all other asynchrous UI updates happen at 60fps,
instead of the traditional 60 calls of rotator play per sec,
we now do only 30 thereby saving rotator bandwidth.

* Property "debug.rotcache.disable" can be used to disable
this feature.

Change-Id: I1d1c352c63007b7e0b4fee40882086ccd2f5a4aa
diff --git a/liboverlay/overlayRotator.cpp b/liboverlay/overlayRotator.cpp
index 06e9074..b55f06a 100644
--- a/liboverlay/overlayRotator.cpp
+++ b/liboverlay/overlayRotator.cpp
@@ -29,6 +29,17 @@
 
 //============Rotator=========================
 
+Rotator::Rotator() {
+    char property[PROPERTY_VALUE_MAX];
+    mRotCacheDisabled = false;
+    if((property_get("debug.rotcache.disable", property, NULL) > 0) &&
+       (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+        (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+        /* Used in debugging to turnoff rotator caching */
+        mRotCacheDisabled = true;
+    }
+}
+
 Rotator::~Rotator() {}
 
 Rotator* Rotator::getRotator() {
@@ -70,6 +81,20 @@
     return TYPE_MDP;
 }
 
+bool Rotator::isRotCached(int fd, uint32_t offset) const {
+    if(mRotCacheDisabled or rotConfChanged() or rotDataChanged(fd,offset))
+        return false;
+    return true;
+}
+
+bool Rotator::rotDataChanged(int fd, uint32_t offset) const {
+    /* fd and offset are the attributes of the current rotator input buffer.
+     * At this instance, getSrcMemId() and getSrcOffset() return the
+     * attributes of the previous rotator input buffer */
+    if( (fd == getSrcMemId()) and (offset == getSrcOffset()) )
+        return false;
+    return true;
+}
 
 //============RotMem=========================
 
@@ -98,7 +123,7 @@
     }
 }
 
-void RotMem::setReleaseFd(const int& fence) {
+void RotMem::setCurrBufReleaseFd(const int& fence) {
     int ret = 0;
 
     if(mRelFence[mCurrIndex] >= 0) {
@@ -116,6 +141,20 @@
     mRelFence[mCurrIndex] = fence;
 }
 
+void RotMem::setPrevBufReleaseFd(const int& fence) {
+    uint32_t numRotBufs = mem.numBufs();
+    uint32_t prevIndex = (mCurrIndex + numRotBufs - 1) % (numRotBufs);
+
+    if(mRelFence[prevIndex] >= 0) {
+        /* No need of any wait as nothing will be written into this
+         * buffer by the rotator (this func is called when rotator is
+         * in cache mode) */
+        ::close(mRelFence[prevIndex]);
+    }
+
+    mRelFence[prevIndex] = fence;
+}
+
 //============RotMgr=========================
 RotMgr * RotMgr::sRotMgr = NULL;