Bug 1267438 - Give layers an optional scrolled clip that is scrolled by all scroll frames associated with the layer. r=mstange draft
authorBotond Ballo <botond@mozilla.com>
Fri, 29 Apr 2016 17:32:53 -0400
changeset 364616 e7f1ddd9ce664317247da1b9f569ac04e383ca47
parent 363526 165a66ccdf2d836acb11fbda39888ad8d7954d1f
child 364617 cda1645407959eb39ff3e880078836d35686a8d8
push id17504
push userbballo@mozilla.com
push dateFri, 06 May 2016 23:44:30 +0000
reviewersmstange
bugs1267438
milestone49.0a1
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
gfx/layers/FrameMetrics.h
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/LayersMessages.ipdlh
gfx/layers/ipc/ShadowLayers.cpp
--- 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();