Bug 1653796 - Eliminate non-monotonic sample times at the start of APZ animations with WR. r=tnikkel

Differential Revision: https://phabricator.services.mozilla.com/D86045
This commit is contained in:
Kartikaya Gupta 2020-08-05 20:26:36 +00:00
Родитель d2c77fe8bd
Коммит fad9416d89
1 изменённых файлов: 22 добавлений и 1 удалений

Просмотреть файл

@ -77,6 +77,9 @@ void APZSampler::SampleForWebRender(
void APZSampler::SetSampleTime(const TimeStamp& aSampleTime) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
MutexAutoLock lock(mSampleTimeLock);
// This only gets called with WR, and the time provided is going to be
// the time at which the current vsync interval ends. i.e. it is the timestamp
// for the next vsync that will occur.
mSampleTime = aSampleTime;
}
@ -92,7 +95,25 @@ void APZSampler::SampleForWebRender(
// WebRenderBridgeParent hasn't yet provided us with a sample time.
// If we're that early there probably aren't any APZ animations happening
// anyway, so using Timestamp::Now() should be fine.
sampleTime = mSampleTime.IsNull() ? TimeStamp::Now() : mSampleTime;
//
// If mSampleTime is in the past, then this is a "delayed sampling", i.e.
// we have passed the vsync interval during which SetSampleTime was called.
// We know this because SetSampleTime is called with the timestamp for the
// next vsync (i.e. the time at which the then-ongoing vsync interval ends)
// and we expect that SampleForWebRender gets called within that same vsync
// interval. If it does not, then the SampleForWebRender call has been
// delayed. This can happen if e.g. there was a very long scene build,
// or WR decided to generate a frame after an idle period for whatever
// random reason without Gecko requesting it explicitly. In these cases
// we shouldn't use mSampleTime, because the current frame will be presented
// at the end of the *current* vsync interval rather than the vsync interval
// SetSampleTime was called in. Ideally we would be able to know when the
// *current* vsync interval ends, and use that timestamp, but pluming that
// here is hard, so instead we use Now() which will at least get us pretty
// close.
TimeStamp now = TimeStamp::Now();
sampleTime =
(mSampleTime.IsNull() || mSampleTime < now) ? now : mSampleTime;
}
mApz->SampleForWebRender(aTxn, sampleTime, aEpochsBeingRendered);
}