1 /* 2 * Copyright (C) 2003, 2009, 2012 Apple Inc. All rights reserved. 3 * Copyright (C) 2013 Intel Corporation. All rights reserved. 4 * 5 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 6 * 7 * Other contributors: 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> 15 * 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. 20 * 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. 25 * 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 29 * 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. 43 */ 44 45 #ifndef RenderLayer_h 46 #define RenderLayer_h 47 48 #include "core/rendering/LayerFragment.h" 49 #include "core/rendering/LayerPaintingInfo.h" 50 #include "core/rendering/RenderBox.h" 51 #include "core/rendering/RenderLayerClipper.h" 52 #include "core/rendering/RenderLayerFilterInfo.h" 53 #include "core/rendering/RenderLayerReflectionInfo.h" 54 #include "core/rendering/RenderLayerScrollableArea.h" 55 #include "core/rendering/RenderLayerStackingNode.h" 56 #include "core/rendering/RenderLayerStackingNodeIterator.h" 57 #include "platform/graphics/CompositingReasons.h" 58 #include "public/platform/WebBlendMode.h" 59 #include "wtf/OwnPtr.h" 60 61 namespace blink { 62 63 class FilterEffectRenderer; 64 class FilterOperations; 65 class HitTestRequest; 66 class HitTestResult; 67 class HitTestingTransformState; 68 class CompositedLayerMapping; 69 class RenderLayerCompositor; 70 class RenderStyle; 71 class TransformationMatrix; 72 73 enum BorderRadiusClippingRule { IncludeSelfForBorderRadius, DoNotIncludeSelfForBorderRadius }; 74 enum IncludeSelfOrNot { IncludeSelf, ExcludeSelf }; 75 76 enum CompositingQueryMode { 77 CompositingQueriesAreAllowed, 78 CompositingQueriesAreOnlyAllowedInCertainDocumentLifecyclePhases 79 }; 80 81 // FIXME: remove this once the compositing query ASSERTS are no longer hit. 82 class DisableCompositingQueryAsserts { 83 WTF_MAKE_NONCOPYABLE(DisableCompositingQueryAsserts); 84 public: 85 DisableCompositingQueryAsserts(); 86 private: 87 TemporaryChange<CompositingQueryMode> m_disabler; 88 }; 89 90 class RenderLayer { 91 WTF_MAKE_NONCOPYABLE(RenderLayer); 92 public: 93 RenderLayer(RenderLayerModelObject*, LayerType); 94 ~RenderLayer(); 95 96 String debugName() const; 97 renderer()98 RenderLayerModelObject* renderer() const { return m_renderer; } renderBox()99 RenderBox* renderBox() const { return m_renderer && m_renderer->isBox() ? toRenderBox(m_renderer) : 0; } parent()100 RenderLayer* parent() const { return m_parent; } previousSibling()101 RenderLayer* previousSibling() const { return m_previous; } nextSibling()102 RenderLayer* nextSibling() const { return m_next; } firstChild()103 RenderLayer* firstChild() const { return m_first; } lastChild()104 RenderLayer* lastChild() const { return m_last; } 105 106 const RenderLayer* compositingContainer() const; 107 108 void addChild(RenderLayer* newChild, RenderLayer* beforeChild = 0); 109 RenderLayer* removeChild(RenderLayer*); 110 111 void removeOnlyThisLayer(); 112 void insertOnlyThisLayer(); 113 114 void styleChanged(StyleDifference, const RenderStyle* oldStyle); 115 116 // FIXME: Many people call this function while it has out-of-date information. isSelfPaintingLayer()117 bool isSelfPaintingLayer() const { return m_isSelfPaintingLayer; } 118 setLayerType(LayerType layerType)119 void setLayerType(LayerType layerType) { m_layerType = layerType; } 120 isTransparent()121 bool isTransparent() const { return renderer()->isTransparent() || renderer()->hasMask(); } 122 RenderLayer* transparentPaintingAncestor(); 123 void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior); 124 isReflection()125 bool isReflection() const { return renderer()->isReplica(); } reflectionInfo()126 RenderLayerReflectionInfo* reflectionInfo() { return m_reflectionInfo.get(); } reflectionInfo()127 const RenderLayerReflectionInfo* reflectionInfo() const { return m_reflectionInfo.get(); } 128 root()129 const RenderLayer* root() const 130 { 131 const RenderLayer* curr = this; 132 while (curr->parent()) 133 curr = curr->parent(); 134 return curr; 135 } 136 137 LayoutPoint location() const; 138 IntSize size() const; 139 rect()140 LayoutRect rect() const { return LayoutRect(location(), size()); } 141 isRootLayer()142 bool isRootLayer() const { return m_isRootLayer; } 143 144 RenderLayerCompositor* compositor() const; 145 146 // Notification from the renderer that its content changed (e.g. current frame of image changed). 147 // Allows updates of layer content without invalidating paint. 148 void contentChanged(ContentChangeType); 149 150 void updateLayerPositionsAfterLayout(); 151 isPaginated()152 bool isPaginated() const { return m_isPaginated; } enclosingPaginationLayer()153 RenderLayer* enclosingPaginationLayer() const { return m_enclosingPaginationLayer; } 154 155 void updateTransformationMatrix(); 156 RenderLayer* renderingContextRoot(); 157 158 // Our current relative position offset. 159 const LayoutSize offsetForInFlowPosition() const; 160 161 void blockSelectionGapsBoundsChanged(); 162 void addBlockSelectionGapsBounds(const LayoutRect&); 163 void clearBlockSelectionGapsBounds(); 164 void invalidatePaintForBlockSelectionGaps(); 165 IntRect blockSelectionGapsBounds() const; 166 bool hasBlockSelectionGapBounds() const; 167 stackingNode()168 RenderLayerStackingNode* stackingNode() { return m_stackingNode.get(); } stackingNode()169 const RenderLayerStackingNode* stackingNode() const { return m_stackingNode.get(); } 170 subtreeIsInvisible()171 bool subtreeIsInvisible() const { return !hasVisibleContent() && !hasVisibleDescendant(); } 172 173 // FIXME: hasVisibleContent() should call updateDescendantDependentFlags() if m_visibleContentStatusDirty. hasVisibleContent()174 bool hasVisibleContent() const { ASSERT(!m_visibleContentStatusDirty); return m_hasVisibleContent; } 175 176 // FIXME: hasVisibleDescendant() should call updateDescendantDependentFlags() if m_visibleDescendantStatusDirty. hasVisibleDescendant()177 bool hasVisibleDescendant() const { ASSERT(!m_visibleDescendantStatusDirty); return m_hasVisibleDescendant; } 178 179 void dirtyVisibleContentStatus(); 180 void potentiallyDirtyVisibleContentStatus(EVisibility); 181 182 bool hasBoxDecorationsOrBackground() const; 183 bool hasVisibleBoxDecorations() const; 184 // Returns true if this layer has visible content (ignoring any child layers). 185 bool isVisuallyNonEmpty() const; 186 // True if this layer container renderers that paint. 187 bool hasNonEmptyChildRenderers() const; 188 189 // Will ensure that hasNonCompositiedChild are up to date. 190 void updateScrollingStateAfterCompositingChange(); hasVisibleNonLayerContent()191 bool hasVisibleNonLayerContent() const { return m_hasVisibleNonLayerContent; } hasNonCompositedChild()192 bool hasNonCompositedChild() const { ASSERT(isAllowedToQueryCompositingState()); return m_hasNonCompositedChild; } 193 usedTransparency()194 bool usedTransparency() const { return m_usedTransparency; } 195 196 // Gets the nearest enclosing positioned ancestor layer (also includes 197 // the <html> layer and the root layer). 198 RenderLayer* enclosingPositionedAncestor() const; 199 200 RenderLayer* enclosingOverflowClipLayer(IncludeSelfOrNot = IncludeSelf) const; 201 202 bool isPaintInvalidationContainer() const; 203 204 // Do *not* call this method unless you know what you are dooing. You probably want to call enclosingCompositingLayerForPaintInvalidation() instead. 205 // If includeSelf is true, may return this. 206 RenderLayer* enclosingLayerWithCompositedLayerMapping(IncludeSelfOrNot) const; 207 208 // 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 209 // GraphicsLayer backing, but is nevertheless the root for a call to the RenderLayer::paint*() methods. 210 RenderLayer* enclosingLayerForPaintInvalidation() const; 211 212 RenderLayer* enclosingLayerForPaintInvalidationCrossingFrameBoundaries() const; 213 214 bool hasAncestorWithFilterOutsets() const; 215 canUseConvertToLayerCoords()216 bool canUseConvertToLayerCoords() const 217 { 218 // These RenderObjects have an impact on their layers without the renderers knowing about it. 219 return !renderer()->hasColumns() && !renderer()->hasTransform() && !renderer()->isSVGRoot(); 220 } 221 222 void convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint&) const; 223 void convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect&) const; 224 225 // The two main functions that use the layer system. The paint method 226 // paints the layers that intersect the damage rect from back to 227 // front. The hitTest method looks for mouse events by walking 228 // layers that intersect the point from front to back. 229 // paint() assumes that the caller will clip to the bounds of damageRect if necessary. 230 void paint(GraphicsContext*, const LayoutRect& damageRect, PaintBehavior = PaintBehaviorNormal, RenderObject* paintingRoot = 0, PaintLayerFlags = 0); 231 bool hitTest(const HitTestRequest&, HitTestResult&); 232 bool hitTest(const HitTestRequest&, const HitTestLocation&, HitTestResult&); 233 void paintOverlayScrollbars(GraphicsContext*, const LayoutRect& damageRect, PaintBehavior, RenderObject* paintingRoot = 0); 234 235 // Pass offsetFromRoot if known. 236 bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot = 0) const; 237 238 // Bounding box relative to some ancestor layer. Pass offsetFromRoot if known. 239 LayoutRect physicalBoundingBox(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot = 0) const; 240 LayoutRect physicalBoundingBoxIncludingReflectionAndStackingChildren(const RenderLayer* ancestorLayer, const LayoutPoint& offsetFromRoot) const; 241 242 // FIXME: This function is inconsistent as to whether the returned rect has been flipped for writing mode. boundingBoxForCompositingOverlapTest()243 LayoutRect boundingBoxForCompositingOverlapTest() const { return overlapBoundsIncludeChildren() ? boundingBoxForCompositing() : logicalBoundingBox(); } 244 245 // If true, this layer's children are included in its bounds for overlap testing. 246 // We can't rely on the children's positions if this layer has a filter that could have moved the children's pixels around. overlapBoundsIncludeChildren()247 bool overlapBoundsIncludeChildren() const { return hasFilter() && renderer()->style()->filter().hasFilterThatMovesPixels(); } 248 249 enum CalculateBoundsOptions { 250 ApplyBoundsChickenEggHacks, 251 DoNotApplyBoundsChickenEggHacks, 252 }; 253 LayoutRect boundingBoxForCompositing(const RenderLayer* ancestorLayer = 0, CalculateBoundsOptions = DoNotApplyBoundsChickenEggHacks) const; 254 staticInlinePosition()255 LayoutUnit staticInlinePosition() const { return m_staticInlinePosition; } staticBlockPosition()256 LayoutUnit staticBlockPosition() const { return m_staticBlockPosition; } 257 setStaticInlinePosition(LayoutUnit position)258 void setStaticInlinePosition(LayoutUnit position) { m_staticInlinePosition = position; } setStaticBlockPosition(LayoutUnit position)259 void setStaticBlockPosition(LayoutUnit position) { m_staticBlockPosition = position; } 260 261 LayoutSize subpixelAccumulation() const; 262 void setSubpixelAccumulation(const LayoutSize&); 263 hasTransform()264 bool hasTransform() const { return renderer()->hasTransform(); } 265 // Note that this transform has the transform-origin baked in. transform()266 TransformationMatrix* transform() const { return m_transform.get(); } 267 // currentTransform computes a transform which takes accelerated animations into account. The 268 // resulting transform has transform-origin baked in. If the layer does not have a transform, 269 // returns the identity matrix. 270 TransformationMatrix currentTransform(RenderStyle::ApplyTransformOrigin = RenderStyle::IncludeTransformOrigin) const; 271 TransformationMatrix renderableTransform(PaintBehavior) const; 272 273 // Get the perspective transform, which is applied to transformed sublayers. 274 // Returns true if the layer has a -webkit-perspective. 275 // Note that this transform has the perspective-origin baked in. 276 TransformationMatrix perspectiveTransform() const; 277 FloatPoint perspectiveOrigin() const; preserves3D()278 bool preserves3D() const { return renderer()->style()->transformStyle3D() == TransformStyle3DPreserve3D; } has3DTransform()279 bool has3DTransform() const { return m_transform && !m_transform->isAffine(); } 280 281 // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959 shouldPreserve3D()282 bool shouldPreserve3D() const { return !renderer()->hasReflection() && renderer()->style()->transformStyle3D() == TransformStyle3DPreserve3D; } 283 284 void filterNeedsPaintInvalidation(); hasFilter()285 bool hasFilter() const { return renderer()->hasFilter(); } 286 287 bool paintsWithBlendMode() const; 288 289 void* operator new(size_t); 290 // Only safe to call from RenderLayerModelObject::destroyLayer() 291 void operator delete(void*); 292 293 CompositingState compositingState() const; 294 295 // This returns true if our document is in a phase of its lifestyle during which 296 // compositing state may legally be read. 297 bool isAllowedToQueryCompositingState() const; 298 299 // Don't null check this. 300 CompositedLayerMapping* compositedLayerMapping() const; 301 // FIXME: This should return a reference. 302 CompositedLayerMapping* ensureCompositedLayerMapping(); 303 GraphicsLayer* graphicsLayerBacking() const; 304 GraphicsLayer* graphicsLayerBackingForScrolling() const; 305 // NOTE: If you are using hasCompositedLayerMapping to determine the state of compositing for this layer, 306 // (and not just to do bookkeeping related to the mapping like, say, allocating or deallocating a mapping), 307 // then you may have incorrect logic. Use compositingState() instead. 308 // FIXME: This is identical to null checking compositedLayerMapping(), why not just call that? hasCompositedLayerMapping()309 bool hasCompositedLayerMapping() const { return m_compositedLayerMapping.get(); } 310 void clearCompositedLayerMapping(bool layerBeingDestroyed = false); groupedMapping()311 CompositedLayerMapping* groupedMapping() const { return m_groupedMapping; } 312 void setGroupedMapping(CompositedLayerMapping* groupedMapping, bool layerBeingDestroyed = false); 313 314 bool hasCompositedMask() const; 315 bool hasCompositedClippingMask() const; needsCompositedScrolling()316 bool needsCompositedScrolling() const { return m_scrollableArea && m_scrollableArea->needsCompositedScrolling(); } 317 318 bool clipsCompositingDescendantsWithBorderRadius() const; 319 320 // Computes the position of the given render object in the space of |paintInvalidationContainer|. 321 // FIXME: invert the logic to have paint invalidation containers take care of painting objects into them, rather than the reverse. 322 // This will allow us to clean up this static method messiness. 323 static LayoutPoint positionFromPaintInvalidationBacking(const RenderObject*, const RenderLayerModelObject* paintInvalidationContainer, const PaintInvalidationState* = 0); 324 325 static void mapPointToPaintBackingCoordinates(const RenderLayerModelObject* paintInvalidationContainer, FloatPoint&); 326 static void mapRectToPaintBackingCoordinates(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect&); 327 328 // Adjusts the given rect (in the coordinate space of the RenderObject) to the coordinate space of |paintInvalidationContainer|'s GraphicsLayer backing. 329 static void mapRectToPaintInvalidationBacking(const RenderObject*, const RenderLayerModelObject* paintInvalidationContainer, LayoutRect&, const PaintInvalidationState* = 0); 330 331 // Computes the bounding paint invalidation rect for |renderObject|, in the coordinate space of |paintInvalidationContainer|'s GraphicsLayer backing. 332 static LayoutRect computePaintInvalidationRect(const RenderObject*, const RenderLayer* paintInvalidationContainer, const PaintInvalidationState* = 0); 333 paintsWithTransparency(PaintBehavior paintBehavior)334 bool paintsWithTransparency(PaintBehavior paintBehavior) const 335 { 336 return isTransparent() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || compositingState() != PaintsIntoOwnBacking); 337 } 338 339 bool paintsWithTransform(PaintBehavior) const; 340 341 // Returns true if background phase is painted opaque in the given rect. 342 // The query rect is given in local coordinates. 343 bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const; 344 containsDirtyOverlayScrollbars()345 bool containsDirtyOverlayScrollbars() const { return m_containsDirtyOverlayScrollbars; } setContainsDirtyOverlayScrollbars(bool dirtyScrollbars)346 void setContainsDirtyOverlayScrollbars(bool dirtyScrollbars) { m_containsDirtyOverlayScrollbars = dirtyScrollbars; } 347 348 FilterOperations computeFilterOperations(const RenderStyle*); 349 bool paintsWithFilters() const; filterRenderer()350 FilterEffectRenderer* filterRenderer() const 351 { 352 RenderLayerFilterInfo* filterInfo = this->filterInfo(); 353 return filterInfo ? filterInfo->renderer() : 0; 354 } 355 filterInfo()356 RenderLayerFilterInfo* filterInfo() const { return hasFilterInfo() ? RenderLayerFilterInfo::filterInfoForRenderLayer(this) : 0; } ensureFilterInfo()357 RenderLayerFilterInfo* ensureFilterInfo() { return RenderLayerFilterInfo::createFilterInfoForRenderLayerIfNeeded(this); } removeFilterInfoIfNeeded()358 void removeFilterInfoIfNeeded() 359 { 360 if (hasFilterInfo()) 361 RenderLayerFilterInfo::removeFilterInfoForRenderLayer(this); 362 } 363 hasFilterInfo()364 bool hasFilterInfo() const { return m_hasFilterInfo; } setHasFilterInfo(bool hasFilterInfo)365 void setHasFilterInfo(bool hasFilterInfo) { m_hasFilterInfo = hasFilterInfo; } 366 367 void updateFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle); 368 369 Node* enclosingElement() const; 370 371 bool isInTopLayer() const; 372 373 bool scrollsWithViewport() const; 374 bool scrollsWithRespectTo(const RenderLayer*) const; 375 376 void addLayerHitTestRects(LayerHitTestRects&) const; 377 378 // Compute rects only for this layer 379 void computeSelfHitTestRects(LayerHitTestRects&) const; 380 381 // FIXME: This should probably return a ScrollableArea but a lot of internal methods are mistakenly exposed. scrollableArea()382 RenderLayerScrollableArea* scrollableArea() const { return m_scrollableArea.get(); } clipper()383 RenderLayerClipper& clipper() { return m_clipper; } clipper()384 const RenderLayerClipper& clipper() const { return m_clipper; } 385 isPositionedContainer()386 inline bool isPositionedContainer() const 387 { 388 // FIXME: This is not in sync with containingBlock. 389 // RenderObject::canContainFixedPositionedObject() should probably be used 390 // instead. 391 RenderLayerModelObject* layerRenderer = renderer(); 392 return isRootLayer() || layerRenderer->isPositioned() || hasTransform(); 393 } 394 395 // paintLayer() assumes that the caller will clip to the bounds of the painting dirty if necessary. 396 void paintLayer(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); 397 398 bool scrollsOverflow() const; 399 potentialCompositingReasonsFromStyle()400 CompositingReasons potentialCompositingReasonsFromStyle() const { return m_potentialCompositingReasonsFromStyle; } setPotentialCompositingReasonsFromStyle(CompositingReasons reasons)401 void setPotentialCompositingReasonsFromStyle(CompositingReasons reasons) { ASSERT(reasons == (reasons & CompositingReasonComboAllStyleDeterminedReasons)); m_potentialCompositingReasonsFromStyle = reasons; } 402 hasStyleDeterminedDirectCompositingReasons()403 bool hasStyleDeterminedDirectCompositingReasons() const { return m_potentialCompositingReasonsFromStyle & CompositingReasonComboAllDirectStyleDeterminedReasons; } 404 405 class AncestorDependentCompositingInputs { 406 public: AncestorDependentCompositingInputs()407 AncestorDependentCompositingInputs() 408 : opacityAncestor(0) 409 , transformAncestor(0) 410 , filterAncestor(0) 411 , clippingContainer(0) 412 , ancestorScrollingLayer(0) 413 , scrollParent(0) 414 , clipParent(0) 415 , isUnclippedDescendant(false) 416 , hasAncestorWithClipPath(false) 417 { } 418 419 IntRect clippedAbsoluteBoundingBox; 420 const RenderLayer* opacityAncestor; 421 const RenderLayer* transformAncestor; 422 const RenderLayer* filterAncestor; 423 const RenderObject* clippingContainer; 424 const RenderLayer* ancestorScrollingLayer; 425 426 // A scroll parent is a compositor concept. It's only needed in blink 427 // because we need to use it as a promotion trigger. A layer has a 428 // scroll parent if neither its compositor scrolling ancestor, nor any 429 // other layer scrolled by this ancestor, is a stacking ancestor of this 430 // layer. Layers with scroll parents must be scrolled with the main 431 // scrolling layer by the compositor. 432 const RenderLayer* scrollParent; 433 434 // A clip parent is another compositor concept that has leaked into 435 // blink so that it may be used as a promotion trigger. Layers with clip 436 // parents escape the clip of a stacking tree ancestor. The compositor 437 // needs to know about clip parents in order to circumvent its normal 438 // clipping logic. 439 const RenderLayer* clipParent; 440 441 // The "is unclipped descendant" concept is now only being used for one 442 // purpose: when traversing the RenderLayers in stacking order, we check 443 // if we scroll wrt to these unclipped descendants. We do this to 444 // proactively promote in the same way that we do for animated layers. 445 // Since we have no idea where scrolled content will scroll to, we just 446 // assume that it can overlap the unclipped thing at some point, so we 447 // promote. But this is unfortunate. We should be able to inflate the 448 // bounds of scrolling content for overlap the same way we're doing for 449 // animation and only promote what's necessary. Once we're doing that, 450 // we won't need to use the "unclipped" concept for promotion any 451 // longer. 452 unsigned isUnclippedDescendant : 1; 453 unsigned hasAncestorWithClipPath : 1; 454 }; 455 456 class DescendantDependentCompositingInputs { 457 public: DescendantDependentCompositingInputs()458 DescendantDependentCompositingInputs() 459 : hasDescendantWithClipPath(false) 460 , hasDescendantWithBlendMode(false) 461 { } 462 463 unsigned hasDescendantWithClipPath : 1; 464 unsigned hasDescendantWithBlendMode : 1; 465 }; 466 467 void setNeedsCompositingInputsUpdate(); childNeedsCompositingInputsUpdate()468 bool childNeedsCompositingInputsUpdate() const { return m_childNeedsCompositingInputsUpdate; } needsCompositingInputsUpdate()469 bool needsCompositingInputsUpdate() const 470 { 471 // While we're updating the compositing inputs, these values may differ. 472 // We should never be asking for this value when that is the case. 473 ASSERT(m_needsDescendantDependentCompositingInputsUpdate == m_needsAncestorDependentCompositingInputsUpdate); 474 return m_needsDescendantDependentCompositingInputsUpdate; 475 } 476 477 void updateAncestorDependentCompositingInputs(const AncestorDependentCompositingInputs&); 478 void updateDescendantDependentCompositingInputs(const DescendantDependentCompositingInputs&); 479 void didUpdateCompositingInputs(); 480 ancestorDependentCompositingInputs()481 const AncestorDependentCompositingInputs& ancestorDependentCompositingInputs() const { ASSERT(!m_needsAncestorDependentCompositingInputsUpdate); return m_ancestorDependentCompositingInputs; } descendantDependentCompositingInputs()482 const DescendantDependentCompositingInputs& descendantDependentCompositingInputs() const { ASSERT(!m_needsDescendantDependentCompositingInputsUpdate); return m_descendantDependentCompositingInputs; } 483 clippedAbsoluteBoundingBox()484 IntRect clippedAbsoluteBoundingBox() const { return ancestorDependentCompositingInputs().clippedAbsoluteBoundingBox; } opacityAncestor()485 const RenderLayer* opacityAncestor() const { return ancestorDependentCompositingInputs().opacityAncestor; } transformAncestor()486 const RenderLayer* transformAncestor() const { return ancestorDependentCompositingInputs().transformAncestor; } filterAncestor()487 const RenderLayer* filterAncestor() const { return ancestorDependentCompositingInputs().filterAncestor; } clippingContainer()488 const RenderObject* clippingContainer() const { return ancestorDependentCompositingInputs().clippingContainer; } ancestorScrollingLayer()489 const RenderLayer* ancestorScrollingLayer() const { return ancestorDependentCompositingInputs().ancestorScrollingLayer; } scrollParent()490 RenderLayer* scrollParent() const { return const_cast<RenderLayer*>(ancestorDependentCompositingInputs().scrollParent); } clipParent()491 RenderLayer* clipParent() const { return const_cast<RenderLayer*>(ancestorDependentCompositingInputs().clipParent); } isUnclippedDescendant()492 bool isUnclippedDescendant() const { return ancestorDependentCompositingInputs().isUnclippedDescendant; } hasAncestorWithClipPath()493 bool hasAncestorWithClipPath() const { return ancestorDependentCompositingInputs().hasAncestorWithClipPath; } hasDescendantWithClipPath()494 bool hasDescendantWithClipPath() const { return descendantDependentCompositingInputs().hasDescendantWithClipPath; } hasDescendantWithBlendMode()495 bool hasDescendantWithBlendMode() const { return descendantDependentCompositingInputs().hasDescendantWithBlendMode; } 496 lostGroupedMapping()497 bool lostGroupedMapping() const { ASSERT(isAllowedToQueryCompositingState()); return m_lostGroupedMapping; } setLostGroupedMapping(bool b)498 void setLostGroupedMapping(bool b) { m_lostGroupedMapping = b; } 499 compositingReasons()500 CompositingReasons compositingReasons() const { ASSERT(isAllowedToQueryCompositingState()); return m_compositingReasons; } 501 void setCompositingReasons(CompositingReasons, CompositingReasons mask = CompositingReasonAll); 502 hasCompositingDescendant()503 bool hasCompositingDescendant() const { ASSERT(isAllowedToQueryCompositingState()); return m_hasCompositingDescendant; } 504 void setHasCompositingDescendant(bool); 505 shouldIsolateCompositedDescendants()506 bool shouldIsolateCompositedDescendants() const { ASSERT(isAllowedToQueryCompositingState()); return m_shouldIsolateCompositedDescendants; } 507 void setShouldIsolateCompositedDescendants(bool); 508 509 void updateDescendantDependentFlags(); 510 void updateDescendantDependentFlagsForEntireSubtree(); 511 512 void updateOrRemoveFilterEffectRenderer(); 513 514 void updateSelfPaintingLayer(); 515 516 // paintLayerContents() assumes that the caller will clip to the bounds of the painting dirty rect if necessary. 517 void paintLayerContents(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); 518 519 RenderLayer* enclosingTransformedAncestor() const; 520 LayoutPoint computeOffsetFromTransformedAncestor() const; 521 522 void didUpdateNeedsCompositedScrolling(); 523 524 void setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants(); 525 526 private: 527 // Bounding box in the coordinates of this layer. 528 LayoutRect logicalBoundingBox() const; 529 530 bool hasOverflowControls() const; 531 532 void setAncestorChainHasSelfPaintingLayerDescendant(); 533 void dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); 534 535 void clipToRect(const LayerPaintingInfo&, GraphicsContext*, const ClipRect&, PaintLayerFlags, BorderRadiusClippingRule = IncludeSelfForBorderRadius); 536 void restoreClip(GraphicsContext*, const LayoutRect& paintDirtyRect, const ClipRect&); 537 538 void updateLayerPositionRecursive(); 539 setNextSibling(RenderLayer * next)540 void setNextSibling(RenderLayer* next) { m_next = next; } setPreviousSibling(RenderLayer * prev)541 void setPreviousSibling(RenderLayer* prev) { m_previous = prev; } setFirstChild(RenderLayer * first)542 void setFirstChild(RenderLayer* first) { m_first = first; } setLastChild(RenderLayer * last)543 void setLastChild(RenderLayer* last) { m_last = last; } 544 545 void updateHasSelfPaintingLayerDescendant() const; 546 hasSelfPaintingLayerDescendant()547 bool hasSelfPaintingLayerDescendant() const 548 { 549 if (m_hasSelfPaintingLayerDescendantDirty) 550 updateHasSelfPaintingLayerDescendant(); 551 ASSERT(!m_hasSelfPaintingLayerDescendantDirty); 552 return m_hasSelfPaintingLayerDescendant; 553 } 554 renderBoxLocation()555 LayoutPoint renderBoxLocation() const { return renderer()->isBox() ? toRenderBox(renderer())->location() : LayoutPoint(); } 556 557 void paintLayerContentsAndReflection(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); 558 void paintLayerByApplyingTransform(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags, const LayoutPoint& translationOffset = LayoutPoint()); 559 560 // Returns whether this layer should be painted during sofware painting (i.e., not via calls from CompositedLayerMapping to draw into composited 561 // layers). 562 bool shouldPaintLayerInSoftwareMode(const LayerPaintingInfo&, PaintLayerFlags paintFlags); 563 564 void paintChildren(unsigned childrenToVisit, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); 565 void paintPaginatedChildLayer(RenderLayer* childLayer, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); 566 void paintChildLayerIntoColumns(RenderLayer* childLayer, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags, const Vector<RenderLayer*>& columnLayers, size_t columnIndex); 567 568 void collectFragments(LayerFragments&, const RenderLayer* rootLayer, const LayoutRect& dirtyRect, 569 ClipRectsCacheSlot, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize, 570 ShouldRespectOverflowClip = RespectOverflowClip, const LayoutPoint* offsetFromRoot = 0, 571 const LayoutSize& subPixelAccumulation = LayoutSize(), const LayoutRect* layerBoundingBox = 0); 572 void updatePaintingInfoForFragments(LayerFragments&, const LayerPaintingInfo&, PaintLayerFlags, bool shouldPaintContent, const LayoutPoint* offsetFromRoot); 573 void paintBackgroundForFragments(const LayerFragments&, GraphicsContext*, GraphicsContext* transparencyLayerContext, 574 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags); 575 void paintForegroundForFragments(const LayerFragments&, GraphicsContext*, GraphicsContext* transparencyLayerContext, 576 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer, 577 bool selectionOnly, PaintLayerFlags); 578 void paintForegroundForFragmentsWithPhase(PaintPhase, const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags); 579 void paintOutlineForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags); 580 void paintOverflowControlsForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); 581 void paintMaskForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, RenderObject* paintingRootForRenderer, PaintLayerFlags); 582 void paintChildClippingMaskForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, RenderObject* paintingRootForRenderer, PaintLayerFlags); 583 void paintTransformedLayerIntoFragments(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); 584 585 RenderLayer* hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result, 586 const LayoutRect& hitTestRect, const HitTestLocation&, bool appliedTransform, 587 const HitTestingTransformState* transformState = 0, double* zOffset = 0); 588 RenderLayer* hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&, 589 const LayoutRect& hitTestRect, const HitTestLocation&, const HitTestingTransformState* = 0, double* zOffset = 0, 590 const LayoutPoint& translationOffset = LayoutPoint()); 591 RenderLayer* hitTestChildren(ChildrenIteration, RenderLayer* rootLayer, const HitTestRequest&, HitTestResult&, 592 const LayoutRect& hitTestRect, const HitTestLocation&, 593 const HitTestingTransformState* transformState, double* zOffsetForDescendants, double* zOffset, 594 const HitTestingTransformState* unflattenedTransformState, bool depthSortDescendants); 595 RenderLayer* hitTestPaginatedChildLayer(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result, 596 const LayoutRect& hitTestRect, const HitTestLocation&, 597 const HitTestingTransformState* transformState, double* zOffset); 598 RenderLayer* hitTestChildLayerColumns(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result, 599 const LayoutRect& hitTestRect, const HitTestLocation&, 600 const HitTestingTransformState* transformState, double* zOffset, 601 const Vector<RenderLayer*>& columnLayers, size_t columnIndex); 602 603 PassRefPtr<HitTestingTransformState> createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer, 604 const LayoutRect& hitTestRect, const HitTestLocation&, 605 const HitTestingTransformState* containerTransformState, 606 const LayoutPoint& translationOffset = LayoutPoint()) const; 607 608 bool hitTestContents(const HitTestRequest&, HitTestResult&, const LayoutRect& layerBounds, const HitTestLocation&, HitTestFilter) const; 609 bool hitTestContentsForFragments(const LayerFragments&, const HitTestRequest&, HitTestResult&, const HitTestLocation&, HitTestFilter, bool& insideClipRect) const; 610 RenderLayer* hitTestTransformedLayerInFragments(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&, 611 const LayoutRect& hitTestRect, const HitTestLocation&, const HitTestingTransformState* = 0, double* zOffset = 0); 612 613 bool childBackgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const; 614 615 bool shouldBeSelfPaintingLayer() const; 616 617 // FIXME: We should only create the stacking node if needed. requiresStackingNode()618 bool requiresStackingNode() const { return true; } 619 void updateStackingNode(); 620 621 void updateReflectionInfo(const RenderStyle*); 622 623 // FIXME: We could lazily allocate our ScrollableArea based on style properties ('overflow', ...) 624 // but for now, we are always allocating it for RenderBox as it's safer. requiresScrollableArea()625 bool requiresScrollableArea() const { return renderBox(); } 626 void updateScrollableArea(); 627 628 void dirtyAncestorChainVisibleDescendantStatus(); 629 630 bool attemptDirectCompositingUpdate(StyleDifference, const RenderStyle* oldStyle); 631 void updateTransform(const RenderStyle* oldStyle, RenderStyle* newStyle); 632 633 void dirty3DTransformedDescendantStatus(); 634 // Both updates the status, and returns true if descendants of this have 3d. 635 bool update3DTransformedDescendantStatus(); 636 637 void updateOrRemoveFilterClients(); 638 639 LayoutRect paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior); 640 641 void updatePaginationRecursive(bool needsPaginationUpdate = false); 642 void updatePagination(); 643 644 // FIXME: Temporary. Remove when new columns come online. 645 bool useRegionBasedColumns() const; 646 647 LayerType m_layerType; 648 649 // Self-painting layer is an optimization where we avoid the heavy RenderLayer painting 650 // machinery for a RenderLayer allocated only to handle the overflow clip case. 651 // FIXME(crbug.com/332791): Self-painting layer should be merged into the overflow-only concept. 652 unsigned m_isSelfPaintingLayer : 1; 653 654 // If have no self-painting descendants, we don't have to walk our children during painting. This can lead to 655 // significant savings, especially if the tree has lots of non-self-painting layers grouped together (e.g. table cells). 656 mutable unsigned m_hasSelfPaintingLayerDescendant : 1; 657 mutable unsigned m_hasSelfPaintingLayerDescendantDirty : 1; 658 659 const unsigned m_isRootLayer : 1; 660 661 unsigned m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether 662 // we ended up painting this layer or any descendants (and therefore need to 663 // blend). 664 665 unsigned m_visibleContentStatusDirty : 1; 666 unsigned m_hasVisibleContent : 1; 667 unsigned m_visibleDescendantStatusDirty : 1; 668 unsigned m_hasVisibleDescendant : 1; 669 670 unsigned m_hasVisibleNonLayerContent : 1; 671 672 unsigned m_isPaginated : 1; // If we think this layer is split by a multi-column ancestor, then this bit will be set. 673 674 unsigned m_3DTransformedDescendantStatusDirty : 1; 675 // Set on a stacking context layer that has 3D descendants anywhere 676 // in a preserves3D hierarchy. Hint to do 3D-aware hit testing. 677 unsigned m_has3DTransformedDescendant : 1; 678 679 unsigned m_containsDirtyOverlayScrollbars : 1; 680 681 unsigned m_hasFilterInfo : 1; 682 unsigned m_needsAncestorDependentCompositingInputsUpdate : 1; 683 unsigned m_needsDescendantDependentCompositingInputsUpdate : 1; 684 unsigned m_childNeedsCompositingInputsUpdate : 1; 685 686 // Used only while determining what layers should be composited. Applies to the tree of z-order lists. 687 unsigned m_hasCompositingDescendant : 1; 688 689 // Applies to the real render layer tree (i.e., the tree determined by the layer's parent and children and 690 // as opposed to the tree formed by the z-order and normal flow lists). 691 unsigned m_hasNonCompositedChild : 1; 692 693 // Should be for stacking contexts having unisolated blending descendants. 694 unsigned m_shouldIsolateCompositedDescendants : 1; 695 696 // True if this render layer just lost its grouped mapping due to the CompositedLayerMapping being destroyed, 697 // and we don't yet know to what graphics layer this RenderLayer will be assigned. 698 unsigned m_lostGroupedMapping : 1; 699 700 RenderLayerModelObject* m_renderer; 701 702 RenderLayer* m_parent; 703 RenderLayer* m_previous; 704 RenderLayer* m_next; 705 RenderLayer* m_first; 706 RenderLayer* m_last; 707 708 // Cached normal flow values for absolute positioned elements with static left/top values. 709 LayoutUnit m_staticInlinePosition; 710 LayoutUnit m_staticBlockPosition; 711 712 OwnPtr<TransformationMatrix> m_transform; 713 714 // Pointer to the enclosing RenderLayer that caused us to be paginated. It is 0 if we are not paginated. 715 RenderLayer* m_enclosingPaginationLayer; 716 717 // These compositing reasons are updated whenever style changes, not while updating compositing layers. 718 // They should not be used to infer the compositing state of this layer. 719 CompositingReasons m_potentialCompositingReasonsFromStyle; 720 721 // Once computed, indicates all that a layer needs to become composited using the CompositingReasons enum bitfield. 722 CompositingReasons m_compositingReasons; 723 724 DescendantDependentCompositingInputs m_descendantDependentCompositingInputs; 725 AncestorDependentCompositingInputs m_ancestorDependentCompositingInputs; 726 727 IntRect m_blockSelectionGapsBounds; 728 729 OwnPtr<CompositedLayerMapping> m_compositedLayerMapping; 730 OwnPtr<RenderLayerScrollableArea> m_scrollableArea; 731 732 CompositedLayerMapping* m_groupedMapping; 733 734 RenderLayerClipper m_clipper; // FIXME: Lazily allocate? 735 OwnPtr<RenderLayerStackingNode> m_stackingNode; 736 OwnPtrWillBePersistent<RenderLayerReflectionInfo> m_reflectionInfo; 737 738 LayoutSize m_subpixelAccumulation; // The accumulated subpixel offset of a composited layer's composited bounds compared to absolute coordinates. 739 }; 740 741 } // namespace blink 742 743 #ifndef NDEBUG 744 // Outside the WebCore namespace for ease of invocation from gdb. 745 void showLayerTree(const blink::RenderLayer*); 746 void showLayerTree(const blink::RenderObject*); 747 #endif 748 749 #endif // RenderLayer_h 750