SF: use FenceTime when possible

Fence::getSignalTime is calling a system call everytime,
where FenceTime caches the signal time.

This shows reduction in simpleperf for the main thread
2.23% -> 1.25%
Test: simpleperf for PIP + Notification shade expansion
Bug: 184378996

Change-Id: I182db2ddfcb7fdbde758f5d87357a16e60c1bb07
diff --git a/libs/ui/FenceTime.cpp b/libs/ui/FenceTime.cpp
index bdfe04b..538c1d2 100644
--- a/libs/ui/FenceTime.cpp
+++ b/libs/ui/FenceTime.cpp
@@ -97,6 +97,34 @@
     return mState != State::INVALID;
 }
 
+status_t FenceTime::wait(int timeout) {
+    // See if we already have a cached value we can return.
+    nsecs_t signalTime = mSignalTime.load(std::memory_order_relaxed);
+    if (signalTime != Fence::SIGNAL_TIME_PENDING) {
+        return NO_ERROR;
+    }
+
+    // Hold a reference to the fence on the stack in case the class'
+    // reference is removed by another thread. This prevents the
+    // fence from being destroyed until the end of this method, where
+    // we conveniently do not have the lock held.
+    sp<Fence> fence;
+    {
+        // With the lock acquired this time, see if we have the cached
+        // value or if we need to poll the fence.
+        std::lock_guard<std::mutex> lock(mMutex);
+        if (!mFence.get()) {
+            // Another thread set the signal time just before we added the
+            // reference to mFence.
+            return NO_ERROR;
+        }
+        fence = mFence;
+    }
+
+    // Make the system call without the lock held.
+    return fence->wait(timeout);
+}
+
 nsecs_t FenceTime::getSignalTime() {
     // See if we already have a cached value we can return.
     nsecs_t signalTime = mSignalTime.load(std::memory_order_relaxed);