diff options
author | Mathias Agopian <mathias@google.com> | 2012-04-08 15:13:32 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2012-04-08 20:54:47 -0700 |
commit | 2965b26022f95051f65b09d7eac47cbe923855c9 (patch) | |
tree | 7d17c24cdafba9852b23c95cfb7f030e9b200bfc /services/surfaceflinger/DisplayHardware | |
parent | d94d3b890ac3d5731bd0397874d32aa4bc74bd61 (diff) | |
download | frameworks_native-2965b26022f95051f65b09d7eac47cbe923855c9.zip frameworks_native-2965b26022f95051f65b09d7eac47cbe923855c9.tar.gz frameworks_native-2965b26022f95051f65b09d7eac47cbe923855c9.tar.bz2 |
VSYNC handling cleanup
Change-Id: I1376bf864c4e03c11fb6d1333a8b7cfdda08c9e4
Diffstat (limited to 'services/surfaceflinger/DisplayHardware')
-rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.cpp | 60 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.h | 54 |
2 files changed, 64 insertions, 50 deletions
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index a6804da..d42153c 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -23,6 +25,7 @@ #include <utils/Errors.h> #include <utils/String8.h> #include <utils/Thread.h> +#include <utils/Trace.h> #include <utils/Vector.h> #include <hardware/hardware.h> @@ -48,7 +51,7 @@ HWComposer::HWComposer( mNumOVLayers(0), mNumFBLayers(0), mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE), mEventHandler(handler), - mRefreshPeriod(refreshPeriod) + mRefreshPeriod(refreshPeriod), mVSyncCount(0) { int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID); @@ -100,6 +103,7 @@ void HWComposer::invalidate() { } void HWComposer::vsync(int dpy, int64_t timestamp) { + ATRACE_INT("VSYNC", ++mVSyncCount&1); mEventHandler.onVSyncReceived(dpy, timestamp); } @@ -245,4 +249,58 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE, } // --------------------------------------------------------------------------- + +HWComposer::VSyncThread::VSyncThread(HWComposer& hwc) + : mHwc(hwc), mEnabled(false), + mNextFakeVSync(0), + mRefreshPeriod(hwc.mRefreshPeriod) +{ +} + +void HWComposer::VSyncThread::setEnabled(bool enabled) { + Mutex::Autolock _l(mLock); + mEnabled = enabled; + mCondition.signal(); +} + +void HWComposer::VSyncThread::onFirstRef() { + run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); +} + +bool HWComposer::VSyncThread::threadLoop() { + { // scope for lock + Mutex::Autolock _l(mLock); + while (!mEnabled) { + mCondition.wait(mLock); + } + } + + const nsecs_t period = mRefreshPeriod; + const nsecs_t now = systemTime(CLOCK_MONOTONIC); + nsecs_t next_vsync = mNextFakeVSync; + nsecs_t sleep = next_vsync - now; + if (sleep < 0) { + // we missed, find where the next vsync should be + sleep = (period - ((now - next_vsync) % period)); + next_vsync = now + sleep; + } + mNextFakeVSync = next_vsync + period; + + struct timespec spec; + spec.tv_sec = next_vsync / 1000000000; + spec.tv_nsec = next_vsync % 1000000000; + + int err; + do { + err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL); + } while (err<0 && errno == EINTR); + + if (err == 0) { + mHwc.mEventHandler.onVSyncReceived(0, next_vsync); + } + + return true; +} + +// --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 60a6367..7814594 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -97,56 +97,11 @@ public: bool mEnabled; mutable nsecs_t mNextFakeVSync; nsecs_t mRefreshPeriod; - - virtual void onFirstRef() { - run("VSyncThread", - PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); - } - - virtual bool threadLoop() { - { // scope for lock - Mutex::Autolock _l(mLock); - while (!mEnabled) { - mCondition.wait(mLock); - } - } - - const nsecs_t period = mRefreshPeriod; - const nsecs_t now = systemTime(CLOCK_MONOTONIC); - nsecs_t next_vsync = mNextFakeVSync; - nsecs_t sleep = next_vsync - now; - if (sleep < 0) { - // we missed, find where the next vsync should be - sleep = (period - ((now - next_vsync) % period)); - next_vsync = now + sleep; - } - mNextFakeVSync = next_vsync + period; - - struct timespec spec; - spec.tv_sec = next_vsync / 1000000000; - spec.tv_nsec = next_vsync % 1000000000; - - // NOTE: EINTR can happen with clock_nanosleep(), in case of - // any error (including EINTR) we go through the condition's - // test -- this is always correct and easy. - if (::clock_nanosleep(CLOCK_MONOTONIC, - TIMER_ABSTIME, &spec, NULL) == 0) { - mHwc.mEventHandler.onVSyncReceived(0, next_vsync); - } - return true; - } - + virtual void onFirstRef(); + virtual bool threadLoop(); public: - VSyncThread(HWComposer& hwc) : - mHwc(hwc), mEnabled(false), - mNextFakeVSync(0), - mRefreshPeriod(hwc.mRefreshPeriod) { - } - void setEnabled(bool enabled) { - Mutex::Autolock _l(mLock); - mEnabled = enabled; - mCondition.signal(); - } + VSyncThread(HWComposer& hwc); + void setEnabled(bool enabled); }; friend class VSyncThread; @@ -187,6 +142,7 @@ private: cb_context mCBContext; EventHandler& mEventHandler; nsecs_t mRefreshPeriod; + size_t mVSyncCount; sp<VSyncThread> mVSyncThread; }; |