1/* 2 * Copyright (C) 2003, 2009, 2012 Apple Inc. All rights reserved. 3 * 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 5 * 6 * Other contributors: 7 * Robert O'Callahan <roc+@cs.cmu.edu> 8 * David Baron <dbaron@fas.harvard.edu> 9 * Christian Biesinger <cbiesinger@web.de> 10 * Randall Jesup <rjesup@wgate.com> 11 * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de> 12 * Josh Soref <timeless@mac.com> 13 * Boris Zbarsky <bzbarsky@mit.edu> 14 * 15 * This library is free software; you can redistribute it and/or 16 * modify it under the terms of the GNU Lesser General Public 17 * License as published by the Free Software Foundation; either 18 * version 2.1 of the License, or (at your option) any later version. 19 * 20 * This library is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 * Lesser General Public License for more details. 24 * 25 * You should have received a copy of the GNU Lesser General Public 26 * License along with this library; if not, write to the Free Software 27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 28 * 29 * Alternatively, the contents of this file may be used under the terms 30 * of either the Mozilla Public License Version 1.1, found at 31 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public 32 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html 33 * (the "GPL"), in which case the provisions of the MPL or the GPL are 34 * applicable instead of those above. If you wish to allow use of your 35 * version of this file only under the terms of one of those two 36 * licenses (the MPL or the GPL) and not to allow others to use your 37 * version of this file under the LGPL, indicate your decision by 38 * deletingthe provisions above and replace them with the notice and 39 * other provisions required by the MPL or the GPL, as the case may be. 40 * If you do not delete the provisions above, a recipient may use your 41 * version of this file under any of the LGPL, the MPL or the GPL. 42 */ 43 44#ifndef RenderLayer_h 45#define RenderLayer_h 46 47#include "GraphicsLayer.h" 48#include "PaintInfo.h" 49#include "RenderBox.h" 50#include "RenderPtr.h" 51#include "ScrollableArea.h" 52#include <memory> 53 54namespace WebCore { 55 56class FilterEffectRenderer; 57class FilterEffectRendererHelper; 58class FilterOperations; 59class HitTestRequest; 60class HitTestResult; 61class HitTestingTransformState; 62class RenderFlowThread; 63class RenderGeometryMap; 64class RenderLayerBacking; 65class RenderLayerCompositor; 66class RenderMarquee; 67class RenderNamedFlowFragment; 68class RenderReplica; 69class RenderScrollbarPart; 70class RenderStyle; 71class RenderView; 72class Scrollbar; 73class TransformationMatrix; 74 75enum BorderRadiusClippingRule { IncludeSelfForBorderRadius, DoNotIncludeSelfForBorderRadius }; 76enum IncludeSelfOrNot { IncludeSelf, ExcludeSelf }; 77 78enum RepaintStatus { 79 NeedsNormalRepaint, 80 NeedsFullRepaint, 81 NeedsFullRepaintForPositionedMovementLayout 82}; 83 84class ClipRect { 85public: 86 ClipRect() 87 : m_hasRadius(false) 88 { } 89 90 ClipRect(const LayoutRect& rect) 91 : m_rect(rect) 92 , m_hasRadius(false) 93 { } 94 95 const LayoutRect& rect() const { return m_rect; } 96 void setRect(const LayoutRect& rect) { m_rect = rect; } 97 98 bool hasRadius() const { return m_hasRadius; } 99 void setHasRadius(bool hasRadius) { m_hasRadius = hasRadius; } 100 101 bool operator==(const ClipRect& other) const { return rect() == other.rect() && hasRadius() == other.hasRadius(); } 102 bool operator!=(const ClipRect& other) const { return rect() != other.rect() || hasRadius() != other.hasRadius(); } 103 bool operator!=(const LayoutRect& otherRect) const { return rect() != otherRect; } 104 105 void intersect(const LayoutRect& other) { m_rect.intersect(other); } 106 void intersect(const ClipRect& other) 107 { 108 m_rect.intersect(other.rect()); 109 if (other.hasRadius()) 110 m_hasRadius = true; 111 } 112 void move(LayoutUnit x, LayoutUnit y) { m_rect.move(x, y); } 113 void move(const LayoutSize& size) { m_rect.move(size); } 114 void moveBy(const LayoutPoint& point) { m_rect.moveBy(point); } 115 116 bool isEmpty() const { return m_rect.isEmpty(); } 117 bool intersects(const LayoutRect& rect) const { return m_rect.intersects(rect); } 118 bool intersects(const HitTestLocation&) const; 119 120 void inflateX(LayoutUnit dx) { m_rect.inflateX(dx); } 121 void inflateY(LayoutUnit dy) { m_rect.inflateY(dy); } 122 void inflate(LayoutUnit d) { inflateX(d); inflateY(d); } 123 124private: 125 LayoutRect m_rect; 126 bool m_hasRadius; 127}; 128 129inline ClipRect intersection(const ClipRect& a, const ClipRect& b) 130{ 131 ClipRect c = a; 132 c.intersect(b); 133 return c; 134} 135 136class ClipRects { 137 WTF_MAKE_FAST_ALLOCATED; 138public: 139 static PassRefPtr<ClipRects> create() 140 { 141 return adoptRef(new ClipRects); 142 } 143 144 static PassRefPtr<ClipRects> create(const ClipRects& other) 145 { 146 return adoptRef(new ClipRects(other)); 147 } 148 149 ClipRects() 150 : m_refCnt(1) 151 , m_fixed(false) 152 { 153 } 154 155 void reset(const LayoutRect& r) 156 { 157 m_overflowClipRect = r; 158 m_fixedClipRect = r; 159 m_posClipRect = r; 160 m_fixed = false; 161 } 162 163 const ClipRect& overflowClipRect() const { return m_overflowClipRect; } 164 void setOverflowClipRect(const ClipRect& r) { m_overflowClipRect = r; } 165 166 const ClipRect& fixedClipRect() const { return m_fixedClipRect; } 167 void setFixedClipRect(const ClipRect&r) { m_fixedClipRect = r; } 168 169 const ClipRect& posClipRect() const { return m_posClipRect; } 170 void setPosClipRect(const ClipRect& r) { m_posClipRect = r; } 171 172 bool fixed() const { return m_fixed; } 173 void setFixed(bool fixed) { m_fixed = fixed; } 174 175 void ref() { m_refCnt++; } 176 void deref() 177 { 178 if (!--m_refCnt) 179 delete this; 180 } 181 182 bool operator==(const ClipRects& other) const 183 { 184 return m_overflowClipRect == other.overflowClipRect() && 185 m_fixedClipRect == other.fixedClipRect() && 186 m_posClipRect == other.posClipRect() && 187 m_fixed == other.fixed(); 188 } 189 190 ClipRects& operator=(const ClipRects& other) 191 { 192 m_overflowClipRect = other.overflowClipRect(); 193 m_fixedClipRect = other.fixedClipRect(); 194 m_posClipRect = other.posClipRect(); 195 m_fixed = other.fixed(); 196 return *this; 197 } 198 199private: 200 ClipRects(const LayoutRect& r) 201 : m_overflowClipRect(r) 202 , m_fixedClipRect(r) 203 , m_posClipRect(r) 204 , m_refCnt(1) 205 , m_fixed(false) 206 { 207 } 208 209 ClipRects(const ClipRects& other) 210 : m_overflowClipRect(other.overflowClipRect()) 211 , m_fixedClipRect(other.fixedClipRect()) 212 , m_posClipRect(other.posClipRect()) 213 , m_refCnt(1) 214 , m_fixed(other.fixed()) 215 { 216 } 217 218 ClipRect m_overflowClipRect; 219 ClipRect m_fixedClipRect; 220 ClipRect m_posClipRect; 221 unsigned m_refCnt : 31; 222 bool m_fixed : 1; 223}; 224 225enum ClipRectsType { 226 PaintingClipRects, // Relative to painting ancestor. Used for painting. 227 RootRelativeClipRects, // Relative to the ancestor treated as the root (e.g. transformed layer). Used for hit testing. 228 AbsoluteClipRects, // Relative to the RenderView's layer. Used for compositing overlap testing. 229 NumCachedClipRectsTypes, 230 AllClipRectTypes, 231 TemporaryClipRects 232}; 233 234enum ShouldRespectOverflowClip { 235 IgnoreOverflowClip, 236 RespectOverflowClip 237}; 238 239enum ShouldApplyRootOffsetToFragments { 240 ApplyRootOffsetToFragments, 241 IgnoreRootOffsetForFragments 242}; 243 244struct ClipRectsCache { 245 WTF_MAKE_FAST_ALLOCATED; 246public: 247 ClipRectsCache() 248 { 249#ifndef NDEBUG 250 for (int i = 0; i < NumCachedClipRectsTypes; ++i) { 251 m_clipRectsRoot[i] = 0; 252 m_scrollbarRelevancy[i] = IgnoreOverlayScrollbarSize; 253 } 254#endif 255 } 256 257 PassRefPtr<ClipRects> getClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow) { return m_clipRects[getIndex(clipRectsType, respectOverflow)]; } 258 void setClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow, PassRefPtr<ClipRects> clipRects) { m_clipRects[getIndex(clipRectsType, respectOverflow)] = clipRects; } 259 260#ifndef NDEBUG 261 const RenderLayer* m_clipRectsRoot[NumCachedClipRectsTypes]; 262 OverlayScrollbarSizeRelevancy m_scrollbarRelevancy[NumCachedClipRectsTypes]; 263#endif 264 265private: 266 int getIndex(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow) 267 { 268 int index = static_cast<int>(clipRectsType); 269 if (respectOverflow == RespectOverflowClip) 270 index += static_cast<int>(NumCachedClipRectsTypes); 271 return index; 272 } 273 274 RefPtr<ClipRects> m_clipRects[NumCachedClipRectsTypes * 2]; 275}; 276 277struct LayerFragment { 278public: 279 LayerFragment() 280 : shouldPaintContent(false) 281 , hasBoundingBox(false) 282 { } 283 284 void setRects(const LayoutRect& bounds, const ClipRect& background, const ClipRect& foreground, const ClipRect& outline, const LayoutRect* bbox) 285 { 286 layerBounds = bounds; 287 backgroundRect = background; 288 foregroundRect = foreground; 289 outlineRect = outline; 290 if (bbox) { 291 boundingBox = *bbox; 292 hasBoundingBox = true; 293 } 294 } 295 296 void moveBy(const LayoutPoint& offset) 297 { 298 layerBounds.moveBy(offset); 299 backgroundRect.moveBy(offset); 300 foregroundRect.moveBy(offset); 301 outlineRect.moveBy(offset); 302 paginationClip.moveBy(offset); 303 boundingBox.moveBy(offset); 304 } 305 306 void intersect(const LayoutRect& rect) 307 { 308 backgroundRect.intersect(rect); 309 foregroundRect.intersect(rect); 310 outlineRect.intersect(rect); 311 boundingBox.intersect(rect); 312 } 313 314 bool shouldPaintContent; 315 bool hasBoundingBox; 316 LayoutRect layerBounds; 317 ClipRect backgroundRect; 318 ClipRect foregroundRect; 319 ClipRect outlineRect; 320 LayoutRect boundingBox; 321 322 // Unique to paginated fragments. The physical translation to apply to shift the layer when painting/hit-testing. 323 LayoutSize paginationOffset; 324 325 // Also unique to paginated fragments. An additional clip that applies to the layer. It is in layer-local 326 // (physical) coordinates. 327 LayoutRect paginationClip; 328}; 329 330typedef Vector<LayerFragment, 1> LayerFragments; 331 332class RenderLayer final : public ScrollableArea { 333 WTF_MAKE_FAST_ALLOCATED; 334public: 335 friend class RenderReplica; 336 337 explicit RenderLayer(RenderLayerModelObject&); 338 virtual ~RenderLayer(); 339 340#if PLATFORM(IOS) 341 // Called before the renderer's widget (if any) has been nulled out. 342 void willBeDestroyed(); 343#endif 344 String name() const; 345 346 RenderLayerModelObject& renderer() const { return m_renderer; } 347 RenderBox* renderBox() const { return renderer().isBox() ? &toRenderBox(renderer()) : nullptr; } 348 RenderLayer* parent() const { return m_parent; } 349 RenderLayer* previousSibling() const { return m_previous; } 350 RenderLayer* nextSibling() const { return m_next; } 351 RenderLayer* firstChild() const { return m_first; } 352 RenderLayer* lastChild() const { return m_last; } 353 354 void addChild(RenderLayer* newChild, RenderLayer* beforeChild = nullptr); 355 RenderLayer* removeChild(RenderLayer*); 356 357 void removeOnlyThisLayer(); 358 void insertOnlyThisLayer(); 359 360 void repaintIncludingDescendants(); 361 362 // Indicate that the layer contents need to be repainted. Only has an effect 363 // if layer compositing is being used. 364 void setBackingNeedsRepaint(GraphicsLayer::ShouldClipToLayer = GraphicsLayer::ClipToLayer); 365 366 // The rect is in the coordinate space of the layer's render object. 367 void setBackingNeedsRepaintInRect(const LayoutRect&, GraphicsLayer::ShouldClipToLayer = GraphicsLayer::ClipToLayer); 368 void repaintIncludingNonCompositingDescendants(RenderLayerModelObject* repaintContainer); 369 370 void styleChanged(StyleDifference, const RenderStyle* oldStyle); 371 372 RenderMarquee* marquee() const { return m_marquee.get(); } 373 374 bool isNormalFlowOnly() const { return m_isNormalFlowOnly; } 375 bool isSelfPaintingLayer() const { return m_isSelfPaintingLayer; } 376 377 bool cannotBlitToWindow() const; 378 379 bool isTransparent() const { return renderer().isTransparent() || renderer().hasMask(); } 380 381 bool hasReflection() const { return renderer().hasReflection(); } 382 bool isReflection() const { return renderer().isReplica(); } 383 RenderReplica* reflection() const { return m_reflection.get(); } 384 RenderLayer* reflectionLayer() const; 385 386 const RenderLayer* root() const 387 { 388 const RenderLayer* curr = this; 389 while (curr->parent()) 390 curr = curr->parent(); 391 return curr; 392 } 393 394 const LayoutPoint& location() const { return m_topLeft; } 395 void setLocation(const LayoutPoint& p) { m_topLeft = p; } 396 397 const IntSize& size() const { return m_layerSize; } 398 void setSize(const IntSize& size) { m_layerSize = size; } 399 400 LayoutRect rect() const { return LayoutRect(location(), size()); } 401 402 int scrollWidth() const; 403 int scrollHeight() const; 404 405 void panScrollFromPoint(const IntPoint&); 406 407 enum ScrollOffsetClamping { 408 ScrollOffsetUnclamped, 409 ScrollOffsetClamped 410 }; 411 412 // Scrolling methods for layers that can scroll their overflow. 413 void scrollByRecursively(const IntSize&, ScrollOffsetClamping = ScrollOffsetUnclamped, ScrollableArea** scrolledArea = nullptr); 414 void scrollToOffset(const IntSize&, ScrollOffsetClamping = ScrollOffsetUnclamped); 415 void scrollToXOffset(int x, ScrollOffsetClamping clamp = ScrollOffsetUnclamped) { scrollToOffset(IntSize(x, scrollYOffset()), clamp); } 416 void scrollToYOffset(int y, ScrollOffsetClamping clamp = ScrollOffsetUnclamped) { scrollToOffset(IntSize(scrollXOffset(), y), clamp); } 417 418 int scrollXOffset() const { return m_scrollOffset.width() + scrollOrigin().x(); } 419 int scrollYOffset() const { return m_scrollOffset.height() + scrollOrigin().y(); } 420 IntSize scrollOffset() const { return IntSize(scrollXOffset(), scrollYOffset()); } 421 IntSize scrollableContentsSize() const; 422 423 void scrollRectToVisible(const LayoutRect&, const ScrollAlignment& alignX, const ScrollAlignment& alignY); 424 425 LayoutRect getRectToExpose(const LayoutRect& visibleRect, const LayoutRect& visibleRectRelativeToDocument, const LayoutRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY); 426 427 bool scrollsOverflow() const; 428 bool hasScrollbars() const { return m_hBar || m_vBar; } 429 void setHasHorizontalScrollbar(bool); 430 void setHasVerticalScrollbar(bool); 431 432 PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation); 433 void destroyScrollbar(ScrollbarOrientation); 434 435 bool hasHorizontalScrollbar() const { return horizontalScrollbar(); } 436 bool hasVerticalScrollbar() const { return verticalScrollbar(); } 437 438 // ScrollableArea overrides 439 virtual Scrollbar* horizontalScrollbar() const override { return m_hBar.get(); } 440 virtual Scrollbar* verticalScrollbar() const override { return m_vBar.get(); } 441 virtual ScrollableArea* enclosingScrollableArea() const override; 442 443#if PLATFORM(IOS) 444#if ENABLE(TOUCH_EVENTS) 445 virtual bool handleTouchEvent(const PlatformTouchEvent&) override; 446 virtual bool isTouchScrollable() const override { return true; } 447#endif 448 virtual bool isOverflowScroll() const override { return true; } 449 450 virtual void didStartScroll() override; 451 virtual void didEndScroll() override; 452 virtual void didUpdateScroll() override; 453 virtual void setIsUserScroll(bool isUserScroll) override { m_inUserScroll = isUserScroll; } 454 455 bool isInUserScroll() const { return m_inUserScroll; } 456 457 bool requiresScrollBoundsOriginUpdate() const { return m_requiresScrollBoundsOriginUpdate; } 458 void setRequiresScrollBoundsOriginUpdate(bool requiresUpdate = true) { m_requiresScrollBoundsOriginUpdate = requiresUpdate; } 459 460 // Returns true when the layer could do touch scrolling, but doesn't look at whether there is actually scrollable overflow. 461 bool hasAcceleratedTouchScrolling() const; 462 // Returns true when there is actually scrollable overflow (requires layout to be up-to-date). 463 bool hasTouchScrollableOverflow() const; 464#endif 465 466 int verticalScrollbarWidth(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const; 467 int horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const; 468 469 bool hasOverflowControls() const; 470 bool isPointInResizeControl(const IntPoint& absolutePoint) const; 471 bool hitTestOverflowControls(HitTestResult&, const IntPoint& localPoint); 472 IntSize offsetFromResizeCorner(const IntPoint& absolutePoint) const; 473 474 void paintOverflowControls(GraphicsContext*, const IntPoint&, const IntRect& damageRect, bool paintingOverlayControls = false); 475 void paintScrollCorner(GraphicsContext*, const IntPoint&, const IntRect& damageRect); 476 void paintResizer(GraphicsContext*, const LayoutPoint&, const LayoutRect& damageRect); 477 478 void updateScrollInfoAfterLayout(); 479 480 bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1); 481 void autoscroll(const IntPoint&); 482 483 bool canResize() const; 484 void resize(const PlatformMouseEvent&, const LayoutSize&); 485 bool inResizeMode() const { return m_inResizeMode; } 486 void setInResizeMode(bool b) { m_inResizeMode = b; } 487 488 bool isRootLayer() const { return m_isRootLayer; } 489 490 RenderLayerCompositor& compositor() const; 491 492 // Notification from the renderer that its content changed (e.g. current frame of image changed). 493 // Allows updates of layer content without repainting. 494 void contentChanged(ContentChangeType); 495 496 bool canRender3DTransforms() const; 497 498 enum UpdateLayerPositionsFlag { 499 CheckForRepaint = 1 << 0, 500 NeedsFullRepaintInBacking = 1 << 1, 501 IsCompositingUpdateRoot = 1 << 2, 502 UpdateCompositingLayers = 1 << 3, 503 UpdatePagination = 1 << 4, 504 SeenTransformedLayer = 1 << 5, 505 Seen3DTransformedLayer = 1 << 6 506 }; 507 typedef unsigned UpdateLayerPositionsFlags; 508 static const UpdateLayerPositionsFlags defaultFlags = CheckForRepaint | IsCompositingUpdateRoot | UpdateCompositingLayers; 509 510 void updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, UpdateLayerPositionsFlags); 511 512 void updateLayerPositionsAfterOverflowScroll(); 513 void updateLayerPositionsAfterDocumentScroll(); 514 515 void positionNewlyCreatedOverflowControls(); 516 517 bool hasCompositedLayerInEnclosingPaginationChain() const; 518 enum PaginationInclusionMode { ExcludeCompositedPaginatedLayers, IncludeCompositedPaginatedLayers }; 519 RenderLayer* enclosingPaginationLayer(PaginationInclusionMode mode) const 520 { 521 if (mode == ExcludeCompositedPaginatedLayers && hasCompositedLayerInEnclosingPaginationChain()) 522 return nullptr; 523 return m_enclosingPaginationLayer; 524 } 525 526 void updateTransform(); 527 528#if ENABLE(CSS_COMPOSITING) 529 void updateBlendMode(); 530#endif 531 532 const LayoutSize& offsetForInFlowPosition() const { return m_offsetForInFlowPosition; } 533 534 void clearClipRectsIncludingDescendants(ClipRectsType typeToClear = AllClipRectTypes); 535 void clearClipRects(ClipRectsType typeToClear = AllClipRectTypes); 536 537 void addBlockSelectionGapsBounds(const LayoutRect&); 538 void clearBlockSelectionGapsBounds(); 539 void repaintBlockSelectionGaps(); 540 541 // A stacking context is a layer that has a non-auto z-index. 542 bool isStackingContext() const { return isStackingContext(&renderer().style()); } 543 544 // A stacking container can have z-order lists. All stacking contexts are 545 // stacking containers, but the converse is not true. Layers that use 546 // composited scrolling are stacking containers, but they may not 547 // necessarily be stacking contexts. 548 bool isStackingContainer() const { return isStackingContext() || needsCompositedScrolling(); } 549 550 // Gets the enclosing stacking container for this layer, excluding this 551 // layer itself. 552 RenderLayer* stackingContainer() const; 553 554 // Gets the enclosing stacking container for this layer, possibly the layer 555 // itself, if it is a stacking container. 556 RenderLayer* enclosingStackingContainer() { return isStackingContainer() ? this : stackingContainer(); } 557 558 void dirtyZOrderLists(); 559 void dirtyStackingContainerZOrderLists(); 560 561 Vector<RenderLayer*>* posZOrderList() const 562 { 563 ASSERT(!m_zOrderListsDirty); 564 ASSERT(isStackingContainer() || !m_posZOrderList); 565 return m_posZOrderList.get(); 566 } 567 568 bool hasNegativeZOrderList() const { return negZOrderList() && negZOrderList()->size(); } 569 570 Vector<RenderLayer*>* negZOrderList() const 571 { 572 ASSERT(!m_zOrderListsDirty); 573 ASSERT(isStackingContainer() || !m_negZOrderList); 574 return m_negZOrderList.get(); 575 } 576 577 void dirtyNormalFlowList(); 578 Vector<RenderLayer*>* normalFlowList() const { ASSERT(!m_normalFlowListDirty); return m_normalFlowList.get(); } 579 580 // Update our normal and z-index lists. 581 void updateLayerListsIfNeeded(); 582 583 // Update the normal and z-index lists of our descendants. 584 void updateDescendantsLayerListsIfNeeded(bool recursive); 585 586 // FIXME: We should ASSERT(!m_visibleContentStatusDirty) here, but see https://bugs.webkit.org/show_bug.cgi?id=71044 587 // ditto for hasVisibleDescendant(), see https://bugs.webkit.org/show_bug.cgi?id=71277 588 bool hasVisibleContent() const { return m_hasVisibleContent; } 589 bool hasVisibleDescendant() const { return m_hasVisibleDescendant; } 590 591 void setHasVisibleContent(); 592 void dirtyVisibleContentStatus(); 593 594 bool hasBoxDecorationsOrBackground() const; 595 bool hasVisibleBoxDecorations() const; 596 // Returns true if this layer has visible content (ignoring any child layers). 597 bool isVisuallyNonEmpty() const; 598 // True if this layer container renderers that paint. 599 bool hasNonEmptyChildRenderers() const; 600 601 // FIXME: We should ASSERT(!m_hasSelfPaintingLayerDescendantDirty); here but we hit the same bugs as visible content above. 602 // Part of the issue is with subtree relayout: we don't check if our ancestors have some descendant flags dirty, missing some updates. 603 bool hasSelfPaintingLayerDescendant() const { return m_hasSelfPaintingLayerDescendant; } 604 605 // This returns true if we have an out of flow positioned descendant whose 606 // containing block is not a descendant of ours. If this is true, we cannot 607 // automatically opt into composited scrolling since this out of flow 608 // positioned descendant would become clipped by us, possibly altering the 609 // rendering of the page. 610 // FIXME: We should ASSERT(!m_hasOutOfFlowPositionedDescendantDirty); here but we may hit the same bugs as visible content above. 611 bool hasOutOfFlowPositionedDescendant() const { return m_hasOutOfFlowPositionedDescendant; } 612 613 // Gets the nearest enclosing positioned ancestor layer (also includes 614 // the <html> layer and the root layer). 615 RenderLayer* enclosingPositionedAncestor() const; 616 617 // Returns the nearest enclosing layer that is scrollable. 618 RenderLayer* enclosingScrollableLayer() const; 619 620 // The layer relative to which clipping rects for this layer are computed. 621 RenderLayer* clippingRootForPainting() const; 622 623 RenderLayer* enclosingOverflowClipLayer(IncludeSelfOrNot) const; 624 625 // Enclosing compositing layer; if includeSelf is true, may return this. 626 RenderLayer* enclosingCompositingLayer(IncludeSelfOrNot = IncludeSelf) const; 627 RenderLayer* enclosingCompositingLayerForRepaint(IncludeSelfOrNot = IncludeSelf) const; 628 // Ancestor compositing layer, excluding this. 629 RenderLayer* ancestorCompositingLayer() const { return enclosingCompositingLayer(ExcludeSelf); } 630 631#if ENABLE(CSS_FILTERS) 632 RenderLayer* enclosingFilterLayer(IncludeSelfOrNot = IncludeSelf) const; 633 RenderLayer* enclosingFilterRepaintLayer() const; 634 void setFilterBackendNeedsRepaintingInRect(const LayoutRect&); 635 bool hasAncestorWithFilterOutsets() const; 636#endif 637 638 bool canUseConvertToLayerCoords() const 639 { 640 // These RenderObject have an impact on their layers' without them knowing about it. 641 return !renderer().hasTransform() && !renderer().isSVGRoot(); 642 } 643 644 // FIXME: adjustForColumns allows us to position compositing layers in columns correctly, but eventually they need to be split across columns too. 645 enum ColumnOffsetAdjustment { DontAdjustForColumns, AdjustForColumns }; 646 void convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& location, ColumnOffsetAdjustment adjustForColumns = DontAdjustForColumns) const; 647 LayoutPoint convertToLayerCoords(const RenderLayer* ancestorLayer, const LayoutPoint&, ColumnOffsetAdjustment adjustForColumns = DontAdjustForColumns) const; 648 LayoutSize offsetFromAncestor(const RenderLayer*) const; 649 650 int zIndex() const { return renderer().style().zIndex(); } 651 652 enum PaintLayerFlag { 653 PaintLayerHaveTransparency = 1, 654 PaintLayerAppliedTransform = 1 << 1, 655 PaintLayerTemporaryClipRects = 1 << 2, 656 PaintLayerPaintingReflection = 1 << 3, 657 PaintLayerPaintingOverlayScrollbars = 1 << 4, 658 PaintLayerPaintingCompositingBackgroundPhase = 1 << 5, 659 PaintLayerPaintingCompositingForegroundPhase = 1 << 6, 660 PaintLayerPaintingCompositingMaskPhase = 1 << 7, 661 PaintLayerPaintingCompositingScrollingPhase = 1 << 8, 662 PaintLayerPaintingOverflowContents = 1 << 9, 663 PaintLayerPaintingRootBackgroundOnly = 1 << 10, 664 PaintLayerPaintingSkipRootBackground = 1 << 11, 665 PaintLayerPaintingCompositingAllPhases = (PaintLayerPaintingCompositingBackgroundPhase | PaintLayerPaintingCompositingForegroundPhase | PaintLayerPaintingCompositingMaskPhase) 666 }; 667 668 typedef unsigned PaintLayerFlags; 669 670 // The two main functions that use the layer system. The paint method 671 // paints the layers that intersect the damage rect from back to 672 // front. The hitTest method looks for mouse events by walking 673 // layers that intersect the point from front to back. 674 void paint(GraphicsContext*, const LayoutRect& damageRect, PaintBehavior = PaintBehaviorNormal, RenderObject* subtreePaintRoot = nullptr, PaintLayerFlags = 0); 675 bool hitTest(const HitTestRequest&, HitTestResult&); 676 bool hitTest(const HitTestRequest&, const HitTestLocation&, HitTestResult&); 677 void paintOverlayScrollbars(GraphicsContext*, const LayoutRect& damageRect, PaintBehavior, RenderObject* subtreePaintRoot = nullptr); 678 679 void paintNamedFlowThreadInsideRegion(GraphicsContext*, RenderNamedFlowFragment*, LayoutRect, LayoutPoint, PaintBehavior = PaintBehaviorNormal, PaintLayerFlags = 0); 680 681 struct ClipRectsContext { 682 ClipRectsContext(const RenderLayer* inRootLayer, ClipRectsType inClipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize, ShouldRespectOverflowClip inRespectOverflowClip = RespectOverflowClip) 683 : rootLayer(inRootLayer) 684 , clipRectsType(inClipRectsType) 685 , overlayScrollbarSizeRelevancy(inOverlayScrollbarSizeRelevancy) 686 , respectOverflowClip(inRespectOverflowClip) 687 { } 688 const RenderLayer* rootLayer; 689 ClipRectsType clipRectsType; 690 OverlayScrollbarSizeRelevancy overlayScrollbarSizeRelevancy; 691 ShouldRespectOverflowClip respectOverflowClip; 692 }; 693 694 // This method figures out our layerBounds in coordinates relative to 695 // |rootLayer}. It also computes our background and foreground clip rects 696 // for painting/event handling. 697 // Pass offsetFromRoot if known. 698 void calculateRects(const ClipRectsContext&, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds, 699 ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutSize& offsetFromRoot) const; 700 701 // Compute and cache clip rects computed with the given layer as the root 702 void updateClipRects(const ClipRectsContext&); 703 // Compute and return the clip rects. If useCached is true, will used previously computed clip rects on ancestors 704 // (rather than computing them all from scratch up the parent chain). 705 void calculateClipRects(const ClipRectsContext&, ClipRects&) const; 706 707 ClipRects* clipRects(const ClipRectsContext& context) const 708 { 709 ASSERT(context.clipRectsType < NumCachedClipRectsTypes); 710 return m_clipRectsCache ? m_clipRectsCache->getClipRects(context.clipRectsType, context.respectOverflowClip).get() : 0; 711 } 712 713 LayoutRect childrenClipRect() const; // Returns the foreground clip rect of the layer in the document's coordinate space. 714 LayoutRect selfClipRect() const; // Returns the background clip rect of the layer in the document's coordinate space. 715 LayoutRect localClipRect(bool& clipExceedsBounds) const; // Returns the background clip rect of the layer in the local coordinate space. 716 717 // Pass offsetFromRoot if known. 718 bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutSize& offsetFromRoot, const LayoutRect* cachedBoundingBox = nullptr) const; 719 720 enum CalculateLayerBoundsFlag { 721 IncludeSelfTransform = 1 << 0, 722 UseLocalClipRectIfPossible = 1 << 1, 723 IncludeLayerFilterOutsets = 1 << 2, 724 ExcludeHiddenDescendants = 1 << 3, 725 DontConstrainForMask = 1 << 4, 726 IncludeCompositedDescendants = 1 << 5, 727 UseFragmentBoxesExcludingCompositing = 1 << 6, 728 UseFragmentBoxesIncludingCompositing = 1 << 7, 729 DefaultCalculateLayerBoundsFlags = IncludeSelfTransform | UseLocalClipRectIfPossible | IncludeLayerFilterOutsets | UseFragmentBoxesExcludingCompositing 730 }; 731 typedef unsigned CalculateLayerBoundsFlags; 732 733 // Bounding box relative to some ancestor layer. Pass offsetFromRoot if known. 734 LayoutRect boundingBox(const RenderLayer* rootLayer, const LayoutSize& offsetFromRoot = LayoutSize(), CalculateLayerBoundsFlags = 0) const; 735 // Bounding box in the coordinates of this layer. 736 LayoutRect localBoundingBox(CalculateLayerBoundsFlags = 0) const; 737 // Deprecated: Pixel snapped bounding box relative to the root. 738 IntRect absoluteBoundingBox() const; 739 // Device pixel snapped bounding box relative to the root. absoluteBoundingBox() callers will be directed to this. 740 FloatRect absoluteBoundingBoxForPainting() const; 741 742 // Bounds used for layer overlap testing in RenderLayerCompositor. 743 LayoutRect overlapBounds() const { return overlapBoundsIncludeChildren() ? calculateLayerBounds(this, LayoutSize()) : localBoundingBox(); } 744 745#if ENABLE(CSS_FILTERS) 746 // If true, this layer's children are included in its bounds for overlap testing. 747 // We can't rely on the children's positions if this layer has a filter that could have moved the children's pixels around. 748 bool overlapBoundsIncludeChildren() const { return hasFilter() && renderer().style().filter().hasFilterThatMovesPixels(); } 749#else 750 bool overlapBoundsIncludeChildren() const { return false; } 751#endif 752 753 // Can pass offsetFromRoot if known. 754 LayoutRect calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutSize& offsetFromRoot, CalculateLayerBoundsFlags = DefaultCalculateLayerBoundsFlags) const; 755 756 // Return a cached repaint rect, computed relative to the layer renderer's containerForRepaint. 757 LayoutRect repaintRect() const { return m_repaintRect; } 758 LayoutRect repaintRectIncludingNonCompositingDescendants() const; 759 760 void setRepaintStatus(RepaintStatus status) { m_repaintStatus = status; } 761 762 LayoutUnit staticInlinePosition() const { return m_staticInlinePosition; } 763 LayoutUnit staticBlockPosition() const { return m_staticBlockPosition; } 764 765 void setStaticInlinePosition(LayoutUnit position) { m_staticInlinePosition = position; } 766 void setStaticBlockPosition(LayoutUnit position) { m_staticBlockPosition = position; } 767 768#if PLATFORM(IOS) 769 bool adjustForIOSCaretWhenScrolling() const { return m_adjustForIOSCaretWhenScrolling; } 770 void setAdjustForIOSCaretWhenScrolling(bool adjustForIOSCaretWhenScrolling) { m_adjustForIOSCaretWhenScrolling = adjustForIOSCaretWhenScrolling; } 771#endif 772 773 bool hasTransform() const { return renderer().hasTransform(); } 774 // Note that this transform has the transform-origin baked in. 775 TransformationMatrix* transform() const { return m_transform.get(); } 776 // currentTransform computes a transform which takes accelerated animations into account. The 777 // resulting transform has transform-origin baked in. If the layer does not have a transform, 778 // returns the identity matrix. 779 TransformationMatrix currentTransform(RenderStyle::ApplyTransformOrigin = RenderStyle::IncludeTransformOrigin) const; 780 TransformationMatrix renderableTransform(PaintBehavior) const; 781 782 // Get the perspective transform, which is applied to transformed sublayers. 783 // Returns true if the layer has a -webkit-perspective. 784 // Note that this transform has the perspective-origin baked in. 785 TransformationMatrix perspectiveTransform() const; 786 FloatPoint perspectiveOrigin() const; 787 bool preserves3D() const { return renderer().style().transformStyle3D() == TransformStyle3DPreserve3D; } 788 bool has3DTransform() const { return m_transform && !m_transform->isAffine(); } 789 790#if ENABLE(CSS_FILTERS) 791 virtual void filterNeedsRepaint(); 792 bool hasFilter() const { return renderer().hasFilter(); } 793#else 794 bool hasFilter() const { return false; } 795#endif 796 797#if ENABLE(CSS_COMPOSITING) 798 bool hasBlendMode() const { return renderer().hasBlendMode(); } 799 BlendMode blendMode() const { return static_cast<BlendMode>(m_blendMode); } 800 801 bool isolatesCompositedBlending() const { return m_hasNotIsolatedCompositedBlendingDescendants && isStackingContext(); } 802 bool hasNotIsolatedCompositedBlendingDescendants() const { return m_hasNotIsolatedCompositedBlendingDescendants; } 803 void setHasNotIsolatedCompositedBlendingDescendants(bool hasNotIsolatedCompositedBlendingDescendants) 804 { 805 m_hasNotIsolatedCompositedBlendingDescendants = hasNotIsolatedCompositedBlendingDescendants; 806 } 807 808 bool isolatesBlending() const { return hasNotIsolatedBlendingDescendants() && isStackingContext(); } 809 810 // FIXME: We should ASSERT(!m_hasNotIsolatedBlendingDescendantsStatusDirty); here but we hit the same bugs as visible content above. 811 bool hasNotIsolatedBlendingDescendants() const { return m_hasNotIsolatedBlendingDescendants; } 812 bool hasNotIsolatedBlendingDescendantsStatusDirty() const { return m_hasNotIsolatedBlendingDescendantsStatusDirty; } 813#else 814 bool hasBlendMode() const { return false; } 815 bool isolatesCompositedBlending() const { return false; } 816 bool isolatesBlending() const { return false; } 817 bool hasNotIsolatedBlendingDescendantsStatusDirty() const { return false; } 818#endif 819 820 bool isComposited() const { return m_backing != 0; } 821 bool hasCompositingDescendant() const { return m_hasCompositingDescendant; } 822 bool hasCompositedMask() const; 823 RenderLayerBacking* backing() const { return m_backing.get(); } 824 RenderLayerBacking* ensureBacking(); 825 void clearBacking(bool layerBeingDestroyed = false); 826 virtual GraphicsLayer* layerForScrolling() const override; 827 virtual GraphicsLayer* layerForHorizontalScrollbar() const override; 828 virtual GraphicsLayer* layerForVerticalScrollbar() const override; 829 virtual GraphicsLayer* layerForScrollCorner() const override; 830 virtual bool usesCompositedScrolling() const override; 831 bool needsCompositedScrolling() const; 832 bool needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const; 833 bool needsCompositingLayersRebuiltForOverflow(const RenderStyle* oldStyle, const RenderStyle* newStyle) const; 834 835 bool paintsWithTransparency(PaintBehavior paintBehavior) const 836 { 837 return (isTransparent() || hasBlendMode() || (isolatesBlending() && !renderer().isRoot())) && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || !isComposited()); 838 } 839 840 bool paintsWithTransform(PaintBehavior) const; 841 842 // Returns true if background phase is painted opaque in the given rect. 843 // The query rect is given in local coordinates. 844 bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const; 845 846 bool containsDirtyOverlayScrollbars() const { return m_containsDirtyOverlayScrollbars; } 847 void setContainsDirtyOverlayScrollbars(bool dirtyScrollbars) { m_containsDirtyOverlayScrollbars = dirtyScrollbars; } 848 849#if ENABLE(CSS_FILTERS) 850 bool paintsWithFilters() const; 851 bool requiresFullLayerImageForFilters() const; 852 FilterEffectRenderer* filterRenderer() const; 853#endif 854 855#if !ASSERT_DISABLED 856 bool layerListMutationAllowed() const { return m_layerListMutationAllowed; } 857 void setLayerListMutationAllowed(bool flag) { m_layerListMutationAllowed = flag; } 858#endif 859 860 Element* enclosingElement() const; 861 862 enum ViewportConstrainedNotCompositedReason { 863 NoNotCompositedReason, 864 NotCompositedForBoundsOutOfView, 865 NotCompositedForNonViewContainer, 866 NotCompositedForNoVisibleContent, 867 }; 868 869 void setViewportConstrainedNotCompositedReason(ViewportConstrainedNotCompositedReason reason) { m_viewportConstrainedNotCompositedReason = reason; } 870 ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason() const { return static_cast<ViewportConstrainedNotCompositedReason>(m_viewportConstrainedNotCompositedReason); } 871 872 bool isRenderFlowThread() const { return renderer().isRenderFlowThread(); } 873 bool isOutOfFlowRenderFlowThread() const { return renderer().isOutOfFlowRenderFlowThread(); } 874 bool isInsideFlowThread() const { return renderer().flowThreadState() != RenderObject::NotInsideFlowThread; } 875 bool isInsideOutOfFlowThread() const { return renderer().flowThreadState() == RenderObject::InsideOutOfFlowThread; } 876 bool isDirtyRenderFlowThread() const 877 { 878 ASSERT(isRenderFlowThread()); 879 return m_zOrderListsDirty || m_normalFlowListDirty; 880 } 881 882 bool isFlowThreadCollectingGraphicsLayersUnderRegions() const; 883 884 RenderLayer* enclosingFlowThreadAncestor() const; 885 886private: 887 enum CollectLayersBehavior { StopAtStackingContexts, StopAtStackingContainers }; 888 889 struct LayerPaintingInfo { 890 LayerPaintingInfo(RenderLayer* inRootLayer, const LayoutRect& inDirtyRect, PaintBehavior inPaintBehavior, const LayoutSize& inSubpixelAccumulation, RenderObject* inSubtreePaintRoot = nullptr, OverlapTestRequestMap* inOverlapTestRequests = nullptr) 891 : rootLayer(inRootLayer) 892 , subtreePaintRoot(inSubtreePaintRoot) 893 , paintDirtyRect(inDirtyRect) 894 , subpixelAccumulation(inSubpixelAccumulation) 895 , overlapTestRequests(inOverlapTestRequests) 896 , paintBehavior(inPaintBehavior) 897 , clipToDirtyRect(true) 898 { } 899 RenderLayer* rootLayer; 900 RenderObject* subtreePaintRoot; // only paint descendants of this object 901 LayoutRect paintDirtyRect; // relative to rootLayer; 902 LayoutSize subpixelAccumulation; 903 OverlapTestRequestMap* overlapTestRequests; // May be null. 904 PaintBehavior paintBehavior; 905 bool clipToDirtyRect; 906 }; 907 908 void updateZOrderLists(); 909 void rebuildZOrderLists(); 910 void rebuildZOrderLists(CollectLayersBehavior, std::unique_ptr<Vector<RenderLayer*>>&, std::unique_ptr<Vector<RenderLayer*>>&); 911 void clearZOrderLists(); 912 913 void updateNormalFlowList(); 914 915 // Non-auto z-index always implies stacking context here, because StyleResolver::adjustRenderStyle already adjusts z-index 916 // based on positioning and other criteria. 917 bool isStackingContext(const RenderStyle* style) const { return !style->hasAutoZIndex() || isRootLayer(); } 918 919 bool isDirtyStackingContainer() const { return m_zOrderListsDirty && isStackingContainer(); } 920 921 void setAncestorChainHasSelfPaintingLayerDescendant(); 922 void dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); 923 924 bool acceleratedCompositingForOverflowScrollEnabled() const; 925 void updateDescendantsAreContiguousInStackingOrder(); 926 void updateDescendantsAreContiguousInStackingOrderRecursive(const HashMap<const RenderLayer*, int>&, int& minIndex, int& maxIndex, int& count, bool firstIteration); 927 928 void computeRepaintRects(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* = nullptr); 929 void computeRepaintRectsIncludingDescendants(); 930 void clearRepaintRects(); 931 932 void clipToRect(const LayerPaintingInfo&, GraphicsContext*, const ClipRect&, BorderRadiusClippingRule = IncludeSelfForBorderRadius); 933 void restoreClip(GraphicsContext*, const LayoutRect& paintDirtyRect, const ClipRect&); 934 935 bool shouldRepaintAfterLayout() const; 936 937 void updateSelfPaintingLayer(); 938 void updateStackingContextsAfterStyleChange(const RenderStyle* oldStyle); 939 940 void updateScrollbarsAfterStyleChange(const RenderStyle* oldStyle); 941 void updateScrollbarsAfterLayout(); 942 943 void setAncestorChainHasOutOfFlowPositionedDescendant(RenderBlock* containingBlock); 944 void dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus(); 945 void updateOutOfFlowPositioned(const RenderStyle* oldStyle); 946 947 void updateNeedsCompositedScrolling(); 948 949 // Returns true if the position changed. 950 bool updateLayerPosition(); 951 952 void updateLayerPositions(RenderGeometryMap* = nullptr, UpdateLayerPositionsFlags = defaultFlags); 953 954 enum UpdateLayerPositionsAfterScrollFlag { 955 NoFlag = 0, 956 IsOverflowScroll = 1 << 0, 957 HasSeenViewportConstrainedAncestor = 1 << 1, 958 HasSeenAncestorWithOverflowClip = 1 << 2, 959 HasChangedAncestor = 1 << 3 960 }; 961 typedef unsigned UpdateLayerPositionsAfterScrollFlags; 962 void updateLayerPositionsAfterScroll(RenderGeometryMap*, UpdateLayerPositionsAfterScrollFlags = NoFlag); 963 964 friend IntSize RenderBox::scrolledContentOffset() const; 965 IntSize scrolledContentOffset() const { return m_scrollOffset; } 966 967 IntSize clampScrollOffset(const IntSize&) const; 968 969 RenderLayer* enclosingPaginationLayerInSubtree(const RenderLayer* rootLayer, PaginationInclusionMode) const; 970 971 void setNextSibling(RenderLayer* next) { m_next = next; } 972 void setPreviousSibling(RenderLayer* prev) { m_previous = prev; } 973 void setParent(RenderLayer* parent); 974 void setFirstChild(RenderLayer* first) { m_first = first; } 975 void setLastChild(RenderLayer* last) { m_last = last; } 976 977 LayoutPoint renderBoxLocation() const { return renderer().isBox() ? toRenderBox(renderer()).location() : LayoutPoint(); } 978 979 void collectLayers(bool includeHiddenLayers, CollectLayersBehavior, std::unique_ptr<Vector<RenderLayer*>>&, std::unique_ptr<Vector<RenderLayer*>>&); 980 981 void updateCompositingAndLayerListsIfNeeded(); 982 983 bool setupFontSubpixelQuantization(GraphicsContext*, bool& didQuantizeFonts); 984 bool setupClipPath(GraphicsContext*, const LayerPaintingInfo&, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed); 985#if ENABLE(CSS_FILTERS) 986 std::unique_ptr<FilterEffectRendererHelper> setupFilters(GraphicsContext*, LayerPaintingInfo&, PaintLayerFlags, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed); 987 GraphicsContext* applyFilters(FilterEffectRendererHelper*, GraphicsContext* originalContext, LayerPaintingInfo&, LayerFragments&); 988#endif 989 990 void paintLayer(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); 991 void paintFixedLayersInNamedFlows(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); 992 void paintLayerContentsAndReflection(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); 993 void paintLayerByApplyingTransform(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags, const LayoutSize& translationOffset = LayoutSize()); 994 void paintLayerContents(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); 995 void paintList(Vector<RenderLayer*>*, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); 996 997 void collectFragments(LayerFragments&, const RenderLayer* rootLayer, const LayoutRect& dirtyRect, 998 PaginationInclusionMode, 999 ClipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip, const LayoutSize& offsetFromRoot, 1000 const LayoutRect* layerBoundingBox = nullptr, ShouldApplyRootOffsetToFragments = IgnoreRootOffsetForFragments); 1001 void updatePaintingInfoForFragments(LayerFragments&, const LayerPaintingInfo&, PaintLayerFlags, bool shouldPaintContent, const LayoutSize& offsetFromRoot); 1002 void paintBackgroundForFragments(const LayerFragments&, GraphicsContext*, GraphicsContext* transparencyLayerContext, 1003 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer); 1004 void paintForegroundForFragments(const LayerFragments&, GraphicsContext*, GraphicsContext* transparencyLayerContext, 1005 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer, 1006 bool selectionOnly, bool forceBlackText); 1007 void paintForegroundForFragmentsWithPhase(PaintPhase, const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer); 1008 void paintOutlineForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer); 1009 void paintOverflowControlsForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&); 1010 void paintMaskForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, RenderObject* paintingRootForRenderer); 1011 void paintTransformedLayerIntoFragments(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); 1012 1013 RenderLayer* transparentPaintingAncestor(); 1014 void beginTransparencyLayers(GraphicsContext*, const LayerPaintingInfo&, const LayoutRect& dirtyRect); 1015 1016 RenderLayer* hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result, 1017 const LayoutRect& hitTestRect, const HitTestLocation&, bool appliedTransform, 1018 const HitTestingTransformState* = nullptr, double* zOffset = nullptr); 1019 RenderLayer* hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&, 1020 const LayoutRect& hitTestRect, const HitTestLocation&, const HitTestingTransformState* = nullptr, double* zOffset = nullptr, 1021 const LayoutSize& translationOffset = LayoutSize()); 1022 RenderLayer* hitTestList(Vector<RenderLayer*>*, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result, 1023 const LayoutRect& hitTestRect, const HitTestLocation&, 1024 const HitTestingTransformState*, double* zOffsetForDescendants, double* zOffset, 1025 const HitTestingTransformState* unflattenedTransformState, bool depthSortDescendants); 1026 1027 RenderLayer* hitTestFixedLayersInNamedFlows(RenderLayer* rootLayer, 1028 const HitTestRequest&, HitTestResult&, 1029 const LayoutRect& hitTestRect, const HitTestLocation&, 1030 const HitTestingTransformState*, 1031 double* zOffsetForDescendants, double* zOffset, 1032 const HitTestingTransformState* unflattenedTransformState, 1033 bool depthSortDescendants); 1034 1035 PassRefPtr<HitTestingTransformState> createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer, 1036 const LayoutRect& hitTestRect, const HitTestLocation&, 1037 const HitTestingTransformState* containerTransformState, 1038 const LayoutSize& translationOffset = LayoutSize()) const; 1039 1040 bool hitTestContents(const HitTestRequest&, HitTestResult&, const LayoutRect& layerBounds, const HitTestLocation&, HitTestFilter) const; 1041 bool hitTestContentsForFragments(const LayerFragments&, const HitTestRequest&, HitTestResult&, const HitTestLocation&, HitTestFilter, bool& insideClipRect) const; 1042 bool hitTestResizerInFragments(const LayerFragments&, const HitTestLocation&) const; 1043 RenderLayer* hitTestTransformedLayerInFragments(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&, 1044 const LayoutRect& hitTestRect, const HitTestLocation&, const HitTestingTransformState* = nullptr, double* zOffset = nullptr); 1045 1046 bool listBackgroundIsKnownToBeOpaqueInRect(const Vector<RenderLayer*>*, const LayoutRect&) const; 1047 1048 void computeScrollDimensions(); 1049 bool hasHorizontalOverflow() const; 1050 bool hasVerticalOverflow() const; 1051 bool hasScrollableHorizontalOverflow() const; 1052 bool hasScrollableVerticalOverflow() const; 1053 1054 bool showsOverflowControls() const; 1055 1056 bool shouldBeNormalFlowOnly() const; 1057 1058 bool shouldBeSelfPaintingLayer() const; 1059 1060 virtual int scrollPosition(Scrollbar*) const override; 1061 1062 // ScrollableArea interface 1063 virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) override; 1064 virtual void invalidateScrollCornerRect(const IntRect&) override; 1065 virtual bool isActive() const override; 1066 virtual bool isScrollCornerVisible() const override; 1067 virtual IntRect scrollCornerRect() const override; 1068 virtual IntRect convertFromScrollbarToContainingView(const Scrollbar*, const IntRect&) const override; 1069 virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar*, const IntRect&) const override; 1070 virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar*, const IntPoint&) const override; 1071 virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar*, const IntPoint&) const override; 1072 virtual int scrollSize(ScrollbarOrientation) const override; 1073 virtual void setScrollOffset(const IntPoint&) override; 1074 virtual IntPoint scrollPosition() const override; 1075 virtual IntPoint minimumScrollPosition() const override; 1076 virtual IntPoint maximumScrollPosition() const override; 1077 virtual IntRect visibleContentRectInternal(VisibleContentRectIncludesScrollbars, VisibleContentRectBehavior) const override; 1078 virtual IntSize visibleSize() const override; 1079 virtual IntSize contentsSize() const override; 1080 virtual IntSize overhangAmount() const override; 1081 virtual IntPoint lastKnownMousePosition() const override; 1082 virtual bool isHandlingWheelEvent() const override; 1083 virtual bool shouldSuspendScrollAnimations() const override; 1084 virtual IntRect scrollableAreaBoundingBox() const override; 1085 virtual bool updatesScrollLayerPositionOnMainThread() const override { return true; } 1086 virtual bool forceUpdateScrollbarsOnMainThreadForPerformanceTesting() const override; 1087 1088#if PLATFORM(IOS) 1089 void registerAsTouchEventListenerForScrolling(); 1090 void unregisterAsTouchEventListenerForScrolling(); 1091#endif 1092 1093 // Rectangle encompassing the scroll corner and resizer rect. 1094 LayoutRect scrollCornerAndResizerRect() const; 1095 1096 // NOTE: This should only be called by the overriden setScrollOffset from ScrollableArea. 1097 void scrollTo(int, int); 1098 void updateCompositingLayersAfterScroll(); 1099 1100 IntSize scrollbarOffset(const Scrollbar*) const; 1101 1102 void updateScrollableAreaSet(bool hasOverflow); 1103 1104 void dirtyAncestorChainVisibleDescendantStatus(); 1105 void setAncestorChainHasVisibleDescendant(); 1106 1107 void updateDescendantDependentFlags(HashSet<const RenderObject*>* outOfFlowDescendantContainingBlocks = nullptr); 1108 bool checkIfDescendantClippingContextNeedsUpdate(bool isClipping); 1109 1110 bool has3DTransformedDescendant() const { return m_has3DTransformedDescendant; } 1111 1112 bool hasTransformedAncestor() const { return m_hasTransformedAncestor; } 1113 bool has3DTransformedAncestor() const { return m_has3DTransformedAncestor; } 1114 1115 void dirty3DTransformedDescendantStatus(); 1116 // Both updates the status, and returns true if descendants of this have 3d. 1117 bool update3DTransformedDescendantStatus(); 1118 1119 void createReflection(); 1120 void removeReflection(); 1121 1122 PassRef<RenderStyle> createReflectionStyle(); 1123 bool paintingInsideReflection() const { return m_paintingInsideReflection; } 1124 void setPaintingInsideReflection(bool b) { m_paintingInsideReflection = b; } 1125 1126#if ENABLE(CSS_FILTERS) 1127 void updateOrRemoveFilterClients(); 1128 void updateOrRemoveFilterEffectRenderer(); 1129#endif 1130 1131#if ENABLE(CSS_COMPOSITING) 1132 void updateAncestorChainHasBlendingDescendants(); 1133 void dirtyAncestorChainHasBlendingDescendants(); 1134#endif 1135 1136 void parentClipRects(const ClipRectsContext&, ClipRects&) const; 1137 ClipRect backgroundClipRect(const ClipRectsContext&) const; 1138 1139 RenderLayer* enclosingTransformedAncestor() const; 1140 1141 // Convert a point in absolute coords into layer coords, taking transforms into account 1142 LayoutPoint absoluteToContents(const LayoutPoint&) const; 1143 1144 void positionOverflowControls(const IntSize&); 1145 void updateScrollCornerStyle(); 1146 void updateResizerStyle(); 1147 1148 void drawPlatformResizerImage(GraphicsContext*, const LayoutRect& resizerCornerRect); 1149 1150 void updatePagination(); 1151 1152 void setHasCompositingDescendant(bool b) { m_hasCompositingDescendant = b; } 1153 1154 enum class IndirectCompositingReason { 1155 None, 1156 Stacking, 1157 Overlap, 1158 BackgroundLayer, 1159 GraphicalEffect, // opacity, mask, filter, transform etc. 1160 Perspective, 1161 Preserve3D 1162 }; 1163 1164 void setIndirectCompositingReason(IndirectCompositingReason reason) { m_indirectCompositingReason = static_cast<unsigned>(reason); } 1165 IndirectCompositingReason indirectCompositingReason() const { return static_cast<IndirectCompositingReason>(m_indirectCompositingReason); } 1166 bool mustCompositeForIndirectReasons() const { return m_indirectCompositingReason; } 1167 1168 // Returns true if z ordering would not change if this layer were a stacking container. 1169 bool canBeStackingContainer() const; 1170 1171 friend class RenderLayerBacking; 1172 friend class RenderLayerCompositor; 1173 friend class RenderLayerModelObject; 1174 1175 LayoutUnit overflowTop() const; 1176 LayoutUnit overflowBottom() const; 1177 LayoutUnit overflowLeft() const; 1178 LayoutUnit overflowRight() const; 1179 1180 IntRect rectForHorizontalScrollbar(const IntRect& borderBoxRect) const; 1181 IntRect rectForVerticalScrollbar(const IntRect& borderBoxRect) const; 1182 1183 LayoutUnit verticalScrollbarStart(int minX, int maxX) const; 1184 LayoutUnit horizontalScrollbarStart(int minX) const; 1185 1186 bool overflowControlsIntersectRect(const IntRect& localRect) const; 1187 1188 RenderLayer* hitTestFlowThreadIfRegionForFragments(const LayerFragments&, RenderLayer*, const HitTestRequest&, HitTestResult&, 1189 const LayoutRect&, const HitTestLocation&, 1190 const HitTestingTransformState*, double* zOffsetForDescendants, 1191 double* zOffset, const HitTestingTransformState* unflattenedTransformState, bool depthSortDescendants); 1192 void paintFlowThreadIfRegionForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags); 1193 bool mapLayerClipRectsToFragmentationLayer(ClipRects&) const; 1194 1195 RenderNamedFlowFragment* currentRenderNamedFlowFragment() const; 1196 1197private: 1198 // The bitfields are up here so they will fall into the padding from ScrollableArea on 64-bit. 1199 1200 // Keeps track of whether the layer is currently resizing, so events can cause resizing to start and stop. 1201 bool m_inResizeMode : 1; 1202 1203 bool m_scrollDimensionsDirty : 1; 1204 bool m_zOrderListsDirty : 1; 1205 bool m_normalFlowListDirty: 1; 1206 bool m_isNormalFlowOnly : 1; 1207 1208 bool m_isSelfPaintingLayer : 1; 1209 1210 // If have no self-painting descendants, we don't have to walk our children during painting. This can lead to 1211 // significant savings, especially if the tree has lots of non-self-painting layers grouped together (e.g. table cells). 1212 bool m_hasSelfPaintingLayerDescendant : 1; 1213 bool m_hasSelfPaintingLayerDescendantDirty : 1; 1214 1215 // If we have no out of flow positioned descendants and no non-descendant 1216 // appears between our descendants in stacking order, then we may become a 1217 // stacking context. 1218 bool m_hasOutOfFlowPositionedDescendant : 1; 1219 bool m_hasOutOfFlowPositionedDescendantDirty : 1; 1220 1221 bool m_needsCompositedScrolling : 1; 1222 1223 // If this is true, then no non-descendant appears between any of our 1224 // descendants in stacking order. This is one of the requirements of being 1225 // able to safely become a stacking context. 1226 bool m_descendantsAreContiguousInStackingOrder : 1; 1227 1228 const bool m_isRootLayer : 1; 1229 1230 bool m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether 1231 // we ended up painting this layer or any descendants (and therefore need to 1232 // blend). 1233 bool m_paintingInsideReflection : 1; // A state bit tracking if we are painting inside a replica. 1234 bool m_inOverflowRelayout : 1; 1235 unsigned m_repaintStatus : 2; // RepaintStatus 1236 1237 bool m_visibleContentStatusDirty : 1; 1238 bool m_hasVisibleContent : 1; 1239 bool m_visibleDescendantStatusDirty : 1; 1240 bool m_hasVisibleDescendant : 1; 1241 1242 bool m_3DTransformedDescendantStatusDirty : 1; 1243 bool m_has3DTransformedDescendant : 1; // Set on a stacking context layer that has 3D descendants anywhere 1244 // in a preserves3D hierarchy. Hint to do 3D-aware hit testing. 1245 bool m_hasCompositingDescendant : 1; // In the z-order tree. 1246 1247 bool m_hasTransformedAncestor : 1; 1248 bool m_has3DTransformedAncestor : 1; 1249 1250 unsigned m_indirectCompositingReason : 3; 1251 unsigned m_viewportConstrainedNotCompositedReason : 2; 1252 1253#if PLATFORM(IOS) 1254 bool m_adjustForIOSCaretWhenScrolling : 1; 1255 bool m_registeredAsTouchEventListenerForScrolling : 1; 1256 bool m_inUserScroll : 1; 1257 bool m_requiresScrollBoundsOriginUpdate : 1; 1258#endif 1259 1260 bool m_containsDirtyOverlayScrollbars : 1; 1261 bool m_updatingMarqueePosition : 1; 1262 1263#if !ASSERT_DISABLED 1264 bool m_layerListMutationAllowed : 1; 1265#endif 1266 1267#if ENABLE(CSS_FILTERS) 1268 bool m_hasFilterInfo : 1; 1269#endif 1270 1271#if ENABLE(CSS_COMPOSITING) 1272 unsigned m_blendMode : 5; 1273 bool m_hasNotIsolatedCompositedBlendingDescendants : 1; 1274 bool m_hasNotIsolatedBlendingDescendants : 1; 1275 bool m_hasNotIsolatedBlendingDescendantsStatusDirty : 1; 1276#endif 1277 1278 RenderLayerModelObject& m_renderer; 1279 1280 RenderLayer* m_parent; 1281 RenderLayer* m_previous; 1282 RenderLayer* m_next; 1283 RenderLayer* m_first; 1284 RenderLayer* m_last; 1285 1286 LayoutRect m_repaintRect; // Cached repaint rects. Used by layout. 1287 LayoutRect m_outlineBox; 1288 1289 // Our current relative position offset. 1290 LayoutSize m_offsetForInFlowPosition; 1291 1292 // Our (x,y) coordinates are in our parent layer's coordinate space. 1293 LayoutPoint m_topLeft; 1294 1295 // The layer's width/height 1296 IntSize m_layerSize; 1297 1298 // This is the (scroll) offset from scrollOrigin(). 1299 IntSize m_scrollOffset; 1300 1301 // The width/height of our scrolled area. 1302 LayoutSize m_scrollSize; 1303 1304 // For layers with overflow, we have a pair of scrollbars. 1305 RefPtr<Scrollbar> m_hBar; 1306 RefPtr<Scrollbar> m_vBar; 1307 1308 // For layers that establish stacking contexts, m_posZOrderList holds a sorted list of all the 1309 // descendant layers within the stacking context that have z-indices of 0 or greater 1310 // (auto will count as 0). m_negZOrderList holds descendants within our stacking context with negative 1311 // z-indices. 1312 std::unique_ptr<Vector<RenderLayer*>> m_posZOrderList; 1313 std::unique_ptr<Vector<RenderLayer*>> m_negZOrderList; 1314 1315 // This list contains child layers that cannot create stacking contexts. For now it is just 1316 // overflow layers, but that may change in the future. 1317 std::unique_ptr<Vector<RenderLayer*>> m_normalFlowList; 1318 1319 std::unique_ptr<ClipRectsCache> m_clipRectsCache; 1320 1321 IntPoint m_cachedOverlayScrollbarOffset; 1322 1323 std::unique_ptr<RenderMarquee> m_marquee; // Used by layers with overflow:marquee 1324 1325 // Cached normal flow values for absolute positioned elements with static left/top values. 1326 LayoutUnit m_staticInlinePosition; 1327 LayoutUnit m_staticBlockPosition; 1328 1329 std::unique_ptr<TransformationMatrix> m_transform; 1330 1331 // May ultimately be extended to many replicas (with their own paint order). 1332 RenderPtr<RenderReplica> m_reflection; 1333 1334 // Renderers to hold our custom scroll corner and resizer. 1335 RenderPtr<RenderScrollbarPart> m_scrollCorner; 1336 RenderPtr<RenderScrollbarPart> m_resizer; 1337 1338 // Pointer to the enclosing RenderLayer that caused us to be paginated. It is 0 if we are not paginated. 1339 RenderLayer* m_enclosingPaginationLayer; 1340 1341 IntRect m_blockSelectionGapsBounds; 1342 1343 std::unique_ptr<RenderLayerBacking> m_backing; 1344 1345 class FilterInfo; 1346}; 1347 1348inline void RenderLayer::clearZOrderLists() 1349{ 1350 ASSERT(!isStackingContainer()); 1351 1352 m_posZOrderList = nullptr; 1353 m_negZOrderList = nullptr; 1354} 1355 1356inline void RenderLayer::updateZOrderLists() 1357{ 1358 if (!m_zOrderListsDirty) 1359 return; 1360 1361 if (!isStackingContainer()) { 1362 clearZOrderLists(); 1363 m_zOrderListsDirty = false; 1364 return; 1365 } 1366 1367 rebuildZOrderLists(); 1368} 1369 1370#if !ASSERT_DISABLED 1371class LayerListMutationDetector { 1372public: 1373 LayerListMutationDetector(RenderLayer* layer) 1374 : m_layer(layer) 1375 , m_previousMutationAllowedState(layer->layerListMutationAllowed()) 1376 { 1377 m_layer->setLayerListMutationAllowed(false); 1378 } 1379 1380 ~LayerListMutationDetector() 1381 { 1382 m_layer->setLayerListMutationAllowed(m_previousMutationAllowedState); 1383 } 1384 1385private: 1386 RenderLayer* m_layer; 1387 bool m_previousMutationAllowedState; 1388}; 1389#endif 1390 1391void makeMatrixRenderable(TransformationMatrix&, bool has3DRendering); 1392 1393} // namespace WebCore 1394 1395#ifndef NDEBUG 1396// Outside the WebCore namespace for ease of invocation from gdb. 1397void showLayerTree(const WebCore::RenderLayer*); 1398void showLayerTree(const WebCore::RenderObject*); 1399#endif 1400 1401#endif // RenderLayer_h 1402