#include "platform/geometry/FloatPoint3D.h"
#include "platform/graphics/GraphicsLayer.h"
#include "platform/graphics/GraphicsLayerClient.h"
-#include "platform/transforms/TransformationMatrix.h"
-namespace WebCore {
+namespace blink {
-class KeyframeList;
class RenderLayerCompositor;
// A GraphicsLayerPaintInfo contains all the info needed to paint a partial subtree of RenderLayers into a GraphicsLayer.
LayoutRect compositedBounds;
- // At first, the m_squashingLayer's bounds/location are not known. The value offsetFromSquashingCLM is
- // an intermediate offset for a squashed RenderLayer, described with respect to the CompositedLayerMapping's
- // owning layer that would eventually have the m_squashingLayer. Once the shared GraphicsLayer's bounds are
- // known, then we can trivially convert this offset to m_squashingLayer's space.
- LayoutSize offsetFromSquashingCLM;
-
// The clip rect to apply, in the local coordinate space of the squashed layer, when painting it.
IntRect localClipRectForSquashedLayer;
// Offset describing where this squashed RenderLayer paints into the shared GraphicsLayer backing.
IntSize offsetFromRenderer;
- LayoutSize subpixelAccumulation;
-
- GraphicsLayerPaintingPhase paintingPhase;
+ bool offsetFromRendererSet;
- bool isBackgroundLayer;
+ GraphicsLayerPaintInfo() : renderLayer(0), offsetFromRendererSet(false) { }
+};
- bool isEquivalentForSquashing(const GraphicsLayerPaintInfo& other)
- {
- // FIXME: offsetFromRenderer and compositedBounds should not be checked here, because
- // they are not yet fixed at the time this function is used.
- return renderLayer == other.renderLayer
- && offsetFromSquashingCLM == other.offsetFromSquashingCLM
- && paintingPhase == other.paintingPhase
- && isBackgroundLayer == other.isBackgroundLayer;
- }
+enum GraphicsLayerUpdateScope {
+ GraphicsLayerUpdateNone,
+ GraphicsLayerUpdateLocal,
+ GraphicsLayerUpdateSubtree,
};
// CompositedLayerMapping keeps track of how RenderLayers of the render tree correspond to
RenderLayer& owningLayer() const { return m_owningLayer; }
- // Returns true if layer configuration changed.
- bool updateGraphicsLayerConfiguration(GraphicsLayerUpdater::UpdateType);
- // Update graphics layer position and bounds.
- void updateGraphicsLayerGeometry(GraphicsLayerUpdater::UpdateType, const RenderLayer* compositingContainer);
+ bool updateGraphicsLayerConfiguration();
+ void updateGraphicsLayerGeometry(const RenderLayer* compositingContainer, const RenderLayer* compositingStackingContext, Vector<RenderLayer*>& layersNeedingPaintInvalidation);
+
// Update whether layer needs blending.
void updateContentsOpaque();
bool hasAncestorClippingLayer() const { return m_ancestorClippingLayer; }
GraphicsLayer* ancestorClippingLayer() const { return m_ancestorClippingLayer.get(); }
- bool hasContentsLayer() const { return m_foregroundLayer; }
GraphicsLayer* foregroundLayer() const { return m_foregroundLayer.get(); }
GraphicsLayer* backgroundLayer() const { return m_backgroundLayer.get(); }
bool hasScrollingLayer() const { return m_scrollingLayer; }
GraphicsLayer* scrollingLayer() const { return m_scrollingLayer.get(); }
GraphicsLayer* scrollingContentsLayer() const { return m_scrollingContentsLayer.get(); }
+ GraphicsLayer* scrollingBlockSelectionLayer() const { return m_scrollingBlockSelectionLayer.get(); }
bool hasMaskLayer() const { return m_maskLayer; }
GraphicsLayer* maskLayer() const { return m_maskLayer.get(); }
GraphicsLayer* parentForSublayers() const;
GraphicsLayer* childForSuperlayers() const;
- // localRootForOwningLayer does not include the m_squashingContainmentLayer, which is technically not associated with this CLM's owning layer.
- GraphicsLayer* localRootForOwningLayer() const;
GraphicsLayer* childTransformLayer() const { return m_childTransformLayer.get(); }
// a backing store changed.
bool updateRequiresOwnBackingStoreForIntrinsicReasons();
+ void setSquashingContentsNeedDisplay();
void setContentsNeedDisplay();
// r is in the coordinate space of the layer's render object
- void setContentsNeedDisplayInRect(const IntRect&);
+ void setContentsNeedDisplayInRect(const LayoutRect&, WebInvalidationDebugAnnotations);
// Notification from the renderer that its content changed.
void contentChanged(ContentChangeType);
LayoutRect compositedBounds() const { return m_compositedBounds; }
IntRect pixelSnappedCompositedBounds() const;
- void updateCompositedBounds(GraphicsLayerUpdater::UpdateType);
void positionOverflowControlsLayers(const IntSize& offsetFromRoot);
bool hasUnpositionedOverflowControlsLayers() const;
// Returns true if the assignment actually changed the assigned squashing layer.
- bool updateSquashingLayerAssignment(RenderLayer*, LayoutSize offsetFromSquashingCLM, size_t nextSquashedLayerIndex);
+ bool updateSquashingLayerAssignment(RenderLayer* squashedLayer, const RenderLayer& owningLayer, size_t nextSquashedLayerIndex);
void removeRenderLayerFromSquashingGraphicsLayer(const RenderLayer*);
void finishAccumulatingSquashingLayers(size_t nextSquashedLayerIndex);
// GraphicsLayerClient interface
virtual void notifyAnimationStarted(const GraphicsLayer*, double monotonicTime) OVERRIDE;
virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& clip) OVERRIDE;
- virtual bool isTrackingRepaints() const OVERRIDE;
-
- PassOwnPtr<Vector<FloatRect> > collectTrackedRepaintRects() const;
+ virtual bool isTrackingPaintInvalidations() const OVERRIDE;
-#ifndef NDEBUG
+#if ENABLE(ASSERT)
virtual void verifyNotPainting() OVERRIDE;
#endif
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 RenderLayer& enclosingLayer);
+
void updateFilters(const RenderStyle*);
- bool canCompositeFilters() const { return m_canCompositeFilters; }
- void setBlendMode(blink::WebBlendMode);
+ 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; }
- void setNeedsGraphicsLayerUpdate();
- bool shouldUpdateGraphicsLayer(GraphicsLayerUpdater::UpdateType updateType) const { return m_needToUpdateGraphicsLayer || updateType == GraphicsLayerUpdater::ForceUpdate; }
GraphicsLayerUpdater::UpdateType updateTypeForChildren(GraphicsLayerUpdater::UpdateType) const;
- void clearNeedsGraphicsLayerUpdate();
-#if !ASSERT_DISABLED
- void assertNeedsToUpdateGraphicsLayerBitsCleared();
+#if ENABLE(ASSERT)
+ void assertNeedsToUpdateGraphicsLayerBitsCleared() { ASSERT(m_pendingUpdateScope == GraphicsLayerUpdateNone); }
#endif
virtual String debugName(const GraphicsLayer*) OVERRIDE;
}
// If there is a squashed layer painting into this CLM that is an ancestor of the given RenderObject, return it. Otherwise return 0.
- const GraphicsLayerPaintInfo* containingSquashedLayer(const RenderObject*) const;
+ const GraphicsLayerPaintInfo* containingSquashedLayer(const RenderObject*);
+
+ void updateScrollingBlockSelection();
private:
+ static const GraphicsLayerPaintInfo* containingSquashedLayer(const RenderObject*, const Vector<GraphicsLayerPaintInfo>& layers);
+
+ // Helper methods to updateGraphicsLayerGeometry:
+ void computeGraphicsLayerParentLocation(const RenderLayer* compositingContainer, const IntRect& ancestorCompositingBounds, IntPoint& graphicsLayerParentLocation);
+ void updateSquashingLayerGeometry(const LayoutPoint& offsetFromCompositedAncestor, const IntPoint& graphicsLayerParentLocation, const RenderLayer& referenceLayer, Vector<GraphicsLayerPaintInfo>& layers, GraphicsLayer*, LayoutPoint* offsetFromTransformedAncestor, Vector<RenderLayer*>& layersNeedingPaintInvalidation);
+ void updateMainGraphicsLayerGeometry(const IntRect& relativeCompositingBounds, const IntRect& localCompositingBounds, const IntPoint& graphicsLayerParentLocation);
+ void updateAncestorClippingLayerGeometry(const RenderLayer* compositingContainer, const IntPoint& snappedOffsetFromCompositedAncestor, IntPoint& graphicsLayerParentLocation);
+ void updateOverflowControlsHostLayerGeometry(const RenderLayer* compositingStackingContext);
+ 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 updateReflectionLayerGeometry(Vector<RenderLayer*>& layersNeedingPaintInvalidation);
+ void updateScrollingLayerGeometry(const IntRect& localCompositingBounds);
+ void updateChildClippingMaskLayerGeometry();
+
void createPrimaryGraphicsLayer();
void destroyGraphicsLayers();
void updatePaintingPhases();
bool updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip);
bool updateChildTransformLayer(bool needsChildTransformLayer);
- bool updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer);
+ bool updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer, bool needsAncestorClip);
bool updateForegroundLayer(bool needsForegroundLayer);
bool updateBackgroundLayer(bool needsBackgroundLayer);
bool updateMaskLayer(bool needsMaskLayer);
bool requiresScrollCornerLayer() const { return m_owningLayer.scrollableArea() && !m_owningLayer.scrollableArea()->scrollCornerAndResizerRect().isEmpty(); }
bool updateScrollingLayers(bool scrollingLayers);
void updateScrollParent(RenderLayer*);
- void updateClipParent(RenderLayer*);
+ void updateClipParent();
bool updateSquashingLayers(bool needsSquashingLayers);
void updateDrawsContent();
void updateChildrenTransform();
+ void updateCompositedBounds();
void registerScrollingLayers();
- void adjustBoundsForSubPixelAccumulation(const RenderLayer* compositedAncestor, IntRect& localCompositingBounds, IntRect& relativeCompositingBounds, IntPoint& delta);
+ // Also sets subpixelAccumulation on the layer.
+ void computeBoundsOfOwningLayer(const RenderLayer* compositedAncestor, IntRect& localCompositingBounds, IntRect& compositingBoundsRelativeToCompositedAncestor, LayoutPoint& offsetFromCompositedAncestor, IntPoint& snappedOffsetFromCompositedAncestor);
void setBackgroundLayerPaintsFixedRootBackground(bool);
// Result is transform origin in pixels.
FloatPoint3D computeTransformOrigin(const IntRect& borderBox) const;
- void updateSquashingLayerGeometry(const IntPoint& delta);
-
void updateOpacity(const RenderStyle*);
void updateTransform(const RenderStyle*);
void updateLayerBlendMode(const RenderStyle*);
// Return the opacity value that this layer should use for compositing.
float compositingOpacity(float rendererOpacity) const;
- bool isMainFrameRenderViewLayer() const;
-
bool paintsChildren() const;
// Returns true if this layer has content that needs to be rendered by painting into the backing store.
Color rendererBackgroundColor() const;
void updateBackgroundColor();
void updateContentsRect();
+ void updateContentsOffsetInCompositingLayer(const IntPoint& snappedOffsetFromCompositedAncestor, const IntPoint& graphicsLayerParentLocation);
void updateAfterWidgetResize();
void updateCompositingReasons();
- bool hasVisibleNonCompositingDescendantLayers() const;
-
- void paintsIntoCompositedAncestorChanged();
+ static bool hasVisibleNonCompositingDescendant(RenderLayer* parent);
- void doPaintTask(GraphicsLayerPaintInfo&, GraphicsContext*, const IntRect& clip);
+ void doPaintTask(const GraphicsLayerPaintInfo&, const PaintLayerFlags&, GraphicsContext*, const IntRect& clip);
// 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.
- IntRect localClipRectForSquashedLayer(const GraphicsLayerPaintInfo&) const;
+ static IntRect localClipRectForSquashedLayer(const RenderLayer& referenceLayer, const GraphicsLayerPaintInfo&, const Vector<GraphicsLayerPaintInfo>& layers);
+
+ // Return true if |m_owningLayer|'s compositing ancestor is not a descendant (inclusive) of the
+ // clipping container for |m_owningLayer|.
+ bool owningLayerClippedByLayerNotAboveCompositedAncestor();
RenderLayer& m_owningLayer;
// + m_ancestorClippingLayer [OPTIONAL]
// + m_graphicsLayer
// + m_childContainmentLayer [OPTIONAL] <-OR-> m_scrollingLayer [OPTIONAL] <-OR-> m_childTransformLayer
- // + m_scrollingContentsLayer [Present iff m_scrollingLayer is present]
+ // | + m_scrollingContentsLayer [Present iff m_scrollingLayer is present]
+ // | + m_scrollingBlockSelectionLayer [Present iff m_scrollingLayer is present]
+ // |
+ // + m_overflowControlsClippingLayer [OPTIONAL] // *The overflow controls may need to be repositioned in the
+ // + m_overflowControlsHostLayer // graphics layer tree by the RLC to ensure that they stack
+ // + m_layerForVerticalScrollbar // above scrolling content.
+ // + m_layerForHorizontalScrollbar
+ // + m_layerForScrollCorner
//
// 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.
OwnPtr<GraphicsLayer> m_childTransformLayer; // Only used if we have perspective and no m_childContainmentLayer.
OwnPtr<GraphicsLayer> m_scrollingLayer; // Only used if the layer is using composited scrolling.
OwnPtr<GraphicsLayer> m_scrollingContentsLayer; // Only used if the layer is using composited scrolling.
+ OwnPtr<GraphicsLayer> m_scrollingBlockSelectionLayer; // Only used if the layer is using composited scrolling, but has no scrolling contents apart from block selection gaps.
// 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
// + root content layer
//
// With the hierarchy set up like this, the root content layer is able to scroll without affecting
- // the background layer (or repainting).
+ // the background layer (or paint invalidation).
OwnPtr<GraphicsLayer> m_foregroundLayer; // Only used in cases where we need to draw the foreground separately.
OwnPtr<GraphicsLayer> m_backgroundLayer; // Only used in cases where we need to draw the background separately.
OwnPtr<GraphicsLayer> m_layerForVerticalScrollbar;
OwnPtr<GraphicsLayer> m_layerForScrollCorner;
+ // This layer exists to simplify the reparenting of overflow control that is occasionally required
+ // to ensure that scrollbars appear above scrolling content.
+ OwnPtr<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. It would be possible to make m_overflowControlsHostLayer be
+ // responsible for applying this clip, but that could require repositioning all of the overflow
+ // controls since the this clip may apply an offset. By using a separate layer, the overflow controls
+ // can remain ignorant of the layers above them and still work correctly.
+ OwnPtr<GraphicsLayer> m_overflowControlsClippingLayer;
+
// A squashing CLM has two possible squashing-related structures.
//
// If m_ancestorClippingLayer is present:
// 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).
OwnPtr<GraphicsLayer> m_squashingContainmentLayer; // 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.
OwnPtr<GraphicsLayer> m_squashingLayer; // Only used if any squashed layers exist, this is the backing that squashed layers paint into.
Vector<GraphicsLayerPaintInfo> m_squashedLayers;
LayoutRect m_compositedBounds;
- bool m_artificiallyInflatedBounds : 1; // bounds had to be made non-zero to make transform-origin work
- bool m_isMainFrameRenderViewLayer : 1;
- bool m_requiresOwnBackingStoreForIntrinsicReasons : 1;
- bool m_requiresOwnBackingStoreForAncestorReasons : 1;
- bool m_canCompositeFilters : 1;
- bool m_backgroundLayerPaintsFixedRootBackground : 1;
- bool m_needToUpdateGraphicsLayer : 1;
- bool m_needToUpdateGraphicsLayerOfAllDecendants : 1;
+ LayoutSize m_contentOffsetInCompositingLayer;
+ unsigned m_contentOffsetInCompositingLayerDirty : 1;
+
+ unsigned m_pendingUpdateScope : 2;
+ unsigned m_isMainFrameRenderViewLayer : 1;
+ unsigned m_requiresOwnBackingStoreForIntrinsicReasons : 1;
+ unsigned m_requiresOwnBackingStoreForAncestorReasons : 1;
+ unsigned m_backgroundLayerPaintsFixedRootBackground : 1;
+ unsigned m_scrollingContentsAreEmpty : 1;
};
-} // namespace WebCore
+} // namespace blink
#endif // CompositedLayerMapping_h