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