mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1874199 - Animate sticky elements by using an animation property on the StickyFrame rather than creating a ReferenceFrame. r=gw,dlrobertson
This uses the support added in the previous patch to set an animation property on a StickyFrame spatial node directly. Depends on D208237 Differential Revision: https://phabricator.services.mozilla.com/D208238
This commit is contained in:
parent
b7116da08f
commit
4486d95678
@ -5207,7 +5207,7 @@ bool nsDisplayOwnLayer::CreateWebRenderCommands(
|
||||
Maybe<wr::WrAnimationProperty> prop;
|
||||
bool needsProp = aManager->LayerManager()->AsyncPanZoomEnabled() &&
|
||||
(IsScrollThumbLayer() || IsZoomingLayer() ||
|
||||
ShouldGetFixedOrStickyAnimationId() ||
|
||||
ShouldGetFixedAnimationId() ||
|
||||
(IsRootScrollbarContainer() && HasDynamicToolbar()));
|
||||
|
||||
if (needsProp) {
|
||||
@ -5234,7 +5234,7 @@ bool nsDisplayOwnLayer::CreateWebRenderCommands(
|
||||
params.prim_flags |= wr::PrimitiveFlags::IS_SCROLLBAR_CONTAINER;
|
||||
}
|
||||
if (IsZoomingLayer() ||
|
||||
(ShouldGetFixedOrStickyAnimationId() ||
|
||||
(ShouldGetFixedAnimationId() ||
|
||||
(IsRootScrollbarContainer() && HasDynamicToolbar()))) {
|
||||
params.is_2d_scale_translation = true;
|
||||
params.should_snap = true;
|
||||
@ -5250,9 +5250,8 @@ bool nsDisplayOwnLayer::CreateWebRenderCommands(
|
||||
|
||||
bool nsDisplayOwnLayer::UpdateScrollData(WebRenderScrollData* aData,
|
||||
WebRenderLayerScrollData* aLayerData) {
|
||||
bool isRelevantToApz =
|
||||
(IsScrollThumbLayer() || IsScrollbarContainer() || IsZoomingLayer() ||
|
||||
ShouldGetFixedOrStickyAnimationId());
|
||||
bool isRelevantToApz = (IsScrollThumbLayer() || IsScrollbarContainer() ||
|
||||
IsZoomingLayer() || ShouldGetFixedAnimationId());
|
||||
|
||||
if (!isRelevantToApz) {
|
||||
return false;
|
||||
@ -5267,16 +5266,11 @@ bool nsDisplayOwnLayer::UpdateScrollData(WebRenderScrollData* aData,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsFixedPositionLayer() && ShouldGetFixedOrStickyAnimationId()) {
|
||||
if (IsFixedPositionLayer() && ShouldGetFixedAnimationId()) {
|
||||
aLayerData->SetFixedPositionAnimationId(mWrAnimationId);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsStickyPositionLayer() && ShouldGetFixedOrStickyAnimationId()) {
|
||||
aLayerData->SetStickyPositionAnimationId(mWrAnimationId);
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(IsScrollbarContainer() || IsScrollThumbLayer());
|
||||
|
||||
aLayerData->SetScrollbarData(mScrollbarData);
|
||||
@ -5458,7 +5452,7 @@ bool nsDisplayFixedPosition::UpdateScrollData(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nsDisplayFixedPosition::ShouldGetFixedOrStickyAnimationId() {
|
||||
bool nsDisplayFixedPosition::ShouldGetFixedAnimationId() {
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
return mFrame->PresContext()->IsRootContentDocumentCrossProcess() &&
|
||||
nsLayoutUtils::ScrollIdForRootScrollFrame(mFrame->PresContext()) ==
|
||||
@ -5522,7 +5516,8 @@ nsDisplayStickyPosition::nsDisplayStickyPosition(
|
||||
: nsDisplayOwnLayer(aBuilder, aFrame, aList, aActiveScrolledRoot),
|
||||
mContainerASR(aContainerASR),
|
||||
mClippedToDisplayPort(aClippedToDisplayPort),
|
||||
mShouldFlatten(false) {
|
||||
mShouldFlatten(false),
|
||||
mWrStickyAnimationId(0) {
|
||||
MOZ_COUNT_CTOR(nsDisplayStickyPosition);
|
||||
}
|
||||
|
||||
@ -5738,13 +5733,27 @@ bool nsDisplayStickyPosition::CreateWebRenderCommands(
|
||||
wr::LayoutVector2D applied = {
|
||||
NSAppUnitsToFloatPixels(appliedOffset.x, auPerDevPixel),
|
||||
NSAppUnitsToFloatPixels(appliedOffset.y, auPerDevPixel)};
|
||||
bool needsProp = ShouldGetStickyAnimationId();
|
||||
Maybe<wr::WrAnimationProperty> prop;
|
||||
auto spatialKey = wr::SpatialKey(uint64_t(mFrame), GetPerFrameKey(),
|
||||
wr::SpatialKeyKind::Sticky);
|
||||
if (needsProp) {
|
||||
RefPtr<WebRenderAPZAnimationData> animationData =
|
||||
aManager->CommandBuilder()
|
||||
.CreateOrRecycleWebRenderUserData<WebRenderAPZAnimationData>(
|
||||
this);
|
||||
mWrStickyAnimationId = animationData->GetAnimationId();
|
||||
|
||||
prop.emplace();
|
||||
prop->id = mWrStickyAnimationId;
|
||||
prop->key = spatialKey;
|
||||
prop->effect_type = wr::WrAnimationType::Transform;
|
||||
}
|
||||
wr::WrSpatialId spatialId = aBuilder.DefineStickyFrame(
|
||||
wr::ToLayoutRect(bounds), topMargin.ptrOr(nullptr),
|
||||
rightMargin.ptrOr(nullptr), bottomMargin.ptrOr(nullptr),
|
||||
leftMargin.ptrOr(nullptr), vBounds, hBounds, applied,
|
||||
wr::SpatialKey(uint64_t(mFrame), GetPerFrameKey(),
|
||||
wr::SpatialKeyKind::Sticky),
|
||||
nullptr);
|
||||
leftMargin.ptrOr(nullptr), vBounds, hBounds, applied, spatialKey,
|
||||
prop.ptrOr(nullptr));
|
||||
|
||||
saccHelper.emplace(aBuilder, spatialId);
|
||||
aManager->CommandBuilder().PushOverrideForASR(mContainerASR, spatialId);
|
||||
@ -5813,6 +5822,10 @@ bool nsDisplayStickyPosition::UpdateScrollData(
|
||||
->GetContent());
|
||||
aLayerData->SetStickyPositionScrollContainerId(scrollId);
|
||||
}
|
||||
|
||||
if (ShouldGetStickyAnimationId()) {
|
||||
aLayerData->SetStickyPositionAnimationId(mWrStickyAnimationId);
|
||||
}
|
||||
}
|
||||
// Return true if either there is a dynamic toolbar affecting this sticky
|
||||
// item or the OwnLayer base implementation returns true for some other
|
||||
@ -5822,10 +5835,11 @@ bool nsDisplayStickyPosition::UpdateScrollData(
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool nsDisplayStickyPosition::ShouldGetFixedOrStickyAnimationId() {
|
||||
bool nsDisplayStickyPosition::ShouldGetStickyAnimationId() const {
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
if (HasDynamicToolbar()) { // also implies being in the cross-process RCD
|
||||
StickyScrollContainer* stickyScrollContainer = GetStickyScrollContainer();
|
||||
StickyScrollContainer* stickyScrollContainer =
|
||||
const_cast<nsDisplayStickyPosition*>(this)->GetStickyScrollContainer();
|
||||
if (stickyScrollContainer) {
|
||||
ScrollableLayerGuid::ViewID scrollId =
|
||||
nsLayoutUtils::FindOrCreateIDFor(stickyScrollContainer->ScrollFrame()
|
||||
|
@ -5475,7 +5475,7 @@ class nsDisplayOwnLayer : public nsDisplayWrapList {
|
||||
bool IsFixedPositionLayer() const;
|
||||
bool IsStickyPositionLayer() const;
|
||||
bool HasDynamicToolbar() const;
|
||||
virtual bool ShouldGetFixedOrStickyAnimationId() { return false; }
|
||||
virtual bool ShouldGetFixedAnimationId() { return false; }
|
||||
|
||||
bool CreatesStackingContextHelper() override { return true; }
|
||||
|
||||
@ -5491,6 +5491,16 @@ class nsDisplayOwnLayer : public nsDisplayWrapList {
|
||||
*/
|
||||
layers::ScrollbarData mScrollbarData;
|
||||
bool mForceActive;
|
||||
|
||||
// Used for APZ to animate this layer for purposes such as
|
||||
// pinch-zooming or scrollbar thumb movement. Note that setting this
|
||||
// creates a WebRender ReferenceFrame spatial node, and should only
|
||||
// be used for display items that establish a Gecko reference frame
|
||||
// as well (or leaf items like scrollbar thumb nodes where it does not
|
||||
// matter).
|
||||
// FIXME: This is currently also used for adjusting position:fixed items
|
||||
// for dynamic toolbar movement. This may be a problem as position:fixed
|
||||
// items do not establish Gecko reference frames.
|
||||
uint64_t mWrAnimationId;
|
||||
};
|
||||
|
||||
@ -5550,7 +5560,8 @@ class nsDisplayStickyPosition : public nsDisplayOwnLayer {
|
||||
: nsDisplayOwnLayer(aBuilder, aOther),
|
||||
mContainerASR(aOther.mContainerASR),
|
||||
mClippedToDisplayPort(aOther.mClippedToDisplayPort),
|
||||
mShouldFlatten(false) {
|
||||
mShouldFlatten(false),
|
||||
mWrStickyAnimationId(0) {
|
||||
MOZ_COUNT_CTOR(nsDisplayStickyPosition);
|
||||
}
|
||||
|
||||
@ -5575,7 +5586,6 @@ class nsDisplayStickyPosition : public nsDisplayOwnLayer {
|
||||
|
||||
bool UpdateScrollData(layers::WebRenderScrollData* aData,
|
||||
layers::WebRenderLayerScrollData* aLayerData) override;
|
||||
bool ShouldGetFixedOrStickyAnimationId() override;
|
||||
|
||||
const ActiveScrolledRoot* GetContainerASR() const { return mContainerASR; }
|
||||
|
||||
@ -5591,6 +5601,8 @@ class nsDisplayStickyPosition : public nsDisplayOwnLayer {
|
||||
return mShouldFlatten;
|
||||
}
|
||||
|
||||
bool ShouldGetStickyAnimationId() const;
|
||||
|
||||
private:
|
||||
NS_DISPLAY_ALLOW_CLONING()
|
||||
|
||||
@ -5620,6 +5632,13 @@ class nsDisplayStickyPosition : public nsDisplayOwnLayer {
|
||||
|
||||
// True if this item should be flattened away.
|
||||
bool mShouldFlatten;
|
||||
|
||||
// Used for APZ to animate the sticky element in the compositor
|
||||
// for purposes such as dynamic toolbar movement and (in the future)
|
||||
// overscroll-related adjustment. Unlike nsDisplayOwnLayer::mWrAnimationId,
|
||||
// this does not create a WebRender ReferenceFrame, which is important
|
||||
// because sticky elements do not establish Gecko reference frames either.
|
||||
uint64_t mWrStickyAnimationId;
|
||||
};
|
||||
|
||||
class nsDisplayFixedPosition : public nsDisplayOwnLayer {
|
||||
@ -5661,7 +5680,7 @@ class nsDisplayFixedPosition : public nsDisplayOwnLayer {
|
||||
nsDisplayListBuilder* aDisplayListBuilder) override;
|
||||
bool UpdateScrollData(layers::WebRenderScrollData* aData,
|
||||
layers::WebRenderLayerScrollData* aLayerData) override;
|
||||
bool ShouldGetFixedOrStickyAnimationId() override;
|
||||
bool ShouldGetFixedAnimationId() override;
|
||||
void WriteDebugInfo(std::stringstream& aStream) override;
|
||||
|
||||
protected:
|
||||
|
Loading…
Reference in New Issue
Block a user