diff options
author | Dan Stoza <stoza@google.com> | 2015-04-15 22:16:03 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-04-15 22:16:03 +0000 |
commit | d5296b342e51bd41c9b1d26e98978d9b9ef23a89 (patch) | |
tree | 42d4be135a19d0e8aebd3cd2552b306365e03e8e /services | |
parent | 91dea34652ff891192148b4062a80c2e8f0852ce (diff) | |
parent | 66dc4ee3729c4e6fea624805a1e58843ce920477 (diff) | |
download | frameworks_native-d5296b342e51bd41c9b1d26e98978d9b9ef23a89.zip frameworks_native-d5296b342e51bd41c9b1d26e98978d9b9ef23a89.tar.gz frameworks_native-d5296b342e51bd41c9b1d26e98978d9b9ef23a89.tar.bz2 |
am 66dc4ee3: am b47584f4: am 2e398e64: Merge "SF: Permit changing DispSync offsets at runtime"
* commit '66dc4ee3729c4e6fea624805a1e58843ce920477':
SF: Permit changing DispSync offsets at runtime
Diffstat (limited to 'services')
-rw-r--r-- | services/surfaceflinger/EventThread.cpp | 5 | ||||
-rw-r--r-- | services/surfaceflinger/EventThread.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 69 |
3 files changed, 69 insertions, 8 deletions
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp index 9b6360e..f760200 100644 --- a/services/surfaceflinger/EventThread.cpp +++ b/services/surfaceflinger/EventThread.cpp @@ -71,6 +71,11 @@ void EventThread::sendVsyncHintOff() { mVsyncHintSent = false; } +void EventThread::setPhaseOffset(nsecs_t phaseOffset) { + Mutex::Autolock _l(mLock); + mVSyncSource->setPhaseOffset(phaseOffset); +} + void EventThread::sendVsyncHintOnLocked() { struct itimerspec ts; if(!mVsyncHintSent) { diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h index d1c4fcd..9ba179a 100644 --- a/services/surfaceflinger/EventThread.h +++ b/services/surfaceflinger/EventThread.h @@ -51,6 +51,7 @@ public: virtual ~VSyncSource() {} virtual void setVSyncEnabled(bool enable) = 0; virtual void setCallback(const sp<Callback>& callback) = 0; + virtual void setPhaseOffset(nsecs_t phaseOffset) = 0; }; class EventThread : public Thread, private VSyncSource::Callback { @@ -99,6 +100,8 @@ public: void dump(String8& result) const; void sendVsyncHintOff(); + void setPhaseOffset(nsecs_t phaseOffset); + private: virtual bool threadLoop(); virtual void onFirstRef(); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index fa0bc06..1419557 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -324,17 +324,20 @@ public: DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync, const char* label) : mValue(0), - mPhaseOffset(phaseOffset), mTraceVsync(traceVsync), mVsyncOnLabel(String8::format("VsyncOn-%s", label)), mVsyncEventLabel(String8::format("VSYNC-%s", label)), - mDispSync(dispSync) {} + mDispSync(dispSync), + mCallbackMutex(), + mCallback(), + mVsyncMutex(), + mPhaseOffset(phaseOffset), + mEnabled(false) {} virtual ~DispSyncSource() {} virtual void setVSyncEnabled(bool enable) { - // Do NOT lock the mutex here so as to avoid any mutex ordering issues - // with locking it in the onDispSyncEvent callback. + Mutex::Autolock lock(mVsyncMutex); if (enable) { status_t err = mDispSync->addEventListener(mPhaseOffset, static_cast<DispSync::Callback*>(this)); @@ -352,18 +355,54 @@ public: } //ATRACE_INT(mVsyncOnLabel.string(), 0); } + mEnabled = enable; } virtual void setCallback(const sp<VSyncSource::Callback>& callback) { - Mutex::Autolock lock(mMutex); + Mutex::Autolock lock(mCallbackMutex); mCallback = callback; } + virtual void setPhaseOffset(nsecs_t phaseOffset) { + Mutex::Autolock lock(mVsyncMutex); + + // Normalize phaseOffset to [0, period) + auto period = mDispSync->getPeriod(); + phaseOffset %= period; + if (phaseOffset < 0) { + // If we're here, then phaseOffset is in (-period, 0). After this + // operation, it will be in (0, period) + phaseOffset += period; + } + mPhaseOffset = phaseOffset; + + // If we're not enabled, we don't need to mess with the listeners + if (!mEnabled) { + return; + } + + // Remove the listener with the old offset + status_t err = mDispSync->removeEventListener( + static_cast<DispSync::Callback*>(this)); + if (err != NO_ERROR) { + ALOGE("error unregistering vsync callback: %s (%d)", + strerror(-err), err); + } + + // Add a listener with the new offset + err = mDispSync->addEventListener(mPhaseOffset, + static_cast<DispSync::Callback*>(this)); + if (err != NO_ERROR) { + ALOGE("error registering vsync callback: %s (%d)", + strerror(-err), err); + } + } + private: virtual void onDispSyncEvent(nsecs_t when) { sp<VSyncSource::Callback> callback; { - Mutex::Autolock lock(mMutex); + Mutex::Autolock lock(mCallbackMutex); callback = mCallback; if (mTraceVsync) { @@ -379,14 +418,18 @@ private: int mValue; - const nsecs_t mPhaseOffset; const bool mTraceVsync; const String8 mVsyncOnLabel; const String8 mVsyncEventLabel; DispSync* mDispSync; + + Mutex mCallbackMutex; // Protects the following sp<VSyncSource::Callback> mCallback; - Mutex mMutex; + + Mutex mVsyncMutex; // Protects the following + nsecs_t mPhaseOffset; + bool mEnabled; }; void SurfaceFlinger::init() { @@ -2941,6 +2984,16 @@ status_t SurfaceFlinger::onTransact( mForceFullDamage = static_cast<bool>(n); return NO_ERROR; } + case 1018: { // Modify Choreographer's phase offset + n = data.readInt32(); + mEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); + return NO_ERROR; + } + case 1019: { // Modify SurfaceFlinger's phase offset + n = data.readInt32(); + mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); + return NO_ERROR; + } } } return err; |