Index: third_party/WebKit/Source/core/paint/PaintLayer.h |
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.h b/third_party/WebKit/Source/core/paint/PaintLayer.h |
index 073009e9d4aa0b1c2290f624a524def54f5fec5c..dd5f4f5142708bd1199a8da0aaab94d59007832c 100644 |
--- a/third_party/WebKit/Source/core/paint/PaintLayer.h |
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.h |
@@ -90,6 +90,49 @@ private: |
TemporaryChange<CompositingQueryMode> m_disabler; |
}; |
+struct PaintLayerRareData { |
+ PaintLayerRareData(); |
+ ~PaintLayerRareData(); |
+ |
+ // Our current relative position offset. |
+ LayoutSize offsetForInFlowPosition; |
+ |
+ OwnPtr<TransformationMatrix> transform; |
+ |
+ // Pointer to the enclosing Layer that caused us to be paginated. It is 0 if we are not paginated. |
+ // |
+ // See LayoutMultiColumnFlowThread and |
+ // https://sites.google.com/a/chromium.org/dev/developers/design-documents/multi-column-layout |
+ // for more information about the multicol implementation. It's important to understand the |
+ // difference between flow thread coordinates and visual coordinates when working with multicol |
+ // in Layer, since Layer is one of the few places where we have to worry about the |
+ // visual ones. Internally we try to use flow-thread coordinates whenever possible. |
+ PaintLayer* enclosingPaginationLayer; |
+ |
+ // These compositing reasons are updated whenever style changes, not while updating compositing layers. |
+ // They should not be used to infer the compositing state of this layer. |
+ CompositingReasons potentialCompositingReasonsFromStyle; |
+ |
+ // Once computed, indicates all that a layer needs to become composited using the CompositingReasons enum bitfield. |
+ CompositingReasons compositingReasons; |
+ |
+ // If the layer paints into its own backings, this keeps track of the backings. |
+ // It's nullptr if the layer is not composited or paints into grouped backing. |
+ OwnPtr<CompositedLayerMapping> compositedLayerMapping; |
+ |
+ // If the layer paints into grouped backing (i.e. squashed), this points to the |
+ // grouped CompositedLayerMapping. It's null if the layer is not composited or |
+ // paints into its own backing. |
+ CompositedLayerMapping* groupedMapping; |
+ |
+ IntRect blockSelectionGapsBounds; |
+ |
+ OwnPtr<PaintLayerReflectionInfo> reflectionInfo; |
+ |
+ // The accumulated subpixel offset of a composited layer's composited bounds compared to absolute coordinates. |
+ LayoutSize subpixelAccumulation; |
+}; |
+ |
// PaintLayer is an old object that handles lots of unrelated operations. |
// |
// We want it to die at some point and be replaced by more focused objects, |
@@ -161,11 +204,11 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient { |
WTF_MAKE_NONCOPYABLE(PaintLayer); |
public: |
PaintLayer(LayoutBoxModelObject*, PaintLayerType); |
- ~PaintLayer(); |
+ ~PaintLayer() override; |
// DisplayItemClient methods |
String debugName() const final; |
- IntRect visualRect() const override; |
+ IntRect visualRect() const final; |
LayoutBoxModelObject* layoutObject() const { return m_layoutObject; } |
LayoutBox* layoutBox() const { return m_layoutObject && m_layoutObject->isBox() ? toLayoutBox(m_layoutObject) : 0; } |
@@ -190,13 +233,13 @@ public: |
// FIXME: Many people call this function while it has out-of-date information. |
bool isSelfPaintingLayer() const { return m_isSelfPaintingLayer; } |
- void setLayerType(PaintLayerType layerType) { m_layerType = layerType; } |
+ void setLayerType(PaintLayerType layerType) { m_layerType = layerType; ASSERT(static_cast<PaintLayerType>(m_layerType) == layerType); } |
bool isTransparent() const { return layoutObject()->isTransparent() || layoutObject()->style()->hasBlendMode() || layoutObject()->hasMask(); } |
bool isReflection() const { return layoutObject()->isReplica(); } |
- PaintLayerReflectionInfo* reflectionInfo() { return m_reflectionInfo.get(); } |
- const PaintLayerReflectionInfo* reflectionInfo() const { return m_reflectionInfo.get(); } |
+ PaintLayerReflectionInfo* reflectionInfo() { return m_rareData ? m_rareData->reflectionInfo.get() : nullptr; } |
+ const PaintLayerReflectionInfo* reflectionInfo() const { return const_cast<PaintLayer*>(this)->reflectionInfo(); } |
const PaintLayer* root() const |
{ |
@@ -225,12 +268,12 @@ public: |
void updateLayerPositionsAfterLayout(); |
void updateLayerPositionsAfterOverflowScroll(const DoubleSize& scrollDelta); |
- PaintLayer* enclosingPaginationLayer() const { return m_enclosingPaginationLayer; } |
+ PaintLayer* enclosingPaginationLayer() const { return m_rareData ? m_rareData->enclosingPaginationLayer : nullptr; } |
void updateTransformationMatrix(); |
PaintLayer* renderingContextRoot(); |
- const LayoutSize& offsetForInFlowPosition() const { return m_offsetForInFlowPosition; } |
+ LayoutSize offsetForInFlowPosition() const { return m_rareData ? m_rareData->offsetForInFlowPosition : LayoutSize(); } |
void addBlockSelectionGapsBounds(const LayoutRect&); |
void clearBlockSelectionGapsBounds(); |
@@ -341,9 +384,7 @@ public: |
bool hasTransformRelatedProperty() const { return layoutObject()->hasTransformRelatedProperty(); } |
// Note that this transform has the transform-origin baked in. |
- TransformationMatrix* transform() const { return m_transform.get(); } |
- void setTransform(PassOwnPtr<TransformationMatrix> transform) { m_transform = transform; } |
- void clearTransform() { m_transform.clear(); } |
+ TransformationMatrix* transform() const { return m_rareData ? m_rareData->transform.get() : nullptr; } |
// currentTransform computes a transform which takes accelerated animations into account. The |
// resulting transform has transform-origin baked in. If the layer does not have a transform, |
@@ -357,7 +398,7 @@ public: |
TransformationMatrix perspectiveTransform() const; |
FloatPoint perspectiveOrigin() const; |
bool preserves3D() const { return layoutObject()->style()->transformStyle3D() == TransformStyle3DPreserve3D; } |
- bool has3DTransform() const { return m_transform && !m_transform->isAffine(); } |
+ bool has3DTransform() const { return m_rareData && m_rareData->transform && !m_rareData->transform->isAffine(); } |
// FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959 |
bool shouldPreserve3D() const { return !layoutObject()->hasReflection() && layoutObject()->style()->transformStyle3D() == TransformStyle3DPreserve3D; } |
@@ -384,10 +425,10 @@ public: |
// (and not just to do bookkeeping related to the mapping like, say, allocating or deallocating a mapping), |
// then you may have incorrect logic. Use compositingState() instead. |
// FIXME: This is identical to null checking compositedLayerMapping(), why not just call that? |
- bool hasCompositedLayerMapping() const { return m_compositedLayerMapping.get(); } |
+ bool hasCompositedLayerMapping() const { return m_rareData && m_rareData->compositedLayerMapping; } |
void ensureCompositedLayerMapping(); |
void clearCompositedLayerMapping(bool layerBeingDestroyed = false); |
- CompositedLayerMapping* groupedMapping() const { return m_groupedMapping; } |
+ CompositedLayerMapping* groupedMapping() const { return m_rareData ? m_rareData->groupedMapping : nullptr; } |
enum SetGroupMappingOptions { |
InvalidateLayerAndRemoveFromMapping, |
DoNotInvalidateLayerAndRemoveFromMapping |
@@ -466,31 +507,44 @@ public: |
bool scrollsOverflow() const; |
- CompositingReasons potentialCompositingReasonsFromStyle() const { return m_potentialCompositingReasonsFromStyle; } |
- void setPotentialCompositingReasonsFromStyle(CompositingReasons reasons) { ASSERT(reasons == (reasons & CompositingReasonComboAllStyleDeterminedReasons)); m_potentialCompositingReasonsFromStyle = reasons; } |
+ CompositingReasons potentialCompositingReasonsFromStyle() const { return m_rareData ? m_rareData->potentialCompositingReasonsFromStyle : CompositingReasonNone; } |
+ void setPotentialCompositingReasonsFromStyle(CompositingReasons reasons) |
+ { |
+ ASSERT(reasons == (reasons & CompositingReasonComboAllStyleDeterminedReasons)); |
+ if (m_rareData || reasons != CompositingReasonNone) |
+ ensureRareData().potentialCompositingReasonsFromStyle = reasons; |
+ } |
- bool hasStyleDeterminedDirectCompositingReasons() const { return m_potentialCompositingReasonsFromStyle & CompositingReasonComboAllDirectStyleDeterminedReasons; } |
+ bool hasStyleDeterminedDirectCompositingReasons() const { return potentialCompositingReasonsFromStyle() & CompositingReasonComboAllDirectStyleDeterminedReasons; } |
class AncestorDependentCompositingInputs { |
DISALLOW_NEW(); |
public: |
AncestorDependentCompositingInputs() |
- : opacityAncestor(0) |
- , transformAncestor(0) |
- , filterAncestor(0) |
- , clippingContainer(0) |
- , ancestorScrollingLayer(0) |
- , nearestFixedPositionLayer(0) |
- , scrollParent(0) |
- , clipParent(0) |
- , hasAncestorWithClipPath(false) |
+ : clippingContainer(nullptr) |
{ } |
IntRect clippedAbsoluteBoundingBox; |
+ const LayoutObject* clippingContainer; |
+ }; |
+ |
+ class RareAncestorDependentCompositingInputs { |
+ public: |
+ RareAncestorDependentCompositingInputs() |
+ : opacityAncestor(nullptr) |
+ , transformAncestor(nullptr) |
+ , filterAncestor(nullptr) |
+ , ancestorScrollingLayer(nullptr) |
+ , nearestFixedPositionLayer(nullptr) |
+ , scrollParent(nullptr) |
+ , clipParent(nullptr) |
+ { } |
+ |
+ bool isDefault() const { return !opacityAncestor && !transformAncestor && !filterAncestor && !ancestorScrollingLayer && !nearestFixedPositionLayer && !scrollParent && !clipParent; } |
+ |
const PaintLayer* opacityAncestor; |
const PaintLayer* transformAncestor; |
const PaintLayer* filterAncestor; |
- const LayoutObject* clippingContainer; |
const PaintLayer* ancestorScrollingLayer; |
const PaintLayer* nearestFixedPositionLayer; |
@@ -508,20 +562,6 @@ public: |
// needs to know about clip parents in order to circumvent its normal |
// clipping logic. |
const PaintLayer* clipParent; |
- |
- unsigned hasAncestorWithClipPath : 1; |
- }; |
- |
- class DescendantDependentCompositingInputs { |
- DISALLOW_NEW(); |
- public: |
- DescendantDependentCompositingInputs() |
- : hasDescendantWithClipPath(false) |
- , hasNonIsolatedDescendantWithBlendMode(false) |
- { } |
- |
- unsigned hasDescendantWithClipPath : 1; |
- unsigned hasNonIsolatedDescendantWithBlendMode : 1; |
}; |
void setNeedsCompositingInputsUpdate(); |
@@ -534,30 +574,27 @@ public: |
return m_needsDescendantDependentCompositingInputsUpdate; |
} |
- void updateAncestorDependentCompositingInputs(const AncestorDependentCompositingInputs&); |
- void updateDescendantDependentCompositingInputs(const DescendantDependentCompositingInputs&); |
+ void updateAncestorDependentCompositingInputs(const AncestorDependentCompositingInputs&, const RareAncestorDependentCompositingInputs&, bool hasAncestorWithClipPath); |
+ void updateDescendantDependentCompositingInputs(bool hasDescendantWithClipPath, bool hasNonIsolatedDescendantWithBlendMode); |
void didUpdateCompositingInputs(); |
- const AncestorDependentCompositingInputs& ancestorDependentCompositingInputs() const { ASSERT(!m_needsAncestorDependentCompositingInputsUpdate); return m_ancestorDependentCompositingInputs; } |
- const DescendantDependentCompositingInputs& descendantDependentCompositingInputs() const { ASSERT(!m_needsDescendantDependentCompositingInputsUpdate); return m_descendantDependentCompositingInputs; } |
- |
- IntRect clippedAbsoluteBoundingBox() const { return ancestorDependentCompositingInputs().clippedAbsoluteBoundingBox; } |
- const PaintLayer* opacityAncestor() const { return ancestorDependentCompositingInputs().opacityAncestor; } |
- const PaintLayer* transformAncestor() const { return ancestorDependentCompositingInputs().transformAncestor; } |
- const PaintLayer* filterAncestor() const { return ancestorDependentCompositingInputs().filterAncestor; } |
- const LayoutObject* clippingContainer() const { return ancestorDependentCompositingInputs().clippingContainer; } |
- const PaintLayer* ancestorScrollingLayer() const { return ancestorDependentCompositingInputs().ancestorScrollingLayer; } |
- const PaintLayer* nearestFixedPositionLayer() const { return ancestorDependentCompositingInputs().nearestFixedPositionLayer; } |
- PaintLayer* scrollParent() const { return const_cast<PaintLayer*>(ancestorDependentCompositingInputs().scrollParent); } |
- PaintLayer* clipParent() const { return const_cast<PaintLayer*>(ancestorDependentCompositingInputs().clipParent); } |
- bool hasAncestorWithClipPath() const { return ancestorDependentCompositingInputs().hasAncestorWithClipPath; } |
- bool hasDescendantWithClipPath() const { return descendantDependentCompositingInputs().hasDescendantWithClipPath; } |
+ IntRect clippedAbsoluteBoundingBox() const { ASSERT(!m_needsAncestorDependentCompositingInputsUpdate); return m_ancestorDependentCompositingInputs.clippedAbsoluteBoundingBox; } |
+ const PaintLayer* opacityAncestor() const { ASSERT(!m_needsAncestorDependentCompositingInputsUpdate); return m_rareAncestorDependentCompositingInputs ? m_rareAncestorDependentCompositingInputs->opacityAncestor : nullptr; } |
+ const PaintLayer* transformAncestor() const { ASSERT(!m_needsAncestorDependentCompositingInputsUpdate); return m_rareAncestorDependentCompositingInputs ? m_rareAncestorDependentCompositingInputs->transformAncestor : nullptr; } |
+ const PaintLayer* filterAncestor() const { ASSERT(!m_needsAncestorDependentCompositingInputsUpdate); return m_rareAncestorDependentCompositingInputs ? m_rareAncestorDependentCompositingInputs->filterAncestor : nullptr; } |
+ const LayoutObject* clippingContainer() const { ASSERT(!m_needsAncestorDependentCompositingInputsUpdate); return m_ancestorDependentCompositingInputs.clippingContainer; } |
+ const PaintLayer* ancestorScrollingLayer() const { ASSERT(!m_needsAncestorDependentCompositingInputsUpdate); return m_rareAncestorDependentCompositingInputs ? m_rareAncestorDependentCompositingInputs->ancestorScrollingLayer : nullptr; } |
+ const PaintLayer* nearestFixedPositionLayer() const { ASSERT(!m_needsAncestorDependentCompositingInputsUpdate); return m_rareAncestorDependentCompositingInputs ? m_rareAncestorDependentCompositingInputs->nearestFixedPositionLayer : nullptr; } |
+ const PaintLayer* scrollParent() const { ASSERT(!m_needsAncestorDependentCompositingInputsUpdate); return m_rareAncestorDependentCompositingInputs ? m_rareAncestorDependentCompositingInputs->scrollParent : nullptr; } |
+ const PaintLayer* clipParent() const { ASSERT(!m_needsAncestorDependentCompositingInputsUpdate); return m_rareAncestorDependentCompositingInputs ? m_rareAncestorDependentCompositingInputs->clipParent : nullptr; } |
+ bool hasAncestorWithClipPath() const { ASSERT(!m_needsAncestorDependentCompositingInputsUpdate); return m_hasAncestorWithClipPath; } |
+ bool hasDescendantWithClipPath() const { ASSERT(!m_needsDescendantDependentCompositingInputsUpdate); return m_hasDescendantWithClipPath; } |
bool hasNonIsolatedDescendantWithBlendMode() const; |
bool lostGroupedMapping() const { ASSERT(isAllowedToQueryCompositingState()); return m_lostGroupedMapping; } |
void setLostGroupedMapping(bool b) { m_lostGroupedMapping = b; } |
- CompositingReasons compositingReasons() const { ASSERT(isAllowedToQueryCompositingState()); return m_compositingReasons; } |
+ CompositingReasons compositingReasons() const { ASSERT(isAllowedToQueryCompositingState()); return m_rareData ? m_rareData->compositingReasons : CompositingReasonNone; } |
void setCompositingReasons(CompositingReasons, CompositingReasons mask = CompositingReasonAll); |
bool hasCompositingDescendant() const { ASSERT(isAllowedToQueryCompositingState()); return m_hasCompositingDescendant; } |
@@ -713,7 +750,14 @@ private: |
void markCompositingContainerChainForNeedsRepaint(); |
- PaintLayerType m_layerType; |
+ PaintLayerRareData& ensureRareData() |
+ { |
+ if (!m_rareData) |
+ m_rareData = adoptPtr(new PaintLayerRareData); |
+ return *m_rareData; |
+ } |
+ |
+ unsigned m_layerType : 2; // PaintLayerType |
// Self-painting layer is an optimization where we avoid the heavy Layer painting |
// machinery for a Layer allocated only to handle the overflow clip case. |
@@ -770,6 +814,11 @@ private: |
unsigned m_needsPaintPhaseDescendantOutlines : 1; |
unsigned m_needsPaintPhaseFloat : 1; |
+ // These bitfields are part of ancestor/descendant dependent compositing inputs. |
+ unsigned m_hasDescendantWithClipPath : 1; |
+ unsigned m_hasNonIsolatedDescendantWithBlendMode : 1; |
+ unsigned m_hasAncestorWithClipPath : 1; |
+ |
LayoutBoxModelObject* m_layoutObject; |
PaintLayer* m_parent; |
@@ -778,9 +827,6 @@ private: |
PaintLayer* m_first; |
PaintLayer* m_last; |
- // Our current relative position offset. |
- LayoutSize m_offsetForInFlowPosition; |
- |
// Our (x,y) coordinates are in our parent layer's coordinate space. |
LayoutPoint m_location; |
@@ -794,44 +840,19 @@ private: |
LayoutUnit m_staticInlinePosition; |
LayoutUnit m_staticBlockPosition; |
- OwnPtr<TransformationMatrix> m_transform; |
- |
- // Pointer to the enclosing Layer that caused us to be paginated. It is 0 if we are not paginated. |
- // |
- // See LayoutMultiColumnFlowThread and |
- // https://sites.google.com/a/chromium.org/dev/developers/design-documents/multi-column-layout |
- // for more information about the multicol implementation. It's important to understand the |
- // difference between flow thread coordinates and visual coordinates when working with multicol |
- // in Layer, since Layer is one of the few places where we have to worry about the |
- // visual ones. Internally we try to use flow-thread coordinates whenever possible. |
- PaintLayer* m_enclosingPaginationLayer; |
- |
- // These compositing reasons are updated whenever style changes, not while updating compositing layers. |
- // They should not be used to infer the compositing state of this layer. |
- CompositingReasons m_potentialCompositingReasonsFromStyle; |
- |
- // Once computed, indicates all that a layer needs to become composited using the CompositingReasons enum bitfield. |
- CompositingReasons m_compositingReasons; |
- |
- DescendantDependentCompositingInputs m_descendantDependentCompositingInputs; |
AncestorDependentCompositingInputs m_ancestorDependentCompositingInputs; |
+ OwnPtr<RareAncestorDependentCompositingInputs> m_rareAncestorDependentCompositingInputs; |
- IntRect m_blockSelectionGapsBounds; |
- |
- OwnPtr<CompositedLayerMapping> m_compositedLayerMapping; |
OwnPtrWillBePersistent<PaintLayerScrollableArea> m_scrollableArea; |
- CompositedLayerMapping* m_groupedMapping; |
- |
PaintLayerClipper m_clipper; // FIXME: Lazily allocate? |
OwnPtr<PaintLayerStackingNode> m_stackingNode; |
- OwnPtr<PaintLayerReflectionInfo> m_reflectionInfo; |
- |
- LayoutSize m_subpixelAccumulation; // The accumulated subpixel offset of a composited layer's composited bounds compared to absolute coordinates. |
IntSize m_previousScrollOffsetAccumulationForPainting; |
RefPtr<ClipRects> m_previousPaintingClipRects; |
LayoutRect m_previousPaintDirtyRect; |
+ |
+ OwnPtr<PaintLayerRareData> m_rareData; |
}; |
} // namespace blink |