OSDN Git Service

Merge "Include tracking state bits to DvrPose." into oc-dr1-dev am: 0d346a0cb1
[android-x86/frameworks-native.git] / services / surfaceflinger / DispSync.cpp
index 1a9820d..ac8aa04 100644 (file)
 
 #include <math.h>
 
-#include <cutils/log.h>
-
-#include <ui/Fence.h>
+#include <algorithm>
 
+#include <log/log.h>
 #include <utils/String8.h>
 #include <utils/Thread.h>
 #include <utils/Trace.h>
 #include <utils/Vector.h>
 
+#include <ui/FenceTime.h>
+
 #include "DispSync.h"
+#include "SurfaceFlinger.h"
 #include "EventLog/EventLog.h"
 
-#include <algorithm>
-
 using std::max;
 using std::min;
 
@@ -55,16 +55,12 @@ static const bool kEnableZeroPhaseTracer = false;
 // present time and the nearest software-predicted vsync.
 static const nsecs_t kErrorThreshold = 160000000000;    // 400 usec squared
 
-// This is the offset from the present fence timestamps to the corresponding
-// vsync event.
-static const int64_t kPresentTimeOffset = PRESENT_TIME_OFFSET_FROM_VSYNC_NS;
-
 #undef LOG_TAG
 #define LOG_TAG "DispSyncThread"
 class DispSyncThread: public Thread {
 public:
 
-    DispSyncThread(const char* name):
+    explicit DispSyncThread(const char* name):
             mName(name),
             mStop(false),
             mPeriod(0),
@@ -220,7 +216,8 @@ public:
         return BAD_VALUE;
     }
 
-    // This method is only here to handle the kIgnorePresentFences case.
+    // This method is only here to handle the !SurfaceFlinger::hasSyncFramework
+    // case.
     bool hasAnyEventListeners() {
         if (kTraceDetailedInfo) ATRACE_CALL();
         Mutex::Autolock lock(mMutex);
@@ -380,8 +377,10 @@ private:
 DispSync::DispSync(const char* name) :
         mName(name),
         mRefreshSkipCount(0),
-        mThread(new DispSyncThread(name)) {
+        mThread(new DispSyncThread(name)),
+        mIgnorePresentFences(!SurfaceFlinger::hasSyncFramework){
 
+    mPresentTimeOffset = SurfaceFlinger::dispSyncPresentTimeOffset;
     mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
     // set DispSync to SCHED_FIFO to minimize jitter
     struct sched_param param = {0};
@@ -400,7 +399,7 @@ DispSync::DispSync(const char* name) :
         // Even if we're just ignoring the fences, the zero-phase tracing is
         // not needed because any time there is an event registered we will
         // turn on the HW vsync events.
-        if (!kIgnorePresentFences && kEnableZeroPhaseTracer) {
+        if (!mIgnorePresentFences && kEnableZeroPhaseTracer) {
             addEventListener("ZeroPhaseTracer", 0, new ZeroPhaseTracer());
         }
     }
@@ -420,25 +419,13 @@ void DispSync::reset() {
     resetErrorLocked();
 }
 
-bool DispSync::addPresentFence(const sp<Fence>& fence) {
+bool DispSync::addPresentFence(const std::shared_ptr<FenceTime>& fenceTime) {
     Mutex::Autolock lock(mMutex);
 
-    mPresentFences[mPresentSampleOffset] = fence;
-    mPresentTimes[mPresentSampleOffset] = 0;
+    mPresentFences[mPresentSampleOffset] = fenceTime;
     mPresentSampleOffset = (mPresentSampleOffset + 1) % NUM_PRESENT_SAMPLES;
     mNumResyncSamplesSincePresent = 0;
 
-    for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) {
-        const sp<Fence>& f(mPresentFences[i]);
-        if (f != NULL) {
-            nsecs_t t = f->getSignalTime();
-            if (t < INT64_MAX) {
-                mPresentFences[i].clear();
-                mPresentTimes[i] = t + kPresentTimeOffset;
-            }
-        }
-    }
-
     updateErrorLocked();
 
     return !mModelUpdated || mError > kErrorThreshold;
@@ -479,7 +466,7 @@ bool DispSync::addResyncSample(nsecs_t timestamp) {
         resetErrorLocked();
     }
 
-    if (kIgnorePresentFences) {
+    if (mIgnorePresentFences) {
         // If we don't have the sync framework we will never have
         // addPresentFence called.  This means we have no way to know whether
         // or not we're synchronized with the HW vsyncs, so we just request
@@ -603,21 +590,39 @@ void DispSync::updateErrorLocked() {
     nsecs_t sqErrSum = 0;
 
     for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) {
-        nsecs_t sample = mPresentTimes[i] - mReferenceTime;
-        if (sample > mPhase) {
-            nsecs_t sampleErr = (sample - mPhase) % period;
-            if (sampleErr > period / 2) {
-                sampleErr -= period;
-            }
-            sqErrSum += sampleErr * sampleErr;
-            numErrSamples++;
+        // Only check for the cached value of signal time to avoid unecessary
+        // syscalls. It is the responsibility of the DispSync owner to
+        // call getSignalTime() periodically so the cache is updated when the
+        // fence signals.
+        nsecs_t time = mPresentFences[i]->getCachedSignalTime();
+        if (time == Fence::SIGNAL_TIME_PENDING ||
+                time == Fence::SIGNAL_TIME_INVALID) {
+            continue;
+        }
+
+        nsecs_t sample = time - mReferenceTime;
+        if (sample <= mPhase) {
+            continue;
+        }
+
+        nsecs_t sampleErr = (sample - mPhase) % period;
+        if (sampleErr > period / 2) {
+            sampleErr -= period;
         }
+        sqErrSum += sampleErr * sampleErr;
+        numErrSamples++;
     }
 
     if (numErrSamples > 0) {
         mError = sqErrSum / numErrSamples;
+        mZeroErrSamplesCount = 0;
     } else {
         mError = 0;
+        // Use mod ACCEPTABLE_ZERO_ERR_SAMPLES_COUNT to avoid log spam.
+        mZeroErrSamplesCount++;
+        ALOGE_IF(
+                (mZeroErrSamplesCount % ACCEPTABLE_ZERO_ERR_SAMPLES_COUNT) == 0,
+                "No present times for model error.");
     }
 
     if (kTraceDetailedInfo) {
@@ -628,9 +633,9 @@ void DispSync::updateErrorLocked() {
 void DispSync::resetErrorLocked() {
     mPresentSampleOffset = 0;
     mError = 0;
+    mZeroErrSamplesCount = 0;
     for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) {
-        mPresentFences[i].clear();
-        mPresentTimes[i] = 0;
+        mPresentFences[i] = FenceTime::NO_FENCE;
     }
 }
 
@@ -644,7 +649,7 @@ nsecs_t DispSync::computeNextRefresh(int periodOffset) const {
 void DispSync::dump(String8& result) const {
     Mutex::Autolock lock(mMutex);
     result.appendFormat("present fences are %s\n",
-            kIgnorePresentFences ? "ignored" : "used");
+            mIgnorePresentFences ? "ignored" : "used");
     result.appendFormat("mPeriod: %" PRId64 " ns (%.3f fps; skipCount=%d)\n",
             mPeriod, 1000000000.0 / mPeriod, mRefreshSkipCount);
     result.appendFormat("mPhase: %" PRId64 " ns\n", mPhase);
@@ -669,19 +674,19 @@ void DispSync::dump(String8& result) const {
         previous = sampleTime;
     }
 
-    result.appendFormat("mPresentFences / mPresentTimes [%d]:\n",
+    result.appendFormat("mPresentFences [%d]:\n",
             NUM_PRESENT_SAMPLES);
     nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-    previous = 0;
+    previous = Fence::SIGNAL_TIME_INVALID;
     for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) {
         size_t idx = (i + mPresentSampleOffset) % NUM_PRESENT_SAMPLES;
-        bool signaled = mPresentFences[idx] == NULL;
-        nsecs_t presentTime = mPresentTimes[idx];
-        if (!signaled) {
+        nsecs_t presentTime = mPresentFences[idx]->getSignalTime();
+        if (presentTime == Fence::SIGNAL_TIME_PENDING) {
             result.appendFormat("  [unsignaled fence]\n");
-        } else if (presentTime == 0) {
-            result.appendFormat("  0\n");
-        } else if (previous == 0) {
+        } else if(presentTime == Fence::SIGNAL_TIME_INVALID) {
+            result.appendFormat("  [invalid fence]\n");
+        } else if (previous == Fence::SIGNAL_TIME_PENDING ||
+                previous == Fence::SIGNAL_TIME_INVALID) {
             result.appendFormat("  %" PRId64 "  (%.3f ms ago)\n", presentTime,
                     (now - presentTime) / 1000000.0);
         } else {