Merge "SF: Permit changing DispSync offsets at runtime"

This commit is contained in:
Dan Stoza 2015-04-15 21:37:19 +00:00 committed by Gerrit Code Review
commit 2e398e64b3
3 changed files with 69 additions and 8 deletions

View File

@ -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) {

View File

@ -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();

View File

@ -320,17 +320,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));
@ -348,18 +351,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) {
@ -375,14 +414,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() {
@ -2887,6 +2930,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;