Bug 1187804 - Annotate fixed-position layers with the scroll id of the scroll frame that they are fixed with respect to. r=mattwoodrow
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -214,17 +214,17 @@ Layer::Layer(LayerManager* aManager, voi
mPostXScale(1.0f),
mPostYScale(1.0f),
mOpacity(1.0),
mMixBlendMode(CompositionOp::OP_OVER),
mForceIsolatedGroup(false),
mContentFlags(0),
mUseTileSourceRect(false),
mIsFixedPosition(false),
- mMargins(0, 0, 0, 0),
+ mFixedPositionData(nullptr),
mStickyPositionData(nullptr),
mScrollbarTargetId(FrameMetrics::NULL_SCROLL_ID),
mScrollbarDirection(ScrollDirection::NONE),
mScrollbarThumbRatio(0.0f),
mIsScrollbarContainer(false),
mDebugColorIndex(0),
mAnimationGeneration(0)
{
@@ -1696,19 +1696,22 @@ Layer::PrintInfo(std::stringstream& aStr
}
if (GetScrollbarDirection() == VERTICAL) {
aStream << nsPrintfCString(" [vscrollbar=%lld]", GetScrollbarTargetContainerId()).get();
}
if (GetScrollbarDirection() == HORIZONTAL) {
aStream << nsPrintfCString(" [hscrollbar=%lld]", GetScrollbarTargetContainerId()).get();
}
if (GetIsFixedPosition()) {
- aStream << nsPrintfCString(" [isFixedPosition anchor=%s margin=%f,%f,%f,%f]",
- ToString(mAnchor).c_str(),
- mMargins.top, mMargins.right, mMargins.bottom, mMargins.left).get();
+ LayerPoint anchor = GetFixedPositionAnchor();
+ LayerMargin margin = GetFixedPositionMargins();
+ aStream << nsPrintfCString(" [isFixedPosition scrollId=%d anchor=%s margin=%f,%f,%f,%f]",
+ GetFixedPositionScrollContainerId(),
+ ToString(anchor).c_str(),
+ margin.top, margin.right, margin.bottom, margin.left).get();
}
if (GetIsStickyPosition()) {
aStream << nsPrintfCString(" [isStickyPosition scrollId=%d outer=%f,%f %fx%f "
"inner=%f,%f %fx%f]", mStickyPositionData->mScrollId,
mStickyPositionData->mOuter.x, mStickyPositionData->mOuter.y,
mStickyPositionData->mOuter.width, mStickyPositionData->mOuter.height,
mStickyPositionData->mInner.x, mStickyPositionData->mInner.y,
mStickyPositionData->mInner.width, mStickyPositionData->mInner.height).get();
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1143,48 +1143,31 @@ public:
// These are a parallel to AddAnimation and clearAnimations, except
// they add pending animations that apply only when the next
// transaction is begun. (See also
// SetBaseTransformForNextTransaction.)
Animation* AddAnimationForNextTransaction();
void ClearAnimationsForNextTransaction();
- /**
- * CONSTRUCTION PHASE ONLY
- * If a layer is "fixed position", this determines which point on the layer
- * is considered the "anchor" point, that is, the point which remains in the
- * same position when compositing the layer tree with a transformation
- * (such as when asynchronously scrolling and zooming).
- */
- void SetFixedPositionAnchor(const LayerPoint& aAnchor)
+ void SetFixedPositionData(FrameMetrics::ViewID aScrollId,
+ const LayerPoint& aAnchor,
+ const LayerMargin& aMargins)
{
- if (mAnchor != aAnchor) {
- MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FixedPositionAnchor", this));
- mAnchor = aAnchor;
- Mutated();
- }
- }
-
- /**
- * CONSTRUCTION PHASE ONLY
- * If a layer represents a fixed position element or elements that are on
- * a document that has had fixed position element margins set on it, these
- * will be mirrored here. This allows for asynchronous animation of the
- * margins by reconciling the difference between this value and a value that
- * is updated more frequently.
- * If the left or top margins are negative, it means that the elements this
- * layer represents are auto-positioned, and so fixed position margins should
- * not have an effect on the corresponding axis.
- */
- void SetFixedPositionMargins(const LayerMargin& aMargins)
- {
- if (mMargins != aMargins) {
- MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FixedPositionMargins", this));
- mMargins = aMargins;
+ if (!mFixedPositionData ||
+ mFixedPositionData->mScrollId != aScrollId ||
+ mFixedPositionData->mAnchor != aAnchor ||
+ mFixedPositionData->mMargins != aMargins) {
+ MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FixedPositionData", this));
+ if (!mFixedPositionData) {
+ mFixedPositionData = new FixedPositionData;
+ }
+ mFixedPositionData->mScrollId = aScrollId;
+ mFixedPositionData->mAnchor = aAnchor;
+ mFixedPositionData->mMargins = aMargins;
Mutated();
}
}
/**
* CONSTRUCTION PHASE ONLY
* If a layer is "sticky position", |aScrollId| holds the scroll identifier
* of the scrollable content that contains it. The difference between the two
@@ -1266,18 +1249,19 @@ public:
virtual Layer* GetLastChild() const { return nullptr; }
const gfx::Matrix4x4 GetTransform() const;
const gfx::Matrix4x4& GetBaseTransform() const { return mTransform; }
// Note: these are virtual because ContainerLayerComposite overrides them.
virtual float GetPostXScale() const { return mPostXScale; }
virtual float GetPostYScale() const { return mPostYScale; }
bool GetIsFixedPosition() { return mIsFixedPosition; }
bool GetIsStickyPosition() { return mStickyPositionData; }
- LayerPoint GetFixedPositionAnchor() { return mAnchor; }
- const LayerMargin& GetFixedPositionMargins() { return mMargins; }
+ FrameMetrics::ViewID GetFixedPositionScrollContainerId() { return mFixedPositionData ? mFixedPositionData->mScrollId : FrameMetrics::NULL_SCROLL_ID; }
+ LayerPoint GetFixedPositionAnchor() { return mFixedPositionData ? mFixedPositionData->mAnchor : LayerPoint(); }
+ LayerMargin GetFixedPositionMargins() { return mFixedPositionData ? mFixedPositionData->mMargins : LayerMargin(); }
FrameMetrics::ViewID GetStickyScrollContainerId() { return mStickyPositionData->mScrollId; }
const LayerRect& GetStickyScrollRangeOuter() { return mStickyPositionData->mOuter; }
const LayerRect& GetStickyScrollRangeInner() { return mStickyPositionData->mInner; }
FrameMetrics::ViewID GetScrollbarTargetContainerId() { return mScrollbarTargetId; }
ScrollDirection GetScrollbarDirection() { return mScrollbarDirection; }
float GetScrollbarThumbRatio() { return mScrollbarThumbRatio; }
bool IsScrollbarContainer() { return mIsScrollbarContainer; }
Layer* GetMaskLayer() const { return mMaskLayer; }
@@ -1768,18 +1752,22 @@ protected:
bool mForceIsolatedGroup;
Maybe<ParentLayerIntRect> mClipRect;
gfx::IntRect mTileSourceRect;
nsIntRegion mInvalidRegion;
nsTArray<nsRefPtr<AsyncPanZoomController> > mApzcs;
uint32_t mContentFlags;
bool mUseTileSourceRect;
bool mIsFixedPosition;
- LayerPoint mAnchor;
- LayerMargin mMargins;
+ struct FixedPositionData {
+ FrameMetrics::ViewID mScrollId;
+ LayerPoint mAnchor;
+ LayerMargin mMargins;
+ };
+ nsAutoPtr<FixedPositionData> mFixedPositionData;
struct StickyPositionData {
FrameMetrics::ViewID mScrollId;
LayerRect mOuter;
LayerRect mInner;
};
nsAutoPtr<StickyPositionData> mStickyPositionData;
FrameMetrics::ViewID mScrollbarTargetId;
ScrollDirection mScrollbarDirection;
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -322,18 +322,21 @@ LayerTransactionParent::RecvUpdate(Infal
layer->SetVisibleRegion(common.visibleRegion());
layer->SetEventRegions(common.eventRegions());
layer->SetContentFlags(common.contentFlags());
layer->SetOpacity(common.opacity());
layer->SetClipRect(common.useClipRect() ? Some(common.clipRect()) : Nothing());
layer->SetBaseTransform(common.transform().value());
layer->SetPostScale(common.postXScale(), common.postYScale());
layer->SetIsFixedPosition(common.isFixedPosition());
- layer->SetFixedPositionAnchor(common.fixedPositionAnchor());
- layer->SetFixedPositionMargins(common.fixedPositionMargin());
+ if (common.isFixedPosition()) {
+ layer->SetFixedPositionData(common.fixedPositionScrollContainerId(),
+ common.fixedPositionAnchor(),
+ common.fixedPositionMargin());
+ }
if (common.isStickyPosition()) {
layer->SetStickyPositionData(common.stickyScrollContainerId(),
common.stickyScrollRangeOuter(),
common.stickyScrollRangeInner());
}
layer->SetScrollbarData(common.scrollbarTargetContainerId(),
static_cast<Layer::ScrollDirection>(common.scrollbarDirection()),
common.scrollbarThumbRatio());
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -210,16 +210,17 @@ struct CommonLayerAttributes {
TransformMatrix transform;
float postXScale;
float postYScale;
uint32_t contentFlags;
float opacity;
bool useClipRect;
ParentLayerIntRect clipRect;
bool isFixedPosition;
+ uint64_t fixedPositionScrollContainerId;
LayerPoint fixedPositionAnchor;
LayerMargin fixedPositionMargin;
bool isStickyPosition;
uint64_t stickyScrollContainerId;
LayerRect stickyScrollRangeOuter;
LayerRect stickyScrollRangeInner;
uint64_t scrollbarTargetContainerId;
uint32_t scrollbarDirection;
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -574,18 +574,21 @@ ShadowLayerForwarder::EndTransaction(Inf
common.postYScale() = mutant->GetPostYScale();
common.transform() = mutant->GetBaseTransform();
common.contentFlags() = mutant->GetContentFlags();
common.opacity() = mutant->GetOpacity();
common.useClipRect() = !!mutant->GetClipRect();
common.clipRect() = (common.useClipRect() ?
*mutant->GetClipRect() : ParentLayerIntRect());
common.isFixedPosition() = mutant->GetIsFixedPosition();
- common.fixedPositionAnchor() = mutant->GetFixedPositionAnchor();
- common.fixedPositionMargin() = mutant->GetFixedPositionMargins();
+ if (mutant->GetIsFixedPosition()) {
+ common.fixedPositionScrollContainerId() = mutant->GetFixedPositionScrollContainerId();
+ common.fixedPositionAnchor() = mutant->GetFixedPositionAnchor();
+ common.fixedPositionMargin() = mutant->GetFixedPositionMargins();
+ }
common.isStickyPosition() = mutant->GetIsStickyPosition();
if (mutant->GetIsStickyPosition()) {
common.stickyScrollContainerId() = mutant->GetStickyScrollContainerId();
common.stickyScrollRangeOuter() = mutant->GetStickyScrollRangeOuter();
common.stickyScrollRangeInner() = mutant->GetStickyScrollRangeInner();
} else {
#ifdef MOZ_VALGRIND
// Initialize these so that Valgrind doesn't complain when we send them
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1779,18 +1779,23 @@ nsLayoutUtils::SetFixedPositionLayerData
fixedLayerMargins.left = -1;
}
if (position->mOffset.GetTopUnit() == eStyleUnit_Auto &&
position->mOffset.GetBottomUnit() == eStyleUnit_Auto) {
fixedLayerMargins.top = -1;
}
}
- aLayer->SetFixedPositionAnchor(anchor);
- aLayer->SetFixedPositionMargins(fixedLayerMargins);
+ ViewID id = FrameMetrics::NULL_SCROLL_ID;
+ if (nsIFrame* rootScrollFrame = aPresContext->PresShell()->GetRootScrollFrame()) {
+ if (nsIContent* content = rootScrollFrame->GetContent()) {
+ id = FindOrCreateIDFor(content);
+ }
+ }
+ aLayer->SetFixedPositionData(id, anchor, fixedLayerMargins);
}
bool
nsLayoutUtils::ViewportHasDisplayPort(nsPresContext* aPresContext, nsRect* aDisplayPort)
{
nsIFrame* rootScrollFrame =
aPresContext->PresShell()->GetRootScrollFrame();
return rootScrollFrame &&