Bug 1267438 - Give layers an optional scrolled clip that is scrolled by all scroll frames associated with the layer. r=mstange
MozReview-Commit-ID: EGqVZuISSZQ
--- a/gfx/layers/FrameMetrics.h
+++ b/gfx/layers/FrameMetrics.h
@@ -720,16 +720,18 @@ public:
private:
ParentLayerIntRect mClipRect;
// Optionally, specifies a mask layer that's part of the clip.
// This is an index into the MetricsMaskLayers array on the Layer.
Maybe<size_t> mMaskLayerIndex;
};
+typedef Maybe<LayerClip> MaybeLayerClip; // for passing over IPDL
+
/**
* Metadata about a scroll frame that's stored in the layer tree for use by
* the compositor (including APZ). This includes the scroll frame's FrameMetrics,
* as well as other metadata. We don't put the other metadata into FrameMetrics
* to avoid FrameMetrics becoming too bloated (as a FrameMetrics is e.g. sent
* over IPC for every repaint request for every active scroll frame).
*/
struct ScrollMetadata {
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -1103,16 +1103,18 @@ Layer::GetVisibleRegionRelativeToRootLay
return true;
}
Maybe<ParentLayerIntRect>
Layer::GetCombinedClipRect() const
{
Maybe<ParentLayerIntRect> clip = GetClipRect();
+ clip = IntersectMaybeRects(clip, GetScrolledClipRect());
+
for (size_t i = 0; i < mScrollMetadata.Length(); i++) {
clip = IntersectMaybeRects(clip, mScrollMetadata[i].GetClipRect());
}
return clip;
}
ContainerLayer::ContainerLayer(LayerManager* aManager, void* aImplData)
@@ -1905,16 +1907,19 @@ Layer::PrintInfo(std::stringstream& aStr
aStream << aPrefix;
aStream << nsPrintfCString("%s%s (0x%p)", mManager->Name(), Name(), this).get();
layers::PrintInfo(aStream, AsLayerComposite());
if (mClipRect) {
AppendToString(aStream, *mClipRect, " [clip=", "]");
}
+ if (mScrolledClip) {
+ AppendToString(aStream, mScrolledClip->GetClipRect(), " [scrolled-clip=", "]");
+ }
if (1.0 != mPostXScale || 1.0 != mPostYScale) {
aStream << nsPrintfCString(" [postScale=%g, %g]", mPostXScale, mPostYScale).get();
}
if (!mTransform.IsIdentity()) {
AppendToString(aStream, mTransform, " [transform=", "]");
}
if (!GetEffectiveTransform().IsIdentity()) {
AppendToString(aStream, GetEffectiveTransform(), " [effective-transform=", "]");
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1032,16 +1032,36 @@ public:
mClipRect = aRect;
Mutated();
}
}
}
/**
* CONSTRUCTION PHASE ONLY
+ * Set an optional scrolled clip on the layer.
+ * The scrolled clip, if present, consists of a clip rect and an optional mask.
+ * This scrolled clip is always scrolled by all scroll frames associated with
+ * this layer. (By contrast, the scroll clips stored in ScrollMetadata are
+ * only scrolled by scroll frames above that ScrollMetadata, and the layer's
+ * mClipRect is always fixed to the layer contents (which may or may not be
+ * scrolled by some of the scroll frames associated with the layer, depending
+ * on whether the layer is fixed).)
+ */
+ void SetScrolledClip(const Maybe<LayerClip>& aScrolledClip)
+ {
+ if (mScrolledClip != aScrolledClip) {
+ MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScrolledClip", this));
+ mScrolledClip = aScrolledClip;
+ Mutated();
+ }
+ }
+
+ /**
+ * CONSTRUCTION PHASE ONLY
* Set a layer to mask this layer.
*
* The mask layer should be applied using its effective transform (after it
* is calculated by ComputeEffectiveTransformForMaskLayer), this should use
* this layer's parent's transform and the mask layer's transform, but not
* this layer's. That is, the mask layer is specified relative to this layer's
* position in it's parent layer's coord space.
* Currently, only 2D translations are supported for the mask layer transform.
@@ -1276,16 +1296,17 @@ public:
Mutated();
}
}
// These getters can be used anytime.
float GetOpacity() { return mOpacity; }
gfx::CompositionOp GetMixBlendMode() const { return mMixBlendMode; }
const Maybe<ParentLayerIntRect>& GetClipRect() const { return mClipRect; }
+ const Maybe<LayerClip>& GetScrolledClip() const { return mScrolledClip; }
uint32_t GetContentFlags() { return mContentFlags; }
const gfx::IntRect& GetLayerBounds() const { return mLayerBounds; }
const LayerIntRegion& GetVisibleRegion() const { return mVisibleRegion; }
const ScrollMetadata& GetScrollMetadata(uint32_t aIndex) const;
const FrameMetrics& GetFrameMetrics(uint32_t aIndex) const;
uint32_t GetScrollMetadataCount() const { return mScrollMetadata.Length(); }
const nsTArray<ScrollMetadata>& GetAllScrollMetadata() { return mScrollMetadata; }
bool HasScrollableFrameMetrics() const;
@@ -1845,16 +1866,17 @@ protected:
AnimationArray mAnimations;
// See mPendingTransform above.
nsAutoPtr<AnimationArray> mPendingAnimations;
InfallibleTArray<AnimData> mAnimationData;
float mOpacity;
gfx::CompositionOp mMixBlendMode;
bool mForceIsolatedGroup;
Maybe<ParentLayerIntRect> mClipRect;
+ Maybe<LayerClip> mScrolledClip;
gfx::IntRect mTileSourceRect;
gfx::TiledIntRegion mInvalidRegion;
nsTArray<RefPtr<AsyncPanZoomController> > mApzcs;
uint32_t mContentFlags;
bool mUseTileSourceRect;
bool mIsFixedPosition;
bool mTransformIsPerspective;
struct FixedPositionData {
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -338,16 +338,17 @@ LayerTransactionParent::RecvUpdate(Infal
const CommonLayerAttributes& common = attrs.common();
layer->SetLayerBounds(common.layerBounds());
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->SetScrolledClip(common.scrolledClip());
layer->SetBaseTransform(common.transform().value());
layer->SetTransformIsPerspective(common.transformIsPerspective());
layer->SetPostScale(common.postXScale(), common.postYScale());
layer->SetIsFixedPosition(common.isFixedPosition());
if (common.isFixedPosition()) {
layer->SetFixedPositionData(common.fixedPositionScrollContainerId(),
common.fixedPositionAnchor(),
common.fixedPositionSides(),
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -40,16 +40,17 @@ using mozilla::LayoutDeviceIntRect from
using mozilla::layers::ScaleMode from "mozilla/layers/LayersTypes.h";
using mozilla::layers::EventRegions from "mozilla/layers/LayersTypes.h";
using mozilla::layers::EventRegionsOverride from "mozilla/layers/LayersTypes.h";
using mozilla::layers::DiagnosticTypes from "mozilla/layers/CompositorTypes.h";
using struct mozilla::layers::ScrollMetadata from "FrameMetrics.h";
using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
using struct mozilla::layers::FenceHandle from "mozilla/layers/FenceUtils.h";
using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
+using mozilla::layers::MaybeLayerClip from "FrameMetrics.h";
namespace mozilla {
namespace layers {
struct TargetConfig {
IntRect naturalBounds;
ScreenRotation rotation;
ScreenOrientationInternal orientation;
@@ -213,16 +214,17 @@ struct CommonLayerAttributes {
TransformMatrix transform;
bool transformIsPerspective;
float postXScale;
float postYScale;
uint32_t contentFlags;
float opacity;
bool useClipRect;
ParentLayerIntRect clipRect;
+ MaybeLayerClip scrolledClip;
bool isFixedPosition;
uint64_t fixedPositionScrollContainerId;
LayerPoint fixedPositionAnchor;
int32_t fixedPositionSides;
bool isClipFixed;
bool isStickyPosition;
uint64_t stickyScrollContainerId;
LayerRect stickyScrollRangeOuter;
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -803,16 +803,17 @@ ShadowLayerForwarder::EndTransaction(Inf
common.postYScale() = mutant->GetPostYScale();
common.transform() = mutant->GetBaseTransform();
common.transformIsPerspective() = mutant->GetTransformIsPerspective();
common.contentFlags() = mutant->GetContentFlags();
common.opacity() = mutant->GetOpacity();
common.useClipRect() = !!mutant->GetClipRect();
common.clipRect() = (common.useClipRect() ?
*mutant->GetClipRect() : ParentLayerIntRect());
+ common.scrolledClip() = mutant->GetScrolledClip();
common.isFixedPosition() = mutant->GetIsFixedPosition();
if (mutant->GetIsFixedPosition()) {
common.fixedPositionScrollContainerId() = mutant->GetFixedPositionScrollContainerId();
common.fixedPositionAnchor() = mutant->GetFixedPositionAnchor();
common.fixedPositionSides() = mutant->GetFixedPositionSides();
common.isClipFixed() = mutant->IsClipFixed();
}
common.isStickyPosition() = mutant->GetIsStickyPosition();