Bug 1739541 - Introduce APZScrollAnimationType and use it in RepaintRequest and ScrollFrameHelopr instead of a boolean representing whether there's an animation or not. r=botond

Differential Revision: https://phabricator.services.mozilla.com/D130421
This commit is contained in:
Hiroyuki Ikezoe 2021-11-09 09:19:26 +00:00
parent cd43013045
commit 9816dd2b16
8 changed files with 66 additions and 37 deletions

View File

@ -57,14 +57,14 @@ struct RepaintRequest {
mTransformToAncestorScale(),
mPaintRequestTime(),
mScrollUpdateType(eNone),
mScrollAnimationType(APZScrollAnimationType::No),
mIsRootContent(false),
mIsAnimationInProgress(false),
mIsScrollInfoLayer(false) {}
RepaintRequest(const FrameMetrics& aOther,
const ScreenMargin& aDisplayportMargins,
const ScrollOffsetUpdateType aScrollUpdateType,
bool aIsAnimationInProgress)
APZScrollAnimationType aScrollAnimationType)
: mScrollId(aOther.GetScrollId()),
mPresShellResolution(aOther.GetPresShellResolution()),
mCompositionBounds(aOther.GetCompositionBounds()),
@ -79,8 +79,8 @@ struct RepaintRequest {
mTransformToAncestorScale(aOther.GetTransformToAncestorScale()),
mPaintRequestTime(aOther.GetPaintRequestTime()),
mScrollUpdateType(aScrollUpdateType),
mScrollAnimationType(aScrollAnimationType),
mIsRootContent(aOther.IsRootContent()),
mIsAnimationInProgress(aIsAnimationInProgress),
mIsScrollInfoLayer(aOther.IsScrollInfoLayer()) {}
// Default copy ctor and operator= are fine
@ -101,8 +101,8 @@ struct RepaintRequest {
mTransformToAncestorScale == aOther.mTransformToAncestorScale &&
mPaintRequestTime == aOther.mPaintRequestTime &&
mScrollUpdateType == aOther.mScrollUpdateType &&
mScrollAnimationType == aOther.mScrollAnimationType &&
mIsRootContent == aOther.mIsRootContent &&
mIsAnimationInProgress == aOther.mIsAnimationInProgress &&
mIsScrollInfoLayer == aOther.mIsScrollInfoLayer;
}
@ -148,7 +148,9 @@ struct RepaintRequest {
return mDevPixelsPerCSSPixel;
}
bool IsAnimationInProgress() const { return mIsAnimationInProgress; }
bool IsAnimationInProgress() const {
return mScrollAnimationType != APZScrollAnimationType::No;
}
bool IsRootContent() const { return mIsRootContent; }
@ -184,11 +186,11 @@ struct RepaintRequest {
bool IsScrollInfoLayer() const { return mIsScrollInfoLayer; }
protected:
void SetIsAnimationInProgress(bool aInProgress) {
mIsAnimationInProgress = aInProgress;
APZScrollAnimationType GetScrollAnimationType() const {
return mScrollAnimationType;
}
protected:
void SetIsRootContent(bool aIsRootContent) {
mIsRootContent = aIsRootContent;
}
@ -279,12 +281,11 @@ struct RepaintRequest {
// The type of repaint request this represents.
ScrollOffsetUpdateType mScrollUpdateType;
APZScrollAnimationType mScrollAnimationType;
// Whether or not this is the root scroll frame for the root content document.
bool mIsRootContent : 1;
// Whether or not we are in the middle of a scroll animation.
bool mIsAnimationInProgress : 1;
// True if this scroll frame is a scroll info layer. A scroll info layer is
// not layerized and its content cannot be truly async-scrolled, but its
// metrics are still sent to and updated by the compositor, with the updates

View File

@ -4309,9 +4309,14 @@ void AsyncPanZoomController::RequestContentRepaint(
}
MOZ_ASSERT(controller->IsRepaintThread());
const bool isAnimationInProgress = !!mAnimation;
APZScrollAnimationType animationType = APZScrollAnimationType::No;
if (mAnimation) {
animationType = mAnimation->WasTriggeredByScript()
? APZScrollAnimationType::TriggeredByScript
: APZScrollAnimationType::TriggeredByUserInput;
}
RepaintRequest request(aFrameMetrics, aDisplayportMargins, aUpdateType,
isAnimationInProgress);
animationType);
// If we're trying to paint what we already think is painted, discard this
// request since it's a pointless paint.
@ -4328,8 +4333,8 @@ void AsyncPanZoomController::RequestContentRepaint(
mLastPaintRequestMetrics.GetScrollGeneration() &&
request.GetScrollUpdateType() ==
mLastPaintRequestMetrics.GetScrollUpdateType() &&
request.IsAnimationInProgress() ==
mLastPaintRequestMetrics.IsAnimationInProgress()) {
request.GetScrollAnimationType() ==
mLastPaintRequestMetrics.GetScrollAnimationType()) {
return;
}

View File

@ -154,7 +154,7 @@ static DisplayPortMargins ScrollFrame(nsIContent* aContent,
nsLayoutUtils::FindScrollableFrameFor(aRequest.GetScrollId());
if (sf) {
sf->ResetScrollInfoIfNeeded(aRequest.GetScrollGeneration(),
aRequest.IsAnimationInProgress());
aRequest.GetScrollAnimationType());
sf->SetScrollableByAPZ(!aRequest.IsScrollInfoLayer());
if (sf->IsRootScrollFrameOfDocument()) {
if (!APZCCallbackHelper::IsScrollInProgress(sf)) {

View File

@ -275,6 +275,12 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
}
};
template <>
struct ParamTraits<mozilla::APZScrollAnimationType>
: public ContiguousEnumSerializerInclusive<
mozilla::APZScrollAnimationType, mozilla::APZScrollAnimationType::No,
mozilla::APZScrollAnimationType::TriggeredByUserInput> {};
template <>
struct ParamTraits<mozilla::layers::RepaintRequest>
: BitfieldHelper<mozilla::layers::RepaintRequest> {
@ -295,8 +301,8 @@ struct ParamTraits<mozilla::layers::RepaintRequest>
WriteParam(aMsg, aParam.mTransformToAncestorScale);
WriteParam(aMsg, aParam.mPaintRequestTime);
WriteParam(aMsg, aParam.mScrollUpdateType);
WriteParam(aMsg, aParam.mScrollAnimationType);
WriteParam(aMsg, aParam.mIsRootContent);
WriteParam(aMsg, aParam.mIsAnimationInProgress);
WriteParam(aMsg, aParam.mIsScrollInfoLayer);
}
@ -316,10 +322,9 @@ struct ParamTraits<mozilla::layers::RepaintRequest>
ReadParam(aMsg, aIter, &aResult->mTransformToAncestorScale) &&
ReadParam(aMsg, aIter, &aResult->mPaintRequestTime) &&
ReadParam(aMsg, aIter, &aResult->mScrollUpdateType) &&
ReadParam(aMsg, aIter, &aResult->mScrollAnimationType) &&
ReadBoolForBitfield(aMsg, aIter, aResult,
&paramType::SetIsRootContent) &&
ReadBoolForBitfield(aMsg, aIter, aResult,
&paramType::SetIsAnimationInProgress) &&
ReadBoolForBitfield(aMsg, aIter, aResult,
&paramType::SetIsScrollInfoLayer));
}

View File

@ -46,6 +46,16 @@ enum class ScrollMode { Instant, Smooth, SmoothMsd, Normal };
*/
enum class ScrollUnit { DEVICE_PIXELS, LINES, PAGES, WHOLE };
/**
* Representing whether there's an on-going animation in APZC and it was
* triggered by script or by user input.
*/
enum class APZScrollAnimationType {
No, // No animation.
TriggeredByScript, // Animation triggered by script.
TriggeredByUserInput // Animation triggered by user input.
};
} // namespace mozilla
#endif // mozilla_ScrollTypes_h

View File

@ -2212,6 +2212,7 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter, bool aIsRoot)
mDisplayPortAtLastFrameUpdate(),
mScrollParentID(mozilla::layers::ScrollableLayerGuid::NULL_SCROLL_ID),
mAnchor(this),
mCurrentAPZScrollAnimationType(APZScrollAnimationType::No),
mAllowScrollOriginDowngrade(false),
mHadDisplayPortAtLastFrameUpdate(false),
mHasVerticalScrollbar(false),
@ -2243,7 +2244,6 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter, bool aIsRoot)
mIsUsingMinimumScaleSize(false),
mMinimumScaleSizeChanged(false),
mProcessingScrollEvent(false),
mApzAnimationInProgress(false),
mApzAnimationRequested(false),
mReclampVVOffsetInReflowFinished(false),
mVelocityQueue(aOuter->PresContext()) {
@ -7227,14 +7227,15 @@ bool ScrollFrameHelper::IsScrollAnimating(
}
void ScrollFrameHelper::ResetScrollInfoIfNeeded(
const ScrollGeneration& aGeneration, bool aApzAnimationInProgress) {
const ScrollGeneration& aGeneration,
APZScrollAnimationType aAPZScrollAnimationType) {
if (aGeneration == mScrollGeneration) {
mLastScrollOrigin = ScrollOrigin::None;
mApzAnimationRequested = false;
}
// We can reset this regardless of scroll generation, as this is only set
// here, as a response to APZ requesting a repaint.
mApzAnimationInProgress = aApzAnimationInProgress;
mCurrentAPZScrollAnimationType = aAPZScrollAnimationType;
}
UniquePtr<PresState> ScrollFrameHelper::SaveState() const {

View File

@ -55,6 +55,7 @@ class ScrollFrameHelper : public nsIReflowCallback {
using Layer = mozilla::layers::Layer;
using WebRenderLayerManager = mozilla::layers::WebRenderLayerManager;
using ScrollAnchorContainer = mozilla::layout::ScrollAnchorContainer;
using APZScrollAnimationType = mozilla::APZScrollAnimationType;
using Element = mozilla::dom::Element;
class AsyncScroll;
@ -480,7 +481,9 @@ class ScrollFrameHelper : public nsIReflowCallback {
void HandleScrollbarStyleSwitching();
ScrollOrigin LastScrollOrigin() const { return mLastScrollOrigin; }
bool IsApzAnimationInProgress() const { return mApzAnimationInProgress; }
bool IsApzAnimationInProgress() const {
return mCurrentAPZScrollAnimationType != APZScrollAnimationType::No;
}
ScrollGeneration CurrentScrollGeneration() const { return mScrollGeneration; }
nsPoint LastScrollDestination() const { return mDestination; }
nsTArray<ScrollPositionUpdate> GetScrollUpdates() const;
@ -491,7 +494,7 @@ class ScrollFrameHelper : public nsIReflowCallback {
bool IsScrollAnimating(IncludeApzAnimation = IncludeApzAnimation::Yes) const;
void ResetScrollInfoIfNeeded(const ScrollGeneration& aGeneration,
bool aApzAnimationInProgress);
APZScrollAnimationType aAPZScrollAnimationType);
bool WantAsyncScroll() const;
Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(
WebRenderLayerManager* aLayerManager, const nsIFrame* aItemFrame,
@ -633,6 +636,14 @@ class ScrollFrameHelper : public nsIReflowCallback {
ScrollAnchorContainer mAnchor;
// Representing there's an APZ animation is in progress and what caused the
// animation. Note that this is only set when repainted via APZ, which means
// that there may be a request for an APZ animation in flight for example,
// while this is still `No`. In order to answer "is an APZ animation in the
// process of starting or in progress" you need to check mScrollUpdates,
// mApzAnimationRequested, and this type.
APZScrollAnimationType mCurrentAPZScrollAnimationType;
bool mAllowScrollOriginDowngrade : 1;
bool mHadDisplayPortAtLastFrameUpdate : 1;
bool mHasVerticalScrollbar : 1;
@ -722,12 +733,6 @@ class ScrollFrameHelper : public nsIReflowCallback {
// True if we're processing an scroll event.
bool mProcessingScrollEvent : 1;
// Whether an APZ animation is in progress. Note that this is only set to true
// when repainted via APZ, which means that there may be a request for an APZ
// animation in flight for example, while this is still false. In order to
// answer "is an APZ animation in the process of starting or in progress" you
// need to check mScrollUpdates, mApzAnimationRequested, and this bit.
bool mApzAnimationInProgress : 1;
// This is true from the time a scroll animation is requested of APZ to the
// time that APZ responds with an up-to-date repaint request. More precisely,
// this is flipped to true if a repaint request is dispatched to APZ where
@ -1079,9 +1084,10 @@ class nsHTMLScrollFrame : public nsContainerFrame,
return mHelper.GetScrollUpdates();
}
bool HasScrollUpdates() const final { return mHelper.HasScrollUpdates(); }
void ResetScrollInfoIfNeeded(const mozilla::ScrollGeneration& aGeneration,
bool aApzAnimationInProgress) final {
mHelper.ResetScrollInfoIfNeeded(aGeneration, aApzAnimationInProgress);
void ResetScrollInfoIfNeeded(
const mozilla::ScrollGeneration& aGeneration,
mozilla::APZScrollAnimationType aAPZScrollAnimationType) final {
mHelper.ResetScrollInfoIfNeeded(aGeneration, aAPZScrollAnimationType);
}
bool WantAsyncScroll() const final { return mHelper.WantAsyncScroll(); }
mozilla::Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(
@ -1554,9 +1560,10 @@ class nsXULScrollFrame final : public nsBoxFrame,
return mHelper.GetScrollUpdates();
}
bool HasScrollUpdates() const final { return mHelper.HasScrollUpdates(); }
void ResetScrollInfoIfNeeded(const mozilla::ScrollGeneration& aGeneration,
bool aApzAnimationInProgress) final {
mHelper.ResetScrollInfoIfNeeded(aGeneration, aApzAnimationInProgress);
void ResetScrollInfoIfNeeded(
const mozilla::ScrollGeneration& aGeneration,
mozilla::APZScrollAnimationType aAPZScrollAnimationType) final {
mHelper.ResetScrollInfoIfNeeded(aGeneration, aAPZScrollAnimationType);
}
bool WantAsyncScroll() const final { return mHelper.WantAsyncScroll(); }
mozilla::Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(

View File

@ -459,7 +459,7 @@ class nsIScrollableFrame : public nsIScrollbarMediator {
*/
virtual void ResetScrollInfoIfNeeded(
const mozilla::ScrollGeneration& aGeneration,
bool aApzAnimationInProgress) = 0;
mozilla::APZScrollAnimationType aAPZScrollAnimationType) = 0;
/**
* Determine whether it is desirable to be able to asynchronously scroll this
* scroll frame.