/*
 * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef CompositedLayerMapping_h
#define CompositedLayerMapping_h

#include "core/layout/compositing/GraphicsLayerUpdater.h"
#include "core/paint/PaintLayer.h"
#include "core/paint/PaintLayerPaintingInfo.h"
#include "platform/geometry/FloatPoint.h"
#include "platform/geometry/FloatPoint3D.h"
#include "platform/graphics/GraphicsLayer.h"
#include "platform/graphics/GraphicsLayerClient.h"
#include "wtf/Allocator.h"
#include <memory>

namespace blink {

class PaintLayerCompositor;

// A GraphicsLayerPaintInfo contains all the info needed to paint a partial
// subtree of Layers into a GraphicsLayer.
struct GraphicsLayerPaintInfo {
  DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
  PaintLayer* paintLayer;

  LayoutRect compositedBounds;

  // The clip rect to apply, in the local coordinate space of the squashed
  // layer, when painting it.
  IntRect localClipRectForSquashedLayer;

  // Offset describing where this squashed Layer paints into the shared
  // GraphicsLayer backing.
  IntSize offsetFromLayoutObject;
  bool offsetFromLayoutObjectSet;

  GraphicsLayerPaintInfo()
      : paintLayer(nullptr), offsetFromLayoutObjectSet(false) {}
};

enum GraphicsLayerUpdateScope {
  GraphicsLayerUpdateNone,
  GraphicsLayerUpdateLocal,
  GraphicsLayerUpdateSubtree,
};

// CompositedLayerMapping keeps track of how PaintLayers correspond to
// GraphicsLayers of the composited layer tree. Each instance of
// CompositedLayerMapping manages a small cluster of GraphicsLayers and the
// references to which Layers and paint phases contribute to each GraphicsLayer.
//
// - If a PaintLayer is composited,
//   - if it paints into its own backings (GraphicsLayers), it owns a
//     CompositedLayerMapping (PaintLayer::compositedLayerMapping()) to keep
//     track the backings;
//   - if it paints into grouped backing (i.e. it's squashed), it has a pointer
//     (PaintLayer::groupedMapping()) to the CompositedLayerMapping into which
//     the PaintLayer is squashed;
// - Otherwise the PaintLayer doesn't own or directly reference any
//   CompositedLayerMapping.
class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
  WTF_MAKE_NONCOPYABLE(CompositedLayerMapping);
  USING_FAST_MALLOC(CompositedLayerMapping);

 public:
  explicit CompositedLayerMapping(PaintLayer&);
  ~CompositedLayerMapping() override;

  PaintLayer& owningLayer() const { return m_owningLayer; }

  bool updateGraphicsLayerConfiguration();
  void updateGraphicsLayerGeometry(
      const PaintLayer* compositingContainer,
      const PaintLayer* compositingStackingContext,
      Vector<PaintLayer*>& layersNeedingPaintInvalidation);

  // Update whether background paints onto scrolling contents layer.
  void updateBackgroundPaintsOntoScrollingContentsLayer();

  // Update whether layer needs blending.
  void updateContentsOpaque();

  GraphicsLayer* mainGraphicsLayer() const { return m_graphicsLayer.get(); }

  // Layer to clip children
  bool hasClippingLayer() const { return m_childContainmentLayer.get(); }
  GraphicsLayer* clippingLayer() const { return m_childContainmentLayer.get(); }

  // Layer to get clipped by ancestor
  bool hasAncestorClippingLayer() const {
    return m_ancestorClippingLayer.get();
  }
  GraphicsLayer* ancestorClippingLayer() const {
    return m_ancestorClippingLayer.get();
  }

  GraphicsLayer* ancestorClippingMaskLayer() const {
    return m_ancestorClippingMaskLayer.get();
  }

  GraphicsLayer* foregroundLayer() const { return m_foregroundLayer.get(); }

  GraphicsLayer* backgroundLayer() const { return m_backgroundLayer.get(); }

  GraphicsLayer* decorationOutlineLayer() const {
    return m_decorationOutlineLayer.get();
  }

  bool backgroundLayerPaintsFixedRootBackground() const {
    return m_backgroundLayerPaintsFixedRootBackground;
  }

  bool hasScrollingLayer() const { return m_scrollingLayer.get(); }
  GraphicsLayer* scrollingLayer() const { return m_scrollingLayer.get(); }
  GraphicsLayer* scrollingContentsLayer() const {
    return m_scrollingContentsLayer.get();
  }

  bool hasMaskLayer() const { return m_maskLayer.get(); }
  GraphicsLayer* maskLayer() const { return m_maskLayer.get(); }

  bool hasChildClippingMaskLayer() const {
    return m_childClippingMaskLayer.get();
  }
  GraphicsLayer* childClippingMaskLayer() const {
    return m_childClippingMaskLayer.get();
  }

  GraphicsLayer* parentForSublayers() const;
  GraphicsLayer* childForSuperlayers() const;
  void setSublayers(const GraphicsLayerVector&);

  bool hasChildTransformLayer() const { return m_childTransformLayer.get(); }
  GraphicsLayer* childTransformLayer() const {
    return m_childTransformLayer.get();
  }

  GraphicsLayer* squashingContainmentLayer() const {
    return m_squashingContainmentLayer.get();
  }
  GraphicsLayer* squashingLayer() const { return m_squashingLayer.get(); }

  void setSquashingContentsNeedDisplay();
  void setContentsNeedDisplay();
  // LayoutRect is in the coordinate space of the layer's layout object.
  void setContentsNeedDisplayInRect(const LayoutRect&,
                                    PaintInvalidationReason,
                                    const DisplayItemClient&);
  // Invalidates just the non-scrolling content layers.
  void setNonScrollingContentsNeedDisplayInRect(const LayoutRect&,
                                                PaintInvalidationReason,
                                                const DisplayItemClient&);
  // Invalidates just scrolling content layers.
  void setScrollingContentsNeedDisplayInRect(const LayoutRect&,
                                             PaintInvalidationReason,
                                             const DisplayItemClient&);

  // Notification from the layoutObject that its content changed.
  void contentChanged(ContentChangeType);

  LayoutRect compositedBounds() const { return m_compositedBounds; }
  IntRect pixelSnappedCompositedBounds() const;

  void positionOverflowControlsLayers();

  // Returns true if the assignment actually changed the assigned squashing
  // layer.
  bool updateSquashingLayerAssignment(PaintLayer* squashedLayer,
                                      size_t nextSquashedLayerIndex);
  void removeLayerFromSquashingGraphicsLayer(const PaintLayer*);
#if ENABLE(ASSERT)
  bool verifyLayerInSquashingVector(const PaintLayer*);
#endif

  void finishAccumulatingSquashingLayers(
      size_t nextSquashedLayerIndex,
      Vector<PaintLayer*>& layersNeedingPaintInvalidation);
  void updateRenderingContext();
  void updateShouldFlattenTransform();
  void updateElementIdAndCompositorMutableProperties();

  // GraphicsLayerClient interface
  void invalidateTargetElementForTesting() override;
  void notifyPaint(bool isFirstPaint,
                   bool textPainted,
                   bool imagePainted) override;

  IntRect computeInterestRect(
      const GraphicsLayer*,
      const IntRect& previousInterestRect) const override;
  LayoutSize subpixelAccumulation() const final;
  bool needsRepaint(const GraphicsLayer&) const override;
  void paintContents(const GraphicsLayer*,
                     GraphicsContext&,
                     GraphicsLayerPaintingPhase,
                     const IntRect& interestRect) const override;

  bool isTrackingRasterInvalidations() const override;

#if ENABLE(ASSERT)
  void verifyNotPainting() override;
#endif

  LayoutRect contentsBox() const;

  GraphicsLayer* layerForHorizontalScrollbar() const {
    return m_layerForHorizontalScrollbar.get();
  }
  GraphicsLayer* layerForVerticalScrollbar() const {
    return m_layerForVerticalScrollbar.get();
  }
  GraphicsLayer* layerForScrollCorner() const {
    return m_layerForScrollCorner.get();
  }

  // Returns true if the overflow controls cannot be positioned within this
  // CLM's internal hierarchy without incorrectly stacking under some
  // scrolling content. If this returns true, these controls must be
  // repositioned in the graphics layer tree to ensure that they stack above
  // scrolling content.
  bool needsToReparentOverflowControls() const;

  // Removes the overflow controls host layer from its parent and positions it
  // so that it can be inserted as a sibling to this CLM without changing
  // position.
  GraphicsLayer* detachLayerForOverflowControls(
      const PaintLayer& enclosingLayer);

  void updateFilters(const ComputedStyle&);
  void updateBackdropFilters(const ComputedStyle&);

  void updateStickyConstraints(const ComputedStyle&);

  void setBlendMode(WebBlendMode);

  bool needsGraphicsLayerUpdate() {
    return m_pendingUpdateScope > GraphicsLayerUpdateNone;
  }
  void setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateScope scope) {
    m_pendingUpdateScope = std::max(
        static_cast<GraphicsLayerUpdateScope>(m_pendingUpdateScope), scope);
  }
  void clearNeedsGraphicsLayerUpdate() {
    m_pendingUpdateScope = GraphicsLayerUpdateNone;
  }

  GraphicsLayerUpdater::UpdateType updateTypeForChildren(
      GraphicsLayerUpdater::UpdateType) const;

#if ENABLE(ASSERT)
  void assertNeedsToUpdateGraphicsLayerBitsCleared() {
    ASSERT(m_pendingUpdateScope == GraphicsLayerUpdateNone);
  }
#endif

  String debugName(const GraphicsLayer*) const override;

  LayoutSize contentOffsetInCompositingLayer() const;

  LayoutPoint squashingOffsetFromTransformedAncestor() {
    return m_squashingLayerOffsetFromTransformedAncestor;
  }

  // If there is a squashed layer painting into this CLM that is an ancestor of
  // the given LayoutObject, return it. Otherwise return nullptr.
  const GraphicsLayerPaintInfo* containingSquashedLayer(
      const LayoutObject*,
      unsigned maxSquashedLayerIndex);

  void updateScrollingBlockSelection();

  void adjustForCompositedScrolling(const GraphicsLayer*,
                                    IntSize& offset) const;

  // Returns true for layers with scrollable overflow which have a background
  // that can be painted into the composited scrolling contents layer (i.e.
  // the background can scroll with the content). When the background is also
  // opaque this allows us to composite the scroller even on low DPI as we can
  // draw with subpixel anti-aliasing.
  bool backgroundPaintsOntoScrollingContentsLayer() {
    return m_backgroundPaintsOntoScrollingContentsLayer;
  }

 private:
  IntRect recomputeInterestRect(const GraphicsLayer*) const;
  static bool interestRectChangedEnoughToRepaint(
      const IntRect& previousInterestRect,
      const IntRect& newInterestRect,
      const IntSize& layerSize);

  static const GraphicsLayerPaintInfo* containingSquashedLayer(
      const LayoutObject*,
      const Vector<GraphicsLayerPaintInfo>& layers,
      unsigned maxSquashedLayerIndex);

  // Paints the scrollbar part associated with the given graphics layer into the
  // given context.
  void paintScrollableArea(const GraphicsLayer*,
                           GraphicsContext&,
                           const IntRect& interestRect) const;
  // Returns whether the given layer is part of the scrollable area, if any,
  // associated with this mapping.
  bool isScrollableAreaLayer(const GraphicsLayer*) const;

  // Helper methods to updateGraphicsLayerGeometry:
  void computeGraphicsLayerParentLocation(
      const PaintLayer* compositingContainer,
      const IntRect& ancestorCompositingBounds,
      IntPoint& graphicsLayerParentLocation);
  void updateSquashingLayerGeometry(
      const IntPoint& graphicsLayerParentLocation,
      const PaintLayer* compositingContainer,
      Vector<GraphicsLayerPaintInfo>& layers,
      GraphicsLayer*,
      LayoutPoint* offsetFromTransformedAncestor,
      Vector<PaintLayer*>& layersNeedingPaintInvalidation);
  void updateMainGraphicsLayerGeometry(
      const IntRect& relativeCompositingBounds,
      const IntRect& localCompositingBounds,
      const IntPoint& graphicsLayerParentLocation);
  void updateAncestorClippingLayerGeometry(
      const PaintLayer* compositingContainer,
      const IntPoint& snappedOffsetFromCompositedAncestor,
      IntPoint& graphicsLayerParentLocation);
  void updateOverflowControlsHostLayerGeometry(
      const PaintLayer* compositingStackingContext,
      const PaintLayer* compositingContainer,
      IntPoint graphicsLayerParentLocation);
  void updateChildContainmentLayerGeometry(
      const IntRect& clippingBox,
      const IntRect& localCompositingBounds);
  void updateChildTransformLayerGeometry();
  void updateMaskLayerGeometry();
  void updateTransformGeometry(
      const IntPoint& snappedOffsetFromCompositedAncestor,
      const IntRect& relativeCompositingBounds);
  void updateForegroundLayerGeometry(
      const FloatSize& relativeCompositingBoundsSize,
      const IntRect& clippingBox);
  void updateBackgroundLayerGeometry(
      const FloatSize& relativeCompositingBoundsSize);
  void updateDecorationOutlineLayerGeometry(
      const FloatSize& relativeCompositingBoundsSize);
  void updateScrollingLayerGeometry(const IntRect& localCompositingBounds);
  void updateChildClippingMaskLayerGeometry();

  void createPrimaryGraphicsLayer();
  void destroyGraphicsLayers();

  std::unique_ptr<GraphicsLayer> createGraphicsLayer(
      CompositingReasons,
      SquashingDisallowedReasons = SquashingDisallowedReasonsNone);
  bool toggleScrollbarLayerIfNeeded(std::unique_ptr<GraphicsLayer>&,
                                    bool needsLayer,
                                    CompositingReasons);

  LayoutBoxModelObject* layoutObject() const {
    return m_owningLayer.layoutObject();
  }
  PaintLayerCompositor* compositor() const {
    return m_owningLayer.compositor();
  }

  void updateInternalHierarchy();
  void updatePaintingPhases();
  bool updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip);
  bool updateClippingLayers(bool needsAncestorClip,
                            bool needsAncestorClippingMask,
                            bool needsDescendantClip);
  bool updateChildTransformLayer(bool needsChildTransformLayer);
  bool updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer,
                                    bool needsVerticalScrollbarLayer,
                                    bool needsScrollCornerLayer,
                                    bool needsAncestorClip);
  bool updateForegroundLayer(bool needsForegroundLayer);
  bool updateBackgroundLayer(bool needsBackgroundLayer);
  bool updateDecorationOutlineLayer(bool needsDecorationOutlineLayer);
  bool updateMaskLayer(bool needsMaskLayer);
  void updateChildClippingMaskLayer(bool needsChildClippingMaskLayer);
  bool requiresHorizontalScrollbarLayer() const {
    return m_owningLayer.getScrollableArea() &&
           m_owningLayer.getScrollableArea()->horizontalScrollbar();
  }
  bool requiresVerticalScrollbarLayer() const {
    return m_owningLayer.getScrollableArea() &&
           m_owningLayer.getScrollableArea()->verticalScrollbar();
  }
  bool requiresScrollCornerLayer() const {
    return m_owningLayer.getScrollableArea() &&
           !m_owningLayer.getScrollableArea()
                ->scrollCornerAndResizerRect()
                .isEmpty();
  }
  bool updateScrollingLayers(bool scrollingLayers);
  void updateScrollParent(const PaintLayer*);
  void updateClipParent(const PaintLayer* scrollParent);
  bool updateSquashingLayers(bool needsSquashingLayers);
  void updateDrawsContent();
  void updateChildrenTransform();
  void updateCompositedBounds();
  void registerScrollingLayers();

  // Also sets subpixelAccumulation on the layer.
  void computeBoundsOfOwningLayer(
      const PaintLayer* compositedAncestor,
      IntRect& localCompositingBounds,
      IntRect& compositingBoundsRelativeToCompositedAncestor,
      LayoutPoint& offsetFromCompositedAncestor,
      IntPoint& snappedOffsetFromCompositedAncestor);

  void setBackgroundLayerPaintsFixedRootBackground(bool);

  GraphicsLayerPaintingPhase paintingPhaseForPrimaryLayer() const;

  // Result is transform origin in pixels.
  FloatPoint3D computeTransformOrigin(const IntRect& borderBox) const;

  void updateOpacity(const ComputedStyle&);
  void updateTransform(const ComputedStyle&);
  void updateLayerBlendMode(const ComputedStyle&);
  void updateIsRootForIsolatedGroup();
  // Return the opacity value that this layer should use for compositing.
  float compositingOpacity(float layoutObjectOpacity) const;

  bool paintsChildren() const;

  // Returns true if this layer has content that needs to be displayed by
  // painting into the backing store.
  bool containsPaintedContent() const;
  // Returns true if the Layer just contains an image that we can composite
  // directly.
  bool isDirectlyCompositedImage() const;
  void updateImageContents();

  Color layoutObjectBackgroundColor() const;
  void updateBackgroundColor();
  void updateContentsRect();
  void updateContentsOffsetInCompositingLayer(
      const IntPoint& snappedOffsetFromCompositedAncestor,
      const IntPoint& graphicsLayerParentLocation);
  void updateAfterPartResize();
  void updateCompositingReasons();

  static bool hasVisibleNonCompositingDescendant(PaintLayer* parent);

  void doPaintTask(const GraphicsLayerPaintInfo&,
                   const GraphicsLayer&,
                   const PaintLayerFlags&,
                   GraphicsContext&,
                   const IntRect& clip) const;

  // Computes the background clip rect for the given squashed layer, up to any
  // containing layer that is squashed into the same squashing layer and
  // contains this squashed layer's clipping ancestor.  The clip rect is
  // returned in the coordinate space of the given squashed layer.  If there is
  // no such containing layer, returns the infinite rect.
  // FIXME: unify this code with the code that sets up m_ancestorClippingLayer.
  // They are doing very similar things.
  static IntRect localClipRectForSquashedLayer(
      const PaintLayer& referenceLayer,
      const GraphicsLayerPaintInfo&,
      const Vector<GraphicsLayerPaintInfo>& layers);

  // Return true in |owningLayerIsClipped| iff |m_owningLayer|'s compositing
  // ancestor is not a descendant (inclusive) of the clipping container for
  // |m_owningLayer|. Return true in |owningLayerIsMasked| iff
  // |owningLayerIsClipped| is true and |m_owningLayer|'s compositing ancestor
  // is not a descendant (inclusive) of a container that applies a mask for
  // |m_owningLayer|.
  void owningLayerClippedOrMaskedByLayerNotAboveCompositedAncestor(
      const PaintLayer* scrollParent,
      bool& owningLayerIsClipped,
      bool& owningLayerIsMasked);

  const PaintLayer* scrollParent();

  // Clear the groupedMapping entry on the layer at the given index, only if
  // that layer does not appear earlier in the set of layers for this object.
  bool invalidateLayerIfNoPrecedingEntry(size_t);

  PaintLayer& m_owningLayer;

  // The hierarchy of layers that is maintained by the CompositedLayerMapping
  // looks like this:
  //
  //  + m_ancestorClippingLayer [OPTIONAL]
  //    + m_graphicsLayer
  //      + m_childTransformLayer [OPTIONAL]
  //      | + m_childContainmentLayer [OPTIONAL]
  //      |   <-OR->
  //      |   (m_scrollingLayer + m_scrollingContentsLayer) [OPTIONAL]
  //      + m_overflowControlsAncestorClippingLayer [OPTIONAL]
  //      | + m_overflowControlsHostLayer [OPTIONAL]
  //      |   + m_layerForVerticalScrollbar [OPTIONAL]
  //      |   + m_layerForHorizontalScrollbar [OPTIONAL]
  //      |   + m_layerForScrollCorner [OPTIONAL]
  //      + m_decorationOutlineLayer [OPTIONAL]
  // The overflow controls may need to be repositioned in the graphics layer
  // tree by the RLC to ensure that they stack above scrolling content.
  //
  // We need an ancestor clipping layer if our clipping ancestor is not our
  // ancestor in the clipping tree. Here's what that might look like.
  //
  // Let A = the clipping ancestor,
  //     B = the clip descendant, and
  //     SC = the stacking context that is the ancestor of A and B in the
  //          stacking tree.
  //
  // SC
  //  + A = m_graphicsLayer
  //  |  + m_childContainmentLayer
  //  |     + ...
  //  ...
  //  |
  //  + B = m_ancestorClippingLayer [+]
  //     + m_graphicsLayer
  //        + ...
  //
  // In this case B is clipped by another layer that doesn't happen to be its
  // ancestor: A.  So we create an ancestor clipping layer for B, [+], which
  // ensures that B is clipped as if it had been A's descendant.
  // In addition, the m_ancestorClippingLayer will have an associated
  // mask layer if the ancestor, A, has a border radius that requires a
  // rounded corner clip rect. The mask is not part of the layer tree; rather
  // it is attached to the m_ancestorClippingLayer itself.
  //
  // Layers that require a CSS mask also have a mask layer attached to them.

  // Only used if we are clipped by an ancestor which is not a stacking context.
  std::unique_ptr<GraphicsLayer> m_ancestorClippingLayer;

  // Only used is there is an m_ancestorClippingLayer that also needs to apply
  // a clipping mask (for CSS clips or border radius).
  std::unique_ptr<GraphicsLayer> m_ancestorClippingMaskLayer;

  std::unique_ptr<GraphicsLayer> m_graphicsLayer;

  // Only used if we have clipping on a stacking context with compositing
  // children.
  std::unique_ptr<GraphicsLayer> m_childContainmentLayer;

  // Only used if we have perspective.
  std::unique_ptr<GraphicsLayer> m_childTransformLayer;

  // Only used if the layer is using composited scrolling.
  std::unique_ptr<GraphicsLayer> m_scrollingLayer;

  // Only used if the layer is using composited scrolling.
  std::unique_ptr<GraphicsLayer> m_scrollingContentsLayer;

  // This layer is also added to the hierarchy by the RLB, but in a different
  // way than the layers above. It's added to m_graphicsLayer as its mask layer
  // (naturally) if we have a mask, and isn't part of the typical hierarchy (it
  // has no children).
  // Only used if we have a mask.
  std::unique_ptr<GraphicsLayer> m_maskLayer;

  // Only used if we have to clip child layers or accelerated contents with
  // border radius or clip-path.
  std::unique_ptr<GraphicsLayer> m_childClippingMaskLayer;

  // There are two other (optional) layers whose painting is managed by the
  // CompositedLayerMapping, but whose position in the hierarchy is maintained
  // by the PaintLayerCompositor. These are the foreground and background
  // layers. The foreground layer exists if we have composited descendants with
  // negative z-order. We need the extra layer in this case because the layer
  // needs to draw both below (for the background, say) and above (for the
  // normal flow content, say) the negative z-order descendants and this is
  // impossible with a single layer. The RLC handles inserting m_foregroundLayer
  // in the correct position in our descendant list for us (right after the neg
  // z-order dsecendants).
  //
  // The background layer is only created if this is the root layer and our
  // background is entirely fixed. In this case we want to put the background in
  // a separate composited layer so that when we scroll, we don't have to
  // re-raster the background into position. This layer is also inserted into
  // the tree by the RLC as it gets a special home. This layer becomes a
  // descendant of the frame clipping layer. That is:
  //   ...
  //     + frame clipping layer
  //       + m_backgroundLayer
  //       + frame scrolling layer
  //         + root content layer
  //
  // With the hierarchy set up like this, the root content layer is able to
  // scroll without affecting the background layer (or paint invalidation).

  // Only used in cases where we need to draw the foreground separately.
  std::unique_ptr<GraphicsLayer> m_foregroundLayer;

  // Only used in cases where we need to draw the background separately.
  std::unique_ptr<GraphicsLayer> m_backgroundLayer;

  std::unique_ptr<GraphicsLayer> m_layerForHorizontalScrollbar;
  std::unique_ptr<GraphicsLayer> m_layerForVerticalScrollbar;
  std::unique_ptr<GraphicsLayer> m_layerForScrollCorner;

  // This layer contains the scrollbar and scroll corner layers and clips them
  // to the border box bounds of our LayoutObject. It is usually added to
  // m_graphicsLayer, but may be reparented by GraphicsLayerTreeBuilder to
  // ensure that scrollbars appear above scrolling content.
  std::unique_ptr<GraphicsLayer> m_overflowControlsHostLayer;

  // The reparented overflow controls sometimes need to be clipped by a
  // non-ancestor. In just the same way we need an ancestor clipping layer to
  // clip this CLM's internal hierarchy, we add another layer to clip the
  // overflow controls. We could combine this with m_overflowControlsHostLayer,
  // but that would require manually intersecting their clips, and shifting the
  // overflow controls to compensate for this clip's offset. By using a separate
  // layer, the overflow controls can remain ignorant of ancestor clipping.
  std::unique_ptr<GraphicsLayer> m_overflowControlsAncestorClippingLayer;

  // DecorationLayer which paints outline.
  std::unique_ptr<GraphicsLayer> m_decorationOutlineLayer;

  // A squashing CLM has two possible squashing-related structures.
  //
  // If m_ancestorClippingLayer is present:
  //
  // m_ancestorClippingLayer
  //   + m_graphicsLayer
  //   + m_squashingLayer
  //
  // If not:
  //
  // m_squashingContainmentLayer
  //   + m_graphicsLayer
  //   + m_squashingLayer
  //
  // Stacking children of a squashed layer receive graphics layers that are
  // parented to the compositd ancestor of the squashed layer (i.e. nearest
  // enclosing composited layer that is not
  // squashed).

  // Only used if any squashed layers exist and m_squashingContainmentLayer is
  // not present, to contain the squashed layers as siblings to the rest of the
  // GraphicsLayer tree chunk.
  std::unique_ptr<GraphicsLayer> m_squashingContainmentLayer;

  // Only used if any squashed layers exist, this is the backing that squashed
  // layers paint into.
  std::unique_ptr<GraphicsLayer> m_squashingLayer;
  Vector<GraphicsLayerPaintInfo> m_squashedLayers;
  LayoutPoint m_squashingLayerOffsetFromTransformedAncestor;

  LayoutRect m_compositedBounds;

  LayoutSize m_contentOffsetInCompositingLayer;

  // We keep track of the scrolling contents offset, so that when it changes we
  // can notify the ScrollingCoordinator, which passes on main-thread scrolling
  // updates to the compositor.
  DoubleSize m_scrollingContentsOffset;

  unsigned m_contentOffsetInCompositingLayerDirty : 1;

  unsigned m_pendingUpdateScope : 2;
  unsigned m_isMainFrameLayoutViewLayer : 1;

  unsigned m_backgroundLayerPaintsFixedRootBackground : 1;
  unsigned m_scrollingContentsAreEmpty : 1;

  // Keep track of whether the background is painted onto the scrolling contents
  // layer for invalidations.
  unsigned m_backgroundPaintsOntoScrollingContentsLayer : 1;

  // Solid color border boxes may be painted into both the scrolling contents
  // layer and the graphics layer because the scrolling contents layer is
  // clipped by the padding box.
  unsigned m_backgroundPaintsOntoGraphicsLayer : 1;

  friend class CompositedLayerMappingTest;
};

}  // namespace blink

#endif  // CompositedLayerMapping_h
