2 * Copyright (C) 2003, 2009, 2012 Apple Inc. All rights reserved.
3 * Copyright (C) 2013 Intel Corporation. All rights reserved.
5 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
8 * Robert O'Callahan <roc+@cs.cmu.edu>
9 * David Baron <dbaron@fas.harvard.edu>
10 * Christian Biesinger <cbiesinger@web.de>
11 * Randall Jesup <rjesup@wgate.com>
12 * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
13 * Josh Soref <timeless@mac.com>
14 * Boris Zbarsky <bzbarsky@mit.edu>
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 * Alternatively, the contents of this file may be used under the terms
31 * of either the Mozilla Public License Version 1.1, found at
32 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
33 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
34 * (the "GPL"), in which case the provisions of the MPL or the GPL are
35 * applicable instead of those above. If you wish to allow use of your
36 * version of this file only under the terms of one of those two
37 * licenses (the MPL or the GPL) and not to allow others to use your
38 * version of this file under the LGPL, indicate your decision by
39 * deletingthe provisions above and replace them with the notice and
40 * other provisions required by the MPL or the GPL, as the case may be.
41 * If you do not delete the provisions above, a recipient may use your
42 * version of this file under any of the LGPL, the MPL or the GPL.
48 #include "core/rendering/LayerFragment.h"
49 #include "core/rendering/RenderBox.h"
50 #include "core/rendering/RenderLayerClipper.h"
51 #include "core/rendering/RenderLayerFilterInfo.h"
52 #include "core/rendering/RenderLayerReflectionInfo.h"
53 #include "core/rendering/RenderLayerScrollableArea.h"
54 #include "core/rendering/RenderLayerStackingNode.h"
55 #include "core/rendering/RenderLayerStackingNodeIterator.h"
56 #include "platform/graphics/CompositingReasons.h"
57 #include "public/platform/WebBlendMode.h"
58 #include "wtf/OwnPtr.h"
62 class FilterEffectRenderer;
63 class FilterOperations;
66 class HitTestingTransformState;
67 class CompositedLayerMapping;
68 class RenderLayerCompositor;
70 class TransformationMatrix;
72 enum IncludeSelfOrNot { IncludeSelf, ExcludeSelf };
74 enum CompositingQueryMode {
75 CompositingQueriesAreAllowed,
76 CompositingQueriesAreOnlyAllowedInCertainDocumentLifecyclePhases
79 // FIXME: remove this once the compositing query ASSERTS are no longer hit.
80 class DisableCompositingQueryAsserts {
81 WTF_MAKE_NONCOPYABLE(DisableCompositingQueryAsserts);
83 DisableCompositingQueryAsserts();
85 TemporaryChange<CompositingQueryMode> m_disabler;
89 WTF_MAKE_NONCOPYABLE(RenderLayer);
91 RenderLayer(RenderLayerModelObject*, LayerType);
94 String debugName() const;
96 RenderLayerModelObject* renderer() const { return m_renderer; }
97 RenderBox* renderBox() const { return m_renderer && m_renderer->isBox() ? toRenderBox(m_renderer) : 0; }
98 RenderLayer* parent() const { return m_parent; }
99 RenderLayer* previousSibling() const { return m_previous; }
100 RenderLayer* nextSibling() const { return m_next; }
101 RenderLayer* firstChild() const { return m_first; }
102 RenderLayer* lastChild() const { return m_last; }
104 const RenderLayer* compositingContainer() const;
106 void addChild(RenderLayer* newChild, RenderLayer* beforeChild = 0);
107 RenderLayer* removeChild(RenderLayer*);
109 void removeOnlyThisLayer();
110 void insertOnlyThisLayer();
112 void styleChanged(StyleDifference, const RenderStyle* oldStyle);
114 // FIXME: Many people call this function while it has out-of-date information.
115 bool isSelfPaintingLayer() const { return m_isSelfPaintingLayer; }
117 void setLayerType(LayerType layerType) { m_layerType = layerType; }
119 bool isTransparent() const { return renderer()->isTransparent() || renderer()->hasBlendMode() || renderer()->hasMask(); }
120 RenderLayer* transparentPaintingAncestor();
122 bool isReflection() const { return renderer()->isReplica(); }
123 RenderLayerReflectionInfo* reflectionInfo() { return m_reflectionInfo.get(); }
124 const RenderLayerReflectionInfo* reflectionInfo() const { return m_reflectionInfo.get(); }
126 const RenderLayer* root() const
128 const RenderLayer* curr = this;
129 while (curr->parent())
130 curr = curr->parent();
134 LayoutPoint location() const;
135 IntSize size() const;
137 LayoutRect rect() const { return LayoutRect(location(), size()); }
139 bool isRootLayer() const { return m_isRootLayer; }
141 RenderLayerCompositor* compositor() const;
143 // Notification from the renderer that its content changed (e.g. current frame of image changed).
144 // Allows updates of layer content without invalidating paint.
145 void contentChanged(ContentChangeType);
147 void updateLayerPositionsAfterLayout();
149 bool isPaginated() const { return m_isPaginated; }
150 RenderLayer* enclosingPaginationLayer() const { return m_enclosingPaginationLayer; }
152 void updateTransformationMatrix();
153 RenderLayer* renderingContextRoot();
155 // Our current relative position offset.
156 const LayoutSize offsetForInFlowPosition() const;
158 void blockSelectionGapsBoundsChanged();
159 void addBlockSelectionGapsBounds(const LayoutRect&);
160 void clearBlockSelectionGapsBounds();
161 void invalidatePaintForBlockSelectionGaps();
162 IntRect blockSelectionGapsBounds() const;
163 bool hasBlockSelectionGapBounds() const;
165 RenderLayerStackingNode* stackingNode() { return m_stackingNode.get(); }
166 const RenderLayerStackingNode* stackingNode() const { return m_stackingNode.get(); }
168 bool subtreeIsInvisible() const { return !hasVisibleContent() && !hasVisibleDescendant(); }
170 // FIXME: hasVisibleContent() should call updateDescendantDependentFlags() if m_visibleContentStatusDirty.
171 bool hasVisibleContent() const { ASSERT(!m_visibleContentStatusDirty); return m_hasVisibleContent; }
173 // FIXME: hasVisibleDescendant() should call updateDescendantDependentFlags() if m_visibleDescendantStatusDirty.
174 bool hasVisibleDescendant() const { ASSERT(!m_visibleDescendantStatusDirty); return m_hasVisibleDescendant; }
176 void dirtyVisibleContentStatus();
177 void potentiallyDirtyVisibleContentStatus(EVisibility);
179 bool hasBoxDecorationsOrBackground() const;
180 bool hasVisibleBoxDecorations() const;
181 // True if this layer container renderers that paint.
182 bool hasNonEmptyChildRenderers() const;
184 // Will ensure that hasNonCompositiedChild are up to date.
185 void updateScrollingStateAfterCompositingChange();
186 bool hasVisibleNonLayerContent() const { return m_hasVisibleNonLayerContent; }
187 bool hasNonCompositedChild() const { ASSERT(isAllowedToQueryCompositingState()); return m_hasNonCompositedChild; }
189 bool usedTransparency() const { return m_usedTransparency; }
190 void setUsedTransparency(bool usedTransparency) { m_usedTransparency = usedTransparency; }
192 // Gets the nearest enclosing positioned ancestor layer (also includes
193 // the <html> layer and the root layer).
194 RenderLayer* enclosingPositionedAncestor() const;
196 bool isPaintInvalidationContainer() const;
198 // Do *not* call this method unless you know what you are dooing. You probably want to call enclosingCompositingLayerForPaintInvalidation() instead.
199 // If includeSelf is true, may return this.
200 RenderLayer* enclosingLayerWithCompositedLayerMapping(IncludeSelfOrNot) const;
202 // Returns the enclosing layer root into which this layer paints, inclusive of this one. Note that the enclosing layer may or may not have its own
203 // GraphicsLayer backing, but is nevertheless the root for a call to the RenderLayer::paint*() methods.
204 RenderLayer* enclosingLayerForPaintInvalidation() const;
206 RenderLayer* enclosingLayerForPaintInvalidationCrossingFrameBoundaries() const;
208 bool hasAncestorWithFilterOutsets() const;
210 bool canUseConvertToLayerCoords() const
212 // These RenderObjects have an impact on their layers without the renderers knowing about it.
213 return !renderer()->hasColumns() && !renderer()->hasTransformRelatedProperty() && !renderer()->isSVGRoot();
216 void convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint&) const;
217 void convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect&) const;
219 // The hitTest() method looks for mouse events by walking layers that intersect the point from front to back.
220 bool hitTest(const HitTestRequest&, HitTestResult&);
221 bool hitTest(const HitTestRequest&, const HitTestLocation&, HitTestResult&);
223 // Pass offsetFromRoot if known.
224 bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot = 0) const;
226 // Bounding box relative to some ancestor layer. Pass offsetFromRoot if known.
227 LayoutRect physicalBoundingBox(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot = 0) const;
228 LayoutRect physicalBoundingBoxIncludingReflectionAndStackingChildren(const RenderLayer* ancestorLayer, const LayoutPoint& offsetFromRoot) const;
229 LayoutRect fragmentsBoundingBox(const RenderLayer* ancestorLayer) const;
231 LayoutRect boundingBoxForCompositingOverlapTest() const;
233 // If true, this layer's children are included in its bounds for overlap testing.
234 // We can't rely on the children's positions if this layer has a filter that could have moved the children's pixels around.
235 bool overlapBoundsIncludeChildren() const { return hasFilter() && renderer()->style()->filter().hasFilterThatMovesPixels(); }
237 enum CalculateBoundsOptions {
238 ApplyBoundsChickenEggHacks,
239 DoNotApplyBoundsChickenEggHacks,
241 LayoutRect boundingBoxForCompositing(const RenderLayer* ancestorLayer = 0, CalculateBoundsOptions = DoNotApplyBoundsChickenEggHacks) const;
243 LayoutUnit staticInlinePosition() const { return m_staticInlinePosition; }
244 LayoutUnit staticBlockPosition() const { return m_staticBlockPosition; }
246 void setStaticInlinePosition(LayoutUnit position) { m_staticInlinePosition = position; }
247 void setStaticBlockPosition(LayoutUnit position) { m_staticBlockPosition = position; }
249 LayoutSize subpixelAccumulation() const;
250 void setSubpixelAccumulation(const LayoutSize&);
252 bool hasTransformRelatedProperty() const { return renderer()->hasTransformRelatedProperty(); }
253 // Note that this transform has the transform-origin baked in.
254 TransformationMatrix* transform() const { return m_transform.get(); }
255 void setTransform(PassOwnPtr<TransformationMatrix> transform) { m_transform = transform; }
256 void clearTransform() { m_transform.clear(); }
258 // currentTransform computes a transform which takes accelerated animations into account. The
259 // resulting transform has transform-origin baked in. If the layer does not have a transform,
260 // returns the identity matrix.
261 TransformationMatrix currentTransform(RenderStyle::ApplyTransformOrigin = RenderStyle::IncludeTransformOrigin) const;
262 TransformationMatrix renderableTransform(PaintBehavior) const;
264 // Get the perspective transform, which is applied to transformed sublayers.
265 // Returns true if the layer has a -webkit-perspective.
266 // Note that this transform has the perspective-origin baked in.
267 TransformationMatrix perspectiveTransform() const;
268 FloatPoint perspectiveOrigin() const;
269 bool preserves3D() const { return renderer()->style()->transformStyle3D() == TransformStyle3DPreserve3D; }
270 bool has3DTransform() const { return m_transform && !m_transform->isAffine(); }
272 // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
273 bool shouldPreserve3D() const { return !renderer()->hasReflection() && renderer()->style()->transformStyle3D() == TransformStyle3DPreserve3D; }
275 void filterNeedsPaintInvalidation();
276 bool hasFilter() const { return renderer()->hasFilter(); }
278 void* operator new(size_t);
279 // Only safe to call from RenderLayerModelObject::destroyLayer()
280 void operator delete(void*);
282 CompositingState compositingState() const;
284 // This returns true if our document is in a phase of its lifestyle during which
285 // compositing state may legally be read.
286 bool isAllowedToQueryCompositingState() const;
288 // Don't null check this.
289 CompositedLayerMapping* compositedLayerMapping() const;
290 // FIXME: This should return a reference.
291 CompositedLayerMapping* ensureCompositedLayerMapping();
292 GraphicsLayer* graphicsLayerBacking() const;
293 GraphicsLayer* graphicsLayerBackingForScrolling() const;
294 // NOTE: If you are using hasCompositedLayerMapping to determine the state of compositing for this layer,
295 // (and not just to do bookkeeping related to the mapping like, say, allocating or deallocating a mapping),
296 // then you may have incorrect logic. Use compositingState() instead.
297 // FIXME: This is identical to null checking compositedLayerMapping(), why not just call that?
298 bool hasCompositedLayerMapping() const { return m_compositedLayerMapping.get(); }
299 void clearCompositedLayerMapping(bool layerBeingDestroyed = false);
300 CompositedLayerMapping* groupedMapping() const { return m_groupedMapping; }
301 void setGroupedMapping(CompositedLayerMapping* groupedMapping, bool layerBeingDestroyed = false);
303 bool hasCompositedMask() const;
304 bool hasCompositedClippingMask() const;
305 bool needsCompositedScrolling() const { return m_scrollableArea && m_scrollableArea->needsCompositedScrolling(); }
307 // Computes the position of the given render object in the space of |paintInvalidationContainer|.
308 // FIXME: invert the logic to have paint invalidation containers take care of painting objects into them, rather than the reverse.
309 // This will allow us to clean up this static method messiness.
310 static LayoutPoint positionFromPaintInvalidationBacking(const RenderObject*, const RenderLayerModelObject* paintInvalidationContainer, const PaintInvalidationState* = 0);
312 static void mapPointToPaintBackingCoordinates(const RenderLayerModelObject* paintInvalidationContainer, FloatPoint&);
313 static void mapRectToPaintBackingCoordinates(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect&);
315 // Adjusts the given rect (in the coordinate space of the RenderObject) to the coordinate space of |paintInvalidationContainer|'s GraphicsLayer backing.
316 static void mapRectToPaintInvalidationBacking(const RenderObject*, const RenderLayerModelObject* paintInvalidationContainer, LayoutRect&, const PaintInvalidationState* = 0);
318 // Computes the bounding paint invalidation rect for |renderObject|, in the coordinate space of |paintInvalidationContainer|'s GraphicsLayer backing.
319 static LayoutRect computePaintInvalidationRect(const RenderObject*, const RenderLayer* paintInvalidationContainer, const PaintInvalidationState* = 0);
321 bool paintsWithTransparency(PaintBehavior paintBehavior) const
323 return isTransparent() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || compositingState() != PaintsIntoOwnBacking);
326 bool paintsWithTransform(PaintBehavior) const;
328 // Returns true if background phase is painted opaque in the given rect.
329 // The query rect is given in local coordinates.
330 bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const;
332 bool containsDirtyOverlayScrollbars() const { return m_containsDirtyOverlayScrollbars; }
333 void setContainsDirtyOverlayScrollbars(bool dirtyScrollbars) { m_containsDirtyOverlayScrollbars = dirtyScrollbars; }
335 FilterOperations computeFilterOperations(const RenderStyle*);
336 bool paintsWithFilters() const;
337 FilterEffectRenderer* filterRenderer() const
339 RenderLayerFilterInfo* filterInfo = this->filterInfo();
340 return filterInfo ? filterInfo->renderer() : 0;
343 RenderLayerFilterInfo* filterInfo() const { return hasFilterInfo() ? RenderLayerFilterInfo::filterInfoForRenderLayer(this) : 0; }
344 RenderLayerFilterInfo* ensureFilterInfo() { return RenderLayerFilterInfo::createFilterInfoForRenderLayerIfNeeded(this); }
345 void removeFilterInfoIfNeeded()
348 RenderLayerFilterInfo::removeFilterInfoForRenderLayer(this);
351 bool hasFilterInfo() const { return m_hasFilterInfo; }
352 void setHasFilterInfo(bool hasFilterInfo) { m_hasFilterInfo = hasFilterInfo; }
354 void updateFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle);
356 Node* enclosingElement() const;
358 bool isInTopLayer() const;
360 bool scrollsWithViewport() const;
361 bool scrollsWithRespectTo(const RenderLayer*) const;
363 void addLayerHitTestRects(LayerHitTestRects&) const;
365 // Compute rects only for this layer
366 void computeSelfHitTestRects(LayerHitTestRects&) const;
368 // FIXME: This should probably return a ScrollableArea but a lot of internal methods are mistakenly exposed.
369 RenderLayerScrollableArea* scrollableArea() const { return m_scrollableArea.get(); }
370 RenderLayerClipper& clipper() { return m_clipper; }
371 const RenderLayerClipper& clipper() const { return m_clipper; }
373 inline bool isPositionedContainer() const
375 // FIXME: This is not in sync with containingBlock.
376 // RenderObject::canContainFixedPositionedObject() should probably be used
378 RenderLayerModelObject* layerRenderer = renderer();
379 return isRootLayer() || layerRenderer->isPositioned() || hasTransformRelatedProperty();
382 bool scrollsOverflow() const;
384 CompositingReasons potentialCompositingReasonsFromStyle() const { return m_potentialCompositingReasonsFromStyle; }
385 void setPotentialCompositingReasonsFromStyle(CompositingReasons reasons) { ASSERT(reasons == (reasons & CompositingReasonComboAllStyleDeterminedReasons)); m_potentialCompositingReasonsFromStyle = reasons; }
387 bool hasStyleDeterminedDirectCompositingReasons() const { return m_potentialCompositingReasonsFromStyle & CompositingReasonComboAllDirectStyleDeterminedReasons; }
389 class AncestorDependentCompositingInputs {
391 AncestorDependentCompositingInputs()
393 , transformAncestor(0)
395 , clippingContainer(0)
396 , ancestorScrollingLayer(0)
399 , hasAncestorWithClipPath(false)
402 IntRect clippedAbsoluteBoundingBox;
403 const RenderLayer* opacityAncestor;
404 const RenderLayer* transformAncestor;
405 const RenderLayer* filterAncestor;
406 const RenderObject* clippingContainer;
407 const RenderLayer* ancestorScrollingLayer;
409 // A scroll parent is a compositor concept. It's only needed in blink
410 // because we need to use it as a promotion trigger. A layer has a
411 // scroll parent if neither its compositor scrolling ancestor, nor any
412 // other layer scrolled by this ancestor, is a stacking ancestor of this
413 // layer. Layers with scroll parents must be scrolled with the main
414 // scrolling layer by the compositor.
415 const RenderLayer* scrollParent;
417 // A clip parent is another compositor concept that has leaked into
418 // blink so that it may be used as a promotion trigger. Layers with clip
419 // parents escape the clip of a stacking tree ancestor. The compositor
420 // needs to know about clip parents in order to circumvent its normal
422 const RenderLayer* clipParent;
424 unsigned hasAncestorWithClipPath : 1;
427 class DescendantDependentCompositingInputs {
429 DescendantDependentCompositingInputs()
430 : hasDescendantWithClipPath(false)
431 , hasNonIsolatedDescendantWithBlendMode(false)
434 unsigned hasDescendantWithClipPath : 1;
435 unsigned hasNonIsolatedDescendantWithBlendMode : 1;
438 void setNeedsCompositingInputsUpdate();
439 bool childNeedsCompositingInputsUpdate() const { return m_childNeedsCompositingInputsUpdate; }
440 bool needsCompositingInputsUpdate() const
442 // While we're updating the compositing inputs, these values may differ.
443 // We should never be asking for this value when that is the case.
444 ASSERT(m_needsDescendantDependentCompositingInputsUpdate == m_needsAncestorDependentCompositingInputsUpdate);
445 return m_needsDescendantDependentCompositingInputsUpdate;
448 void updateAncestorDependentCompositingInputs(const AncestorDependentCompositingInputs&);
449 void updateDescendantDependentCompositingInputs(const DescendantDependentCompositingInputs&);
450 void didUpdateCompositingInputs();
452 const AncestorDependentCompositingInputs& ancestorDependentCompositingInputs() const { ASSERT(!m_needsAncestorDependentCompositingInputsUpdate); return m_ancestorDependentCompositingInputs; }
453 const DescendantDependentCompositingInputs& descendantDependentCompositingInputs() const { ASSERT(!m_needsDescendantDependentCompositingInputsUpdate); return m_descendantDependentCompositingInputs; }
455 IntRect clippedAbsoluteBoundingBox() const { return ancestorDependentCompositingInputs().clippedAbsoluteBoundingBox; }
456 const RenderLayer* opacityAncestor() const { return ancestorDependentCompositingInputs().opacityAncestor; }
457 const RenderLayer* transformAncestor() const { return ancestorDependentCompositingInputs().transformAncestor; }
458 const RenderLayer* filterAncestor() const { return ancestorDependentCompositingInputs().filterAncestor; }
459 const RenderObject* clippingContainer() const { return ancestorDependentCompositingInputs().clippingContainer; }
460 const RenderLayer* ancestorScrollingLayer() const { return ancestorDependentCompositingInputs().ancestorScrollingLayer; }
461 RenderLayer* scrollParent() const { return const_cast<RenderLayer*>(ancestorDependentCompositingInputs().scrollParent); }
462 RenderLayer* clipParent() const { return const_cast<RenderLayer*>(ancestorDependentCompositingInputs().clipParent); }
463 bool hasAncestorWithClipPath() const { return ancestorDependentCompositingInputs().hasAncestorWithClipPath; }
464 bool hasDescendantWithClipPath() const { return descendantDependentCompositingInputs().hasDescendantWithClipPath; }
465 bool hasNonIsolatedDescendantWithBlendMode() const { return descendantDependentCompositingInputs().hasNonIsolatedDescendantWithBlendMode; }
467 bool lostGroupedMapping() const { ASSERT(isAllowedToQueryCompositingState()); return m_lostGroupedMapping; }
468 void setLostGroupedMapping(bool b) { m_lostGroupedMapping = b; }
470 CompositingReasons compositingReasons() const { ASSERT(isAllowedToQueryCompositingState()); return m_compositingReasons; }
471 void setCompositingReasons(CompositingReasons, CompositingReasons mask = CompositingReasonAll);
473 bool hasCompositingDescendant() const { ASSERT(isAllowedToQueryCompositingState()); return m_hasCompositingDescendant; }
474 void setHasCompositingDescendant(bool);
476 bool shouldIsolateCompositedDescendants() const { ASSERT(isAllowedToQueryCompositingState()); return m_shouldIsolateCompositedDescendants; }
477 void setShouldIsolateCompositedDescendants(bool);
479 void updateDescendantDependentFlags();
480 void updateDescendantDependentFlagsForEntireSubtree();
482 void updateOrRemoveFilterEffectRenderer();
484 void updateSelfPaintingLayer();
486 RenderLayer* enclosingTransformedAncestor() const;
487 LayoutPoint computeOffsetFromTransformedAncestor() const;
489 void didUpdateNeedsCompositedScrolling();
491 void setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
493 bool hasSelfPaintingLayerDescendant() const
495 if (m_hasSelfPaintingLayerDescendantDirty)
496 updateHasSelfPaintingLayerDescendant();
497 ASSERT(!m_hasSelfPaintingLayerDescendantDirty);
498 return m_hasSelfPaintingLayerDescendant;
500 LayoutRect paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior);
501 void collectFragments(LayerFragments&, const RenderLayer* rootLayer, const LayoutRect& dirtyRect,
502 ClipRectsCacheSlot, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize,
503 ShouldRespectOverflowClip = RespectOverflowClip, const LayoutPoint* offsetFromRoot = 0,
504 const LayoutSize& subPixelAccumulation = LayoutSize(), const LayoutRect* layerBoundingBox = 0);
506 LayoutPoint renderBoxLocation() const { return renderer()->isBox() ? toRenderBox(renderer())->location() : LayoutPoint(); }
508 enum TransparencyClipBoxBehavior {
509 PaintingTransparencyClipBox,
510 HitTestingTransparencyClipBox
513 enum TransparencyClipBoxMode {
514 DescendantsOfTransparencyClipBox,
515 RootOfTransparencyClipBox
518 static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior,
519 TransparencyClipBoxMode transparencyMode, const LayoutSize& subPixelAccumulation, PaintBehavior = 0);
522 // Bounding box in the coordinates of this layer.
523 LayoutRect logicalBoundingBox() const;
525 bool hasOverflowControls() const;
527 void dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
529 void updateLayerPositionRecursive();
531 void setNextSibling(RenderLayer* next) { m_next = next; }
532 void setPreviousSibling(RenderLayer* prev) { m_previous = prev; }
533 void setFirstChild(RenderLayer* first) { m_first = first; }
534 void setLastChild(RenderLayer* last) { m_last = last; }
536 void updateHasSelfPaintingLayerDescendant() const;
537 RenderLayer* hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
538 const LayoutRect& hitTestRect, const HitTestLocation&, bool appliedTransform,
539 const HitTestingTransformState* transformState = 0, double* zOffset = 0);
540 RenderLayer* hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&,
541 const LayoutRect& hitTestRect, const HitTestLocation&, const HitTestingTransformState* = 0, double* zOffset = 0,
542 const LayoutPoint& translationOffset = LayoutPoint());
543 RenderLayer* hitTestChildren(ChildrenIteration, RenderLayer* rootLayer, const HitTestRequest&, HitTestResult&,
544 const LayoutRect& hitTestRect, const HitTestLocation&,
545 const HitTestingTransformState* transformState, double* zOffsetForDescendants, double* zOffset,
546 const HitTestingTransformState* unflattenedTransformState, bool depthSortDescendants);
547 RenderLayer* hitTestPaginatedChildLayer(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
548 const LayoutRect& hitTestRect, const HitTestLocation&,
549 const HitTestingTransformState* transformState, double* zOffset);
550 RenderLayer* hitTestChildLayerColumns(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
551 const LayoutRect& hitTestRect, const HitTestLocation&,
552 const HitTestingTransformState* transformState, double* zOffset,
553 const Vector<RenderLayer*>& columnLayers, size_t columnIndex);
555 PassRefPtr<HitTestingTransformState> createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer,
556 const LayoutRect& hitTestRect, const HitTestLocation&,
557 const HitTestingTransformState* containerTransformState,
558 const LayoutPoint& translationOffset = LayoutPoint()) const;
560 bool hitTestContents(const HitTestRequest&, HitTestResult&, const LayoutRect& layerBounds, const HitTestLocation&, HitTestFilter) const;
561 bool hitTestContentsForFragments(const LayerFragments&, const HitTestRequest&, HitTestResult&, const HitTestLocation&, HitTestFilter, bool& insideClipRect) const;
562 RenderLayer* hitTestTransformedLayerInFragments(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&,
563 const LayoutRect& hitTestRect, const HitTestLocation&, const HitTestingTransformState* = 0, double* zOffset = 0);
565 bool childBackgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const;
567 bool shouldBeSelfPaintingLayer() const;
569 // FIXME: We should only create the stacking node if needed.
570 bool requiresStackingNode() const { return true; }
571 void updateStackingNode();
573 void updateReflectionInfo(const RenderStyle*);
575 // FIXME: We could lazily allocate our ScrollableArea based on style properties ('overflow', ...)
576 // but for now, we are always allocating it for RenderBox as it's safer.
577 bool requiresScrollableArea() const { return renderBox(); }
578 void updateScrollableArea();
580 void dirtyAncestorChainVisibleDescendantStatus();
582 bool attemptDirectCompositingUpdate(StyleDifference, const RenderStyle* oldStyle);
583 void updateTransform(const RenderStyle* oldStyle, RenderStyle* newStyle);
585 void dirty3DTransformedDescendantStatus();
586 // Both updates the status, and returns true if descendants of this have 3d.
587 bool update3DTransformedDescendantStatus();
589 void updateOrRemoveFilterClients();
591 void updatePaginationRecursive(bool needsPaginationUpdate = false);
592 void updatePagination();
594 // FIXME: Temporary. Remove when new columns come online.
595 bool useRegionBasedColumns() const;
597 LayerType m_layerType;
599 // Self-painting layer is an optimization where we avoid the heavy RenderLayer painting
600 // machinery for a RenderLayer allocated only to handle the overflow clip case.
601 // FIXME(crbug.com/332791): Self-painting layer should be merged into the overflow-only concept.
602 unsigned m_isSelfPaintingLayer : 1;
604 // If have no self-painting descendants, we don't have to walk our children during painting. This can lead to
605 // significant savings, especially if the tree has lots of non-self-painting layers grouped together (e.g. table cells).
606 mutable unsigned m_hasSelfPaintingLayerDescendant : 1;
607 mutable unsigned m_hasSelfPaintingLayerDescendantDirty : 1;
609 const unsigned m_isRootLayer : 1;
611 unsigned m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether
612 // we ended up painting this layer or any descendants (and therefore need to
615 unsigned m_visibleContentStatusDirty : 1;
616 unsigned m_hasVisibleContent : 1;
617 unsigned m_visibleDescendantStatusDirty : 1;
618 unsigned m_hasVisibleDescendant : 1;
620 unsigned m_hasVisibleNonLayerContent : 1;
622 unsigned m_isPaginated : 1; // If we think this layer is split by a multi-column ancestor, then this bit will be set.
624 unsigned m_3DTransformedDescendantStatusDirty : 1;
625 // Set on a stacking context layer that has 3D descendants anywhere
626 // in a preserves3D hierarchy. Hint to do 3D-aware hit testing.
627 unsigned m_has3DTransformedDescendant : 1;
629 unsigned m_containsDirtyOverlayScrollbars : 1;
631 unsigned m_hasFilterInfo : 1;
632 unsigned m_needsAncestorDependentCompositingInputsUpdate : 1;
633 unsigned m_needsDescendantDependentCompositingInputsUpdate : 1;
634 unsigned m_childNeedsCompositingInputsUpdate : 1;
636 // Used only while determining what layers should be composited. Applies to the tree of z-order lists.
637 unsigned m_hasCompositingDescendant : 1;
639 // Applies to the real render layer tree (i.e., the tree determined by the layer's parent and children and
640 // as opposed to the tree formed by the z-order and normal flow lists).
641 unsigned m_hasNonCompositedChild : 1;
643 // Should be for stacking contexts having unisolated blending descendants.
644 unsigned m_shouldIsolateCompositedDescendants : 1;
646 // True if this render layer just lost its grouped mapping due to the CompositedLayerMapping being destroyed,
647 // and we don't yet know to what graphics layer this RenderLayer will be assigned.
648 unsigned m_lostGroupedMapping : 1;
650 RenderLayerModelObject* m_renderer;
652 RenderLayer* m_parent;
653 RenderLayer* m_previous;
655 RenderLayer* m_first;
658 // Cached normal flow values for absolute positioned elements with static left/top values.
659 LayoutUnit m_staticInlinePosition;
660 LayoutUnit m_staticBlockPosition;
662 OwnPtr<TransformationMatrix> m_transform;
664 // Pointer to the enclosing RenderLayer that caused us to be paginated. It is 0 if we are not paginated.
665 RenderLayer* m_enclosingPaginationLayer;
667 // These compositing reasons are updated whenever style changes, not while updating compositing layers.
668 // They should not be used to infer the compositing state of this layer.
669 CompositingReasons m_potentialCompositingReasonsFromStyle;
671 // Once computed, indicates all that a layer needs to become composited using the CompositingReasons enum bitfield.
672 CompositingReasons m_compositingReasons;
674 DescendantDependentCompositingInputs m_descendantDependentCompositingInputs;
675 AncestorDependentCompositingInputs m_ancestorDependentCompositingInputs;
677 IntRect m_blockSelectionGapsBounds;
679 OwnPtr<CompositedLayerMapping> m_compositedLayerMapping;
680 OwnPtr<RenderLayerScrollableArea> m_scrollableArea;
682 CompositedLayerMapping* m_groupedMapping;
684 RenderLayerClipper m_clipper; // FIXME: Lazily allocate?
685 OwnPtr<RenderLayerStackingNode> m_stackingNode;
686 OwnPtrWillBePersistent<RenderLayerReflectionInfo> m_reflectionInfo;
688 LayoutSize m_subpixelAccumulation; // The accumulated subpixel offset of a composited layer's composited bounds compared to absolute coordinates.
694 // Outside the WebCore namespace for ease of invocation from gdb.
695 void showLayerTree(const blink::RenderLayer*);
696 void showLayerTree(const blink::RenderObject*);
699 #endif // RenderLayer_h