Bug 1658205 - Don't sample APZ post webrender scene build. r=botond,nical

Conceptually we should only sample APZ on frame build, never on scene
build. When a late scene build occured, this unnecessary sample was
the underlying cause of the non-monotonic sample times as seen in bug
1653796. The fix for bug 1653796 introduced non-vsync-aligned sample
times to work around this, but these lead to inconsistent scroll
deltas during fling animations, appearing as janky scrolling on
Android.

This patch fixes the underling issue, by removing the sample after
scene building. This means we no longer hit the case where sample
times are in the past after a late scene build, allowing us to revert
bug 1653796 to ensure that sample times remain vsync-aligned.

Differential Revision: https://phabricator.services.mozilla.com/D106414
This commit is contained in:
Jamie Nicol 2021-03-01 09:00:00 +00:00
Родитель e22533b070
Коммит 226a216318
2 изменённых файлов: 2 добавлений и 25 удалений

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

@ -96,31 +96,8 @@ void APZSampler::SampleForWebRender(const Maybe<VsyncId>& aVsyncId,
// 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.
//
// 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 plumbing that
// here is hard, so instead we use Now() which will at least get us pretty
// close.
// The exception is if we're in a test situation, where the test is
// expecting us to use a specific timestamp and we shouldn't arbitrarily
// fiddle with it.
SampleTime now = SampleTime::FromNow();
sampleTime =
(mSampleTime.IsNull() ||
(mSampleTime.Type() != SampleTime::eTest && mSampleTime < now))
? now
: mSampleTime;
sampleTime = mSampleTime.IsNull() ? now : mSampleTime;
}
mApz->SampleForWebRender(aVsyncId, aTxn, sampleTime);
}

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

@ -1437,7 +1437,7 @@ impl RenderBackend {
// fiddle with things after a potentially long scene build, but just
// before rendering. This is useful for rendering with the latest
// async transforms.
if requested_frame || has_built_scene {
if requested_frame {
if let Some(ref sampler) = self.sampler {
frame_ops.append(&mut sampler.sample(document_id, generated_frame_id));
}