Bug 1630781 - Allow mSampledState to temporarily hold more than one state. r=botond

Again, functionally this is a no-op since instead of replacing the back()
element, we do an emplace_back() followed by a pop_front().

Differential Revision: https://phabricator.services.mozilla.com/D72044
This commit is contained in:
Kartikaya Gupta 2020-04-27 01:02:34 +00:00
parent 6041ceee66
commit ead6b2732c
2 changed files with 53 additions and 12 deletions

View File

@ -3984,6 +3984,7 @@ bool AsyncPanZoomController::UpdateAnimation(
// call this after the |mLastSampleTime == aSampleTime| check, to ensure
// it's only called once per APZC on each composite.
bool needComposite = SampleCompositedAsyncTransform(aProofOfLock);
AdvanceToNextSample();
TimeDuration sampleTimeDelta = aSampleTime - mLastSampleTime;
mLastSampleTime = aSampleTime;
@ -4199,15 +4200,29 @@ CSSToParentLayerScale2D AsyncPanZoomController::GetEffectiveZoom(
return Metrics().GetZoom();
}
void AsyncPanZoomController::AdvanceToNextSample() {
AssertOnSamplerThread();
RecursiveMutexAutoLock lock(mRecursiveMutex);
// Always keep at least one state in mSampledState.
if (mSampledState.size() > 1) {
mSampledState.pop_front();
}
}
bool AsyncPanZoomController::SampleCompositedAsyncTransform(
const RecursiveMutexAutoLock& aProofOfLock) {
MOZ_ASSERT(mSampledState.size() == 1);
if (mSampledState.back() != SampledAPZCState(Metrics())) {
mSampledState.back() =
SampledAPZCState(Metrics(), std::move(mScrollPayload));
return true;
}
return false;
bool sampleChanged = (mSampledState.back() != SampledAPZCState(Metrics()));
mSampledState.emplace_back(Metrics(), std::move(mScrollPayload));
return sampleChanged;
}
void AsyncPanZoomController::ResampleCompositedAsyncTransform(
const RecursiveMutexAutoLock& aProofOfLock) {
// This only gets called during testing situations, so the fact that this
// drops the scroll payload from mSampledState.front() is not really a
// problem.
mSampledState.front() = SampledAPZCState(Metrics());
}
void AsyncPanZoomController::ApplyAsyncTestAttributes(
@ -4215,9 +4230,16 @@ void AsyncPanZoomController::ApplyAsyncTestAttributes(
if (mTestAttributeAppliers == 0) {
if (mTestAsyncScrollOffset != CSSPoint() ||
mTestAsyncZoom != LayerToParentLayerScale()) {
// TODO Currently we update Metrics() and resample, which will cause
// the very latest user input to get immediately captured in the sample,
// and may defeat our attempt at "frame delay" (i.e. delaying the user
// input from affecting composition by one frame).
// Instead, maybe we should just apply the mTest* stuff directly to
// mSampledState.front(). We can even save/restore that SampledAPZCState
// instance in the AutoApplyAsyncTestAttributes instead of Metrics().
Metrics().ZoomBy(mTestAsyncZoom.scale);
ScrollBy(mTestAsyncScrollOffset);
SampleCompositedAsyncTransform(aProofOfLock);
ResampleCompositedAsyncTransform(aProofOfLock);
}
}
++mTestAttributeAppliers;
@ -4232,7 +4254,7 @@ void AsyncPanZoomController::UnapplyAsyncTestAttributes(
if (mTestAsyncScrollOffset != CSSPoint() ||
mTestAsyncZoom != LayerToParentLayerScale()) {
Metrics() = aPrevFrameMetrics;
SampleCompositedAsyncTransform(aProofOfLock);
ResampleCompositedAsyncTransform(aProofOfLock);
}
}
}

View File

@ -961,7 +961,7 @@ class AsyncPanZoomController {
FrameMetrics mExpectedGeckoMetrics;
// This holds important state from the Metrics() at previous times
// SampleCompositedAsyncTransform() was called. This will always have exactly
// SampleCompositedAsyncTransform() was called. This will always have at least
// one item. mRecursiveMutex must be held when using or modifying this member.
// Samples should be inserted to the "back" of the deque and extracted from
// the "front".
@ -1143,16 +1143,35 @@ class AsyncPanZoomController {
private:
/**
* Samples the composited async transform, making the result of
* Advances to the next sample, if there is one, the list of sampled states
* stored in mSampledState. This will make the result of
* |GetCurrentAsyncTransform(eForCompositing)| and similar functions reflect
* the async scroll offset and zoom stored in |Metrics()|.
* the async scroll offset and zoom of the next sample. See also
* SampleCompositedAsyncTransform which creates the samples.
*/
void AdvanceToNextSample();
/**
* Samples the composited async transform, storing the result into
* mSampledState. This will make the result of
* |GetCurrentAsyncTransform(eForCompositing)| and similar functions reflect
* the async scroll offset and zoom stored in |Metrics()| when the sample
* is activated via some future call to |AdvanceToNextSample|.
*
* Returns true if the newly sampled value is different from the previously
* Returns true if the newly sampled value is different from the last
* sampled value.
*/
bool SampleCompositedAsyncTransform(
const RecursiveMutexAutoLock& aProofOfLock);
/**
* Updates the sample at the front of mSampledState with the latest
* metrics. This makes the result of
* |GetCurrentAsyncTransform(eForCompositing)| reflect the current Metrics().
*/
void ResampleCompositedAsyncTransform(
const RecursiveMutexAutoLock& aProofOfLock);
/*
* Helper functions to query the async layout viewport, scroll offset, and
* zoom either directly from |Metrics()|, or from cached variables that