Merge "SF: Permit changing DispSync offsets at runtime"
This commit is contained in:
commit
2e398e64b3
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user