Implement backing-sharing in compositing layers, allowing overlap layers to paint...
[WebKit-https.git] / Source / WebCore / rendering / RenderLayer.cpp
1 /*
2  * Copyright (C) 2006-2017 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 #include "config.h"
45 #include "RenderLayer.h"
46
47 #include "BoxShape.h"
48 #include "CSSAnimationController.h"
49 #include "CSSFilter.h"
50 #include "CSSPropertyNames.h"
51 #include "Chrome.h"
52 #include "DebugPageOverlays.h"
53 #include "DeprecatedGlobalSettings.h"
54 #include "Document.h"
55 #include "DocumentEventQueue.h"
56 #include "DocumentMarkerController.h"
57 #include "DocumentTimeline.h"
58 #include "Element.h"
59 #include "EventHandler.h"
60 #include "FEColorMatrix.h"
61 #include "FEMerge.h"
62 #include "FloatConversion.h"
63 #include "FloatPoint3D.h"
64 #include "FloatRect.h"
65 #include "FloatRoundedRect.h"
66 #include "FocusController.h"
67 #include "Frame.h"
68 #include "FrameLoader.h"
69 #include "FrameLoaderClient.h"
70 #include "FrameSelection.h"
71 #include "FrameTree.h"
72 #include "FrameView.h"
73 #include "Gradient.h"
74 #include "GraphicsContext.h"
75 #include "HTMLFormControlElement.h"
76 #include "HTMLFrameElement.h"
77 #include "HTMLFrameOwnerElement.h"
78 #include "HTMLIFrameElement.h"
79 #include "HTMLNames.h"
80 #include "HTMLParserIdioms.h"
81 #include "HitTestRequest.h"
82 #include "HitTestResult.h"
83 #include "HitTestingTransformState.h"
84 #include "Logging.h"
85 #include "OverflowEvent.h"
86 #include "OverlapTestRequestClient.h"
87 #include "Page.h"
88 #include "PlatformMouseEvent.h"
89 #include "RenderFlexibleBox.h"
90 #include "RenderFragmentContainer.h"
91 #include "RenderFragmentedFlow.h"
92 #include "RenderGeometryMap.h"
93 #include "RenderImage.h"
94 #include "RenderInline.h"
95 #include "RenderIterator.h"
96 #include "RenderLayerBacking.h"
97 #include "RenderLayerCompositor.h"
98 #include "RenderLayerFilters.h"
99 #include "RenderMarquee.h"
100 #include "RenderMultiColumnFlow.h"
101 #include "RenderReplica.h"
102 #include "RenderSVGResourceClipper.h"
103 #include "RenderSVGRoot.h"
104 #include "RenderScrollbar.h"
105 #include "RenderScrollbarPart.h"
106 #include "RenderTableCell.h"
107 #include "RenderTableRow.h"
108 #include "RenderText.h"
109 #include "RenderTheme.h"
110 #include "RenderTreeAsText.h"
111 #include "RenderView.h"
112 #include "RuntimeEnabledFeatures.h"
113 #include "SVGNames.h"
114 #include "ScaleTransformOperation.h"
115 #include "ScriptDisallowedScope.h"
116 #include "ScrollAnimator.h"
117 #include "Scrollbar.h"
118 #include "ScrollbarTheme.h"
119 #include "ScrollingCoordinator.h"
120 #include "Settings.h"
121 #include "ShadowRoot.h"
122 #include "SourceGraphic.h"
123 #include "StyleProperties.h"
124 #include "StyleResolver.h"
125 #include "TransformationMatrix.h"
126 #include "TranslateTransformOperation.h"
127 #include "WheelEventTestTrigger.h"
128 #include <stdio.h>
129 #include <wtf/MonotonicTime.h>
130 #include <wtf/StdLibExtras.h>
131 #include <wtf/text/CString.h>
132 #include <wtf/text/TextStream.h>
133
134 #if ENABLE(CSS_SCROLL_SNAP)
135 #include "AxisScrollSnapOffsets.h"
136 #endif
137
138 #define MIN_INTERSECT_FOR_REVEAL 32
139
140 namespace WebCore {
141
142 using namespace HTMLNames;
143
144 class ClipRects : public RefCounted<ClipRects> {
145     WTF_MAKE_FAST_ALLOCATED;
146 public:
147     static Ref<ClipRects> create()
148     {
149         return adoptRef(*new ClipRects);
150     }
151
152     static Ref<ClipRects> create(const ClipRects& other)
153     {
154         return adoptRef(*new ClipRects(other));
155     }
156
157     void reset()
158     {
159         m_overflowClipRect.reset();
160         m_fixedClipRect.reset();
161         m_posClipRect.reset();
162         m_fixed = false;
163     }
164
165     const ClipRect& overflowClipRect() const { return m_overflowClipRect; }
166     void setOverflowClipRect(const ClipRect& clipRect) { m_overflowClipRect = clipRect; }
167
168     const ClipRect& fixedClipRect() const { return m_fixedClipRect; }
169     void setFixedClipRect(const ClipRect& clipRect) { m_fixedClipRect = clipRect; }
170
171     const ClipRect& posClipRect() const { return m_posClipRect; }
172     void setPosClipRect(const ClipRect& clipRect) { m_posClipRect = clipRect; }
173
174     bool fixed() const { return m_fixed; }
175     void setFixed(bool fixed) { m_fixed = fixed; }
176
177     bool operator==(const ClipRects& other) const
178     {
179         return m_overflowClipRect == other.overflowClipRect()
180             && m_fixedClipRect == other.fixedClipRect()
181             && m_posClipRect == other.posClipRect()
182             && m_fixed == other.fixed();
183     }
184
185     ClipRects& operator=(const ClipRects& other)
186     {
187         m_overflowClipRect = other.overflowClipRect();
188         m_fixedClipRect = other.fixedClipRect();
189         m_posClipRect = other.posClipRect();
190         m_fixed = other.fixed();
191         return *this;
192     }
193
194 private:
195     ClipRects() = default;
196
197     ClipRects(const LayoutRect& clipRect)
198         : m_overflowClipRect(clipRect)
199         , m_fixedClipRect(clipRect)
200         , m_posClipRect(clipRect)
201     {
202     }
203
204     ClipRects(const ClipRects& other)
205         : RefCounted()
206         , m_fixed(other.fixed())
207         , m_overflowClipRect(other.overflowClipRect())
208         , m_fixedClipRect(other.fixedClipRect())
209         , m_posClipRect(other.posClipRect())
210     {
211     }
212
213     bool m_fixed { false };
214     ClipRect m_overflowClipRect;
215     ClipRect m_fixedClipRect;
216     ClipRect m_posClipRect;
217 };
218
219 class ClipRectsCache {
220     WTF_MAKE_FAST_ALLOCATED;
221 public:
222     ClipRectsCache()
223     {
224 #ifndef NDEBUG
225         for (int i = 0; i < NumCachedClipRectsTypes; ++i) {
226             m_clipRectsRoot[i] = 0;
227             m_scrollbarRelevancy[i] = IgnoreOverlayScrollbarSize;
228         }
229 #endif
230     }
231
232     ClipRects* getClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow) const
233     {
234         return m_clipRects[getIndex(clipRectsType, respectOverflow)].get();
235     }
236
237     void setClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow, RefPtr<ClipRects>&& clipRects)
238     {
239         m_clipRects[getIndex(clipRectsType, respectOverflow)] = WTFMove(clipRects);
240     }
241
242 #ifndef NDEBUG
243     const RenderLayer* m_clipRectsRoot[NumCachedClipRectsTypes];
244     OverlayScrollbarSizeRelevancy m_scrollbarRelevancy[NumCachedClipRectsTypes];
245 #endif
246
247 private:
248     unsigned getIndex(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow) const
249     {
250         unsigned index = static_cast<unsigned>(clipRectsType);
251         if (respectOverflow == RespectOverflowClip)
252             index += static_cast<unsigned>(NumCachedClipRectsTypes);
253         ASSERT_WITH_SECURITY_IMPLICATION(index < NumCachedClipRectsTypes * 2);
254         return index;
255     }
256
257     RefPtr<ClipRects> m_clipRects[NumCachedClipRectsTypes * 2];
258 };
259
260 void makeMatrixRenderable(TransformationMatrix& matrix, bool has3DRendering)
261 {
262 #if !ENABLE(3D_TRANSFORMS)
263     UNUSED_PARAM(has3DRendering);
264     matrix.makeAffine();
265 #else
266     if (!has3DRendering)
267         matrix.makeAffine();
268 #endif
269 }
270
271 RenderLayer::RenderLayer(RenderLayerModelObject& rendererLayerModelObject)
272     : m_isRenderViewLayer(rendererLayerModelObject.isRenderView())
273     , m_forcedStackingContext(rendererLayerModelObject.isMedia())
274     , m_isOpportunisticStackingContext(false)
275     , m_zOrderListsDirty(false)
276     , m_normalFlowListDirty(true)
277     , m_hadNegativeZOrderList(false)
278     , m_inResizeMode(false)
279     , m_scrollDimensionsDirty(true)
280     , m_hasSelfPaintingLayerDescendant(false)
281     , m_hasSelfPaintingLayerDescendantDirty(false)
282     , m_usedTransparency(false)
283     , m_paintingInsideReflection(false)
284     , m_inOverflowRelayout(false)
285     , m_repaintStatus(NeedsNormalRepaint)
286     , m_visibleContentStatusDirty(true)
287     , m_hasVisibleContent(false)
288     , m_visibleDescendantStatusDirty(false)
289     , m_hasVisibleDescendant(false)
290     , m_registeredScrollableArea(false)
291     , m_isFixedIntersectingViewport(false)
292     , m_3DTransformedDescendantStatusDirty(true)
293     , m_has3DTransformedDescendant(false)
294     , m_hasCompositingDescendant(false)
295     , m_hasCompositedScrollingAncestor(false)
296     , m_hasTransformedAncestor(false)
297     , m_has3DTransformedAncestor(false)
298     , m_indirectCompositingReason(static_cast<unsigned>(IndirectCompositingReason::None))
299     , m_viewportConstrainedNotCompositedReason(NoNotCompositedReason)
300 #if PLATFORM(IOS_FAMILY)
301 #if ENABLE(IOS_TOUCH_EVENTS)
302     , m_registeredAsTouchEventListenerForScrolling(false)
303 #endif
304     , m_adjustForIOSCaretWhenScrolling(false)
305 #endif
306     , m_requiresScrollPositionReconciliation(false)
307     , m_containsDirtyOverlayScrollbars(false)
308     , m_updatingMarqueePosition(false)
309 #if !ASSERT_DISABLED
310     , m_layerListMutationAllowed(true)
311 #endif
312 #if ENABLE(CSS_COMPOSITING)
313     , m_blendMode(static_cast<unsigned>(BlendMode::Normal))
314     , m_hasNotIsolatedCompositedBlendingDescendants(false)
315     , m_hasNotIsolatedBlendingDescendants(false)
316     , m_hasNotIsolatedBlendingDescendantsStatusDirty(false)
317 #endif
318     , m_renderer(rendererLayerModelObject)
319 {
320     setIsNormalFlowOnly(shouldBeNormalFlowOnly());
321     setIsCSSStackingContext(shouldBeCSSStackingContext());
322
323     m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
324
325     if (!renderer().firstChild()) {
326         m_visibleContentStatusDirty = false;
327         m_hasVisibleContent = renderer().style().visibility() == Visibility::Visible;
328     }
329
330     if (Element* element = renderer().element()) {
331         // We save and restore only the scrollOffset as the other scroll values are recalculated.
332         m_scrollPosition = element->savedLayerScrollPosition();
333         if (!m_scrollPosition.isZero())
334             scrollAnimator().setCurrentPosition(m_scrollPosition);
335         element->setSavedLayerScrollPosition(IntPoint());
336     }
337 }
338
339 RenderLayer::~RenderLayer()
340 {
341     if (inResizeMode())
342         renderer().frame().eventHandler().resizeLayerDestroyed();
343
344     ASSERT(m_registeredScrollableArea == renderer().view().frameView().containsScrollableArea(this));
345
346     if (m_registeredScrollableArea)
347         renderer().view().frameView().removeScrollableArea(this);
348
349 #if ENABLE(IOS_TOUCH_EVENTS)
350     unregisterAsTouchEventListenerForScrolling();
351 #endif
352     if (Element* element = renderer().element())
353         element->setSavedLayerScrollPosition(m_scrollPosition);
354
355     destroyScrollbar(HorizontalScrollbar);
356     destroyScrollbar(VerticalScrollbar);
357
358     if (auto* scrollingCoordinator = renderer().page().scrollingCoordinator())
359         scrollingCoordinator->willDestroyScrollableArea(*this);
360
361     if (m_reflection)
362         removeReflection();
363
364     clearScrollCorner();
365     clearResizer();
366
367     clearLayerFilters();
368
369     if (paintsIntoProvidedBacking()) {
370         auto* backingProviderLayer = this->backingProviderLayer();
371         if (backingProviderLayer->backing())
372             backingProviderLayer->backing()->removeBackingSharingLayer(*this);
373     }
374
375     // Child layers will be deleted by their corresponding render objects, so
376     // we don't need to delete them ourselves.
377
378     clearBacking(true);
379
380     // Layer and all its children should be removed from the tree before destruction.
381     RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(renderer().renderTreeBeingDestroyed() || !parent());
382     RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(renderer().renderTreeBeingDestroyed() || !firstChild());
383 }
384
385 void RenderLayer::addChild(RenderLayer& child, RenderLayer* beforeChild)
386 {
387     RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
388     if (prevSibling) {
389         child.setPreviousSibling(prevSibling);
390         prevSibling->setNextSibling(&child);
391         ASSERT(prevSibling != &child);
392     } else
393         setFirstChild(&child);
394
395     if (beforeChild) {
396         beforeChild->setPreviousSibling(&child);
397         child.setNextSibling(beforeChild);
398         ASSERT(beforeChild != &child);
399     } else
400         setLastChild(&child);
401
402     child.setParent(this);
403
404     dirtyPaintOrderListsOnChildChange(child);
405
406     child.updateDescendantDependentFlags();
407     if (child.m_hasVisibleContent || child.m_hasVisibleDescendant)
408         setAncestorChainHasVisibleDescendant();
409
410     if (child.isSelfPaintingLayer() || child.hasSelfPaintingLayerDescendant())
411         setAncestorChainHasSelfPaintingLayerDescendant();
412
413     if (compositor().hasContentCompositingLayers())
414         setDescendantsNeedCompositingRequirementsTraversal();
415
416     if (child.hasDescendantNeedingCompositingRequirementsTraversal() || child.needsCompositingRequirementsTraversal())
417         child.setAncestorsHaveCompositingDirtyFlag(Compositing::HasDescendantNeedingRequirementsTraversal);
418
419     if (child.hasDescendantNeedingUpdateBackingOrHierarchyTraversal() || child.needsUpdateBackingOrHierarchyTraversal())
420         child.setAncestorsHaveCompositingDirtyFlag(Compositing::HasDescendantNeedingBackingOrHierarchyTraversal);
421
422 #if ENABLE(CSS_COMPOSITING)
423     if (child.hasBlendMode() || (child.hasNotIsolatedBlendingDescendants() && !child.isolatesBlending()))
424         updateAncestorChainHasBlendingDescendants(); // Why not just dirty?
425 #endif
426
427     compositor().layerWasAdded(*this, child);
428 }
429
430 void RenderLayer::removeChild(RenderLayer& oldChild)
431 {
432     if (!renderer().renderTreeBeingDestroyed())
433         compositor().layerWillBeRemoved(*this, oldChild);
434
435     // remove the child
436     if (oldChild.previousSibling())
437         oldChild.previousSibling()->setNextSibling(oldChild.nextSibling());
438     if (oldChild.nextSibling())
439         oldChild.nextSibling()->setPreviousSibling(oldChild.previousSibling());
440
441     if (m_first == &oldChild)
442         m_first = oldChild.nextSibling();
443     if (m_last == &oldChild)
444         m_last = oldChild.previousSibling();
445
446     dirtyPaintOrderListsOnChildChange(oldChild);
447
448     oldChild.setPreviousSibling(nullptr);
449     oldChild.setNextSibling(nullptr);
450     oldChild.setParent(nullptr);
451     
452     oldChild.updateDescendantDependentFlags();
453     if (oldChild.m_hasVisibleContent || oldChild.m_hasVisibleDescendant)
454         dirtyAncestorChainVisibleDescendantStatus();
455
456     if (oldChild.isSelfPaintingLayer() || oldChild.hasSelfPaintingLayerDescendant())
457         dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
458
459     if (compositor().hasContentCompositingLayers())
460         setDescendantsNeedCompositingRequirementsTraversal();
461
462 #if ENABLE(CSS_COMPOSITING)
463     if (oldChild.hasBlendMode() || (oldChild.hasNotIsolatedBlendingDescendants() && !oldChild.isolatesBlending()))
464         dirtyAncestorChainHasBlendingDescendants();
465 #endif
466 }
467
468 void RenderLayer::dirtyPaintOrderListsOnChildChange(RenderLayer& child)
469 {
470     if (child.isNormalFlowOnly())
471         dirtyNormalFlowList();
472
473     if (!child.isNormalFlowOnly() || child.firstChild()) {
474         // Dirty the z-order list in which we are contained. The stackingContext() can be null in the
475         // case where we're building up generated content layers. This is ok, since the lists will start
476         // off dirty in that case anyway.
477         child.dirtyStackingContextZOrderLists();
478     }
479 }
480
481 void RenderLayer::insertOnlyThisLayer()
482 {
483     if (!m_parent && renderer().parent()) {
484         // We need to connect ourselves when our renderer() has a parent.
485         // Find our enclosingLayer and add ourselves.
486         RenderLayer* parentLayer = renderer().parent()->enclosingLayer();
487         ASSERT(parentLayer);
488         RenderLayer* beforeChild = parentLayer->reflectionLayer() != this ? renderer().parent()->findNextLayer(parentLayer, &renderer()) : nullptr;
489         parentLayer->addChild(*this, beforeChild);
490     }
491
492     // Remove all descendant layers from the hierarchy and add them to the new position.
493     for (auto& child : childrenOfType<RenderElement>(renderer()))
494         child.moveLayers(m_parent, this);
495
496     // Clear out all the clip rects.
497     clearClipRectsIncludingDescendants();
498 }
499
500 void RenderLayer::removeOnlyThisLayer()
501 {
502     if (!m_parent)
503         return;
504
505     // Mark that we are about to lose our layer. This makes render tree
506     // walks ignore this layer while we're removing it.
507     renderer().setHasLayer(false);
508
509     compositor().layerWillBeRemoved(*m_parent, *this);
510
511     // Dirty the clip rects.
512     clearClipRectsIncludingDescendants();
513
514     RenderLayer* nextSib = nextSibling();
515
516     // Remove the child reflection layer before moving other child layers.
517     // The reflection layer should not be moved to the parent.
518     if (reflection())
519         removeChild(*reflectionLayer());
520
521     // Now walk our kids and reattach them to our parent.
522     RenderLayer* current = m_first;
523     while (current) {
524         RenderLayer* next = current->nextSibling();
525         removeChild(*current);
526         m_parent->addChild(*current, nextSib);
527         current->setRepaintStatus(NeedsFullRepaint);
528         current = next;
529     }
530
531     // Remove us from the parent.
532     m_parent->removeChild(*this);
533     renderer().destroyLayer();
534 }
535
536 static bool canCreateStackingContext(const RenderLayer& layer)
537 {
538     auto& renderer = layer.renderer();
539     return renderer.hasTransformRelatedProperty()
540         || renderer.hasClipPath()
541         || renderer.hasFilter()
542         || renderer.hasMask()
543         || renderer.hasBackdropFilter()
544 #if ENABLE(CSS_COMPOSITING)
545         || renderer.hasBlendMode()
546 #endif
547         || renderer.isTransparent()
548         || renderer.isPositioned() // Note that this only creates stacking context in conjunction with explicit z-index.
549         || renderer.hasReflection()
550         || renderer.style().hasIsolation()
551         || !renderer.style().hasAutoZIndex()
552         || (renderer.style().willChange() && renderer.style().willChange()->canCreateStackingContext());
553 }
554
555 bool RenderLayer::shouldBeNormalFlowOnly() const
556 {
557     if (canCreateStackingContext(*this))
558         return false;
559
560     return renderer().hasOverflowClip()
561         || renderer().isCanvas()
562         || renderer().isVideo()
563         || renderer().isEmbeddedObject()
564         || renderer().isRenderIFrame()
565         || (renderer().isRenderImage() && downcast<RenderImage>(renderer()).isEditableImage())
566         || (renderer().style().specifiesColumns() && !isRenderViewLayer())
567         || renderer().isInFlowRenderFragmentedFlow();
568 }
569
570 bool RenderLayer::shouldBeCSSStackingContext() const
571 {
572     return !renderer().style().hasAutoZIndex() || isRenderViewLayer();
573 }
574
575 bool RenderLayer::setIsNormalFlowOnly(bool isNormalFlowOnly)
576 {
577     if (isNormalFlowOnly == m_isNormalFlowOnly)
578         return false;
579     
580     m_isNormalFlowOnly = isNormalFlowOnly;
581
582     if (auto* p = parent())
583         p->dirtyNormalFlowList();
584     dirtyStackingContextZOrderLists();
585     return true;
586 }
587
588 void RenderLayer::isStackingContextChanged()
589 {
590     dirtyStackingContextZOrderLists();
591     if (isStackingContext())
592         dirtyZOrderLists();
593     else
594         clearZOrderLists();
595 }
596
597 bool RenderLayer::setIsOpportunisticStackingContext(bool isStacking)
598 {
599     bool wasStacking = isStackingContext();
600     m_isOpportunisticStackingContext = isStacking;
601     if (wasStacking == isStackingContext())
602         return false;
603
604     isStackingContextChanged();
605     return true;
606 }
607
608 bool RenderLayer::setIsCSSStackingContext(bool isCSSStackingContext)
609 {
610     bool wasStacking = isStackingContext();
611     m_isCSSStackingContext = isCSSStackingContext;
612     if (wasStacking == isStackingContext())
613         return false;
614
615     isStackingContextChanged();
616     return true;
617 }
618
619 void RenderLayer::setParent(RenderLayer* parent)
620 {
621     if (parent == m_parent)
622         return;
623
624     if (m_parent && !renderer().renderTreeBeingDestroyed())
625         compositor().layerWillBeRemoved(*m_parent, *this);
626
627     m_parent = parent;
628
629     if (m_parent && !renderer().renderTreeBeingDestroyed())
630         compositor().layerWasAdded(*m_parent, *this);
631 }
632
633 RenderLayer* RenderLayer::stackingContext() const
634 {
635     auto* layer = parent();
636     while (layer && !layer->isStackingContext())
637         layer = layer->parent();
638
639     ASSERT(!layer || layer->isStackingContext());
640     return layer;
641 }
642
643 void RenderLayer::dirtyZOrderLists()
644 {
645     ASSERT(layerListMutationAllowed());
646     ASSERT(isStackingContext());
647
648     if (m_posZOrderList)
649         m_posZOrderList->clear();
650     if (m_negZOrderList)
651         m_negZOrderList->clear();
652     m_zOrderListsDirty = true;
653
654     // FIXME: Ideally, we'd only dirty if the lists changed.
655     if (hasCompositingDescendant())
656         setNeedsCompositingPaintOrderChildrenUpdate();
657 }
658
659 void RenderLayer::dirtyStackingContextZOrderLists()
660 {
661     if (auto* sc = stackingContext())
662         sc->dirtyZOrderLists();
663 }
664
665 void RenderLayer::dirtyNormalFlowList()
666 {
667     ASSERT(layerListMutationAllowed());
668
669     if (m_normalFlowList)
670         m_normalFlowList->clear();
671     m_normalFlowListDirty = true;
672
673     if (hasCompositingDescendant())
674         setNeedsCompositingPaintOrderChildrenUpdate();
675 }
676
677 void RenderLayer::updateNormalFlowList()
678 {
679     if (!m_normalFlowListDirty)
680         return;
681
682     ASSERT(layerListMutationAllowed());
683
684     for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
685         // Ignore non-overflow layers and reflections.
686         if (child->isNormalFlowOnly() && !isReflectionLayer(*child)) {
687             if (!m_normalFlowList)
688                 m_normalFlowList = std::make_unique<Vector<RenderLayer*>>();
689             m_normalFlowList->append(child);
690         }
691     }
692     
693     m_normalFlowListDirty = false;
694 }
695
696 void RenderLayer::rebuildZOrderLists()
697 {
698     ASSERT(layerListMutationAllowed());
699     ASSERT(isDirtyStackingContext());
700     rebuildZOrderLists(m_posZOrderList, m_negZOrderList);
701     m_zOrderListsDirty = false;
702     
703     bool hasNegativeZOrderList = m_negZOrderList && m_negZOrderList->size();
704     // Having negative z-order lists affect whether a compositing layer needs a foreground layer.
705     // Ideally we'd only trigger this when having z-order children changes, but we blow away the old z-order
706     // lists on dirtying so we don't know the old state.
707     if (hasNegativeZOrderList != m_hadNegativeZOrderList) {
708         m_hadNegativeZOrderList = hasNegativeZOrderList;
709         if (isComposited())
710             setNeedsCompositingConfigurationUpdate();
711     }
712 }
713
714 void RenderLayer::rebuildZOrderLists(std::unique_ptr<Vector<RenderLayer*>>& posZOrderList, std::unique_ptr<Vector<RenderLayer*>>& negZOrderList)
715 {
716     bool includeHiddenLayers = compositor().usesCompositing();
717     for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
718         if (!isReflectionLayer(*child))
719             child->collectLayers(includeHiddenLayers, posZOrderList, negZOrderList);
720     }
721
722     auto compareZIndex = [] (const RenderLayer* first, const RenderLayer* second) -> bool {
723         return first->zIndex() < second->zIndex();
724     };
725
726     // Sort the two lists.
727     if (posZOrderList)
728         std::stable_sort(posZOrderList->begin(), posZOrderList->end(), compareZIndex);
729
730     if (negZOrderList)
731         std::stable_sort(negZOrderList->begin(), negZOrderList->end(), compareZIndex);
732 }
733
734 void RenderLayer::collectLayers(bool includeHiddenLayers, std::unique_ptr<Vector<RenderLayer*>>& positiveZOrderList, std::unique_ptr<Vector<RenderLayer*>>& negativeZOrderList)
735 {
736     updateDescendantDependentFlags();
737
738     bool isStacking = isStackingContext();
739     // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists.
740     bool includeHiddenLayer = includeHiddenLayers || (m_hasVisibleContent || (m_hasVisibleDescendant && isStacking));
741     if (includeHiddenLayer && !isNormalFlowOnly()) {
742         auto& layerList = (zIndex() >= 0) ? positiveZOrderList : negativeZOrderList;
743         if (!layerList)
744             layerList = std::make_unique<Vector<RenderLayer*>>();
745         layerList->append(this);
746     }
747
748     // Recur into our children to collect more layers, but only if we don't establish
749     // a stacking context/container.
750     if ((includeHiddenLayers || m_hasVisibleDescendant) && !isStacking) {
751         for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
752             // Ignore reflections.
753             if (!isReflectionLayer(*child))
754                 child->collectLayers(includeHiddenLayers, positiveZOrderList, negativeZOrderList);
755         }
756     }
757 }
758
759 void RenderLayer::setAncestorsHaveCompositingDirtyFlag(Compositing flag)
760 {
761     for (auto* layer = paintOrderParent(); layer; layer = layer->paintOrderParent()) {
762         if (layer->m_compositingDirtyBits.contains(flag))
763             break;
764         layer->m_compositingDirtyBits.add(flag);
765     }
766 }
767
768 void RenderLayer::updateLayerListsIfNeeded()
769 {
770     updateZOrderLists();
771     updateNormalFlowList();
772
773     if (RenderLayer* reflectionLayer = this->reflectionLayer()) {
774         reflectionLayer->updateZOrderLists();
775         reflectionLayer->updateNormalFlowList();
776     }
777 }
778
779 String RenderLayer::name() const
780 {
781     StringBuilder name;
782
783     if (Element* element = renderer().element()) {
784         name.append(" <");
785         name.append(element->tagName().convertToLowercaseWithoutLocale());
786         name.append('>');
787
788         if (element->hasID()) {
789             name.appendLiteral(" id=\'");
790             name.append(element->getIdAttribute());
791             name.append('\'');
792         }
793
794         if (element->hasClass()) {
795             name.appendLiteral(" class=\'");
796             size_t classNamesToDump = element->classNames().size();
797             const size_t maxNumClassNames = 7;
798             bool addEllipsis = false;
799             if (classNamesToDump > maxNumClassNames) {
800                 classNamesToDump = maxNumClassNames;
801                 addEllipsis = true;
802             }
803             
804             for (size_t i = 0; i < classNamesToDump; ++i) {
805                 if (i > 0)
806                     name.append(' ');
807                 name.append(element->classNames()[i]);
808             }
809             if (addEllipsis)
810                 name.append("...");
811             name.append('\'');
812         }
813     } else
814         name.append(renderer().renderName());
815
816     if (isReflection())
817         name.appendLiteral(" (reflection)");
818
819     return name.toString();
820 }
821
822 RenderLayerCompositor& RenderLayer::compositor() const
823 {
824     return renderer().view().compositor();
825 }
826
827 void RenderLayer::contentChanged(ContentChangeType changeType)
828 {
829     if (changeType == CanvasChanged || changeType == VideoChanged || changeType == FullScreenChanged || (isComposited() && changeType == ImageChanged)) {
830         setNeedsPostLayoutCompositingUpdate();
831         setNeedsCompositingConfigurationUpdate();
832     }
833
834     if (auto* backing = this->backing())
835         backing->contentChanged(changeType);
836 }
837
838 bool RenderLayer::canRender3DTransforms() const
839 {
840     return compositor().canRender3DTransforms();
841 }
842
843 bool RenderLayer::paintsWithFilters() const
844 {
845     if (!renderer().hasFilter())
846         return false;
847         
848     if (!isComposited())
849         return true;
850
851     return !m_backing->canCompositeFilters();
852 }
853
854 bool RenderLayer::requiresFullLayerImageForFilters() const 
855 {
856     if (!paintsWithFilters())
857         return false;
858
859     return m_filters && m_filters->hasFilterThatMovesPixels();
860 }
861
862 void RenderLayer::updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, OptionSet<UpdateLayerPositionsFlag> flags)
863 {
864     LOG(Compositing, "RenderLayer %p updateLayerPositionsAfterLayout", this);
865     RenderGeometryMap geometryMap(UseTransforms);
866     if (this != rootLayer)
867         geometryMap.pushMappingsToAncestor(parent(), nullptr);
868     updateLayerPositions(&geometryMap, flags);
869 }
870
871 void RenderLayer::updateLayerPositions(RenderGeometryMap* geometryMap, OptionSet<UpdateLayerPositionsFlag> flags)
872 {
873     updateLayerPosition(&flags);
874     applyPostLayoutScrollPositionIfNeeded();
875
876     if (geometryMap)
877         geometryMap->pushMappingsToAncestor(this, parent());
878
879     // Clear our cached clip rect information.
880     clearClipRects();
881     
882     if (hasOverflowControls()) {
883         LayoutSize offsetFromRoot;
884         if (geometryMap)
885             offsetFromRoot = LayoutSize(toFloatSize(geometryMap->absolutePoint(FloatPoint())));
886         else {
887             // FIXME: It looks suspicious to call convertToLayerCoords here
888             // as canUseConvertToLayerCoords may be true for an ancestor layer.
889             offsetFromRoot = offsetFromAncestor(root());
890         }
891         positionOverflowControls(roundedIntSize(offsetFromRoot));
892     }
893
894     updateDescendantDependentFlags();
895
896     if (flags & UpdatePagination)
897         updatePagination();
898     else
899         m_enclosingPaginationLayer = nullptr;
900     
901     if (m_hasVisibleContent) {
902         // FIXME: Paint offset cache does not work with RenderLayers as there is not a 1-to-1
903         // mapping between them and the RenderObjects. It would be neat to enable
904         // LayoutState outside the layout() phase and use it here.
905         ASSERT(!renderer().view().frameView().layoutContext().isPaintOffsetCacheEnabled());
906
907         RenderLayerModelObject* repaintContainer = renderer().containerForRepaint();
908         
909         auto hadRepaintLayoutRects = renderer().hasRepaintLayoutRects();
910         RepaintLayoutRects oldRects = hadRepaintLayoutRects ? renderer().repaintLayoutRects() : RepaintLayoutRects();
911         computeRepaintRects(repaintContainer, geometryMap);
912         
913         auto hasRepaintLayoutRects = renderer().hasRepaintLayoutRects();
914         RepaintLayoutRects newRects = hasRepaintLayoutRects ? renderer().repaintLayoutRects() : RepaintLayoutRects();
915         // FIXME: Should ASSERT that value calculated for m_outlineBox using the cached offset is the same
916         // as the value not using the cached offset, but we can't due to https://bugs.webkit.org/show_bug.cgi?id=37048
917         if ((flags & CheckForRepaint) && hasRepaintLayoutRects) {
918             if (!renderer().view().printing()) {
919                 if (m_repaintStatus & NeedsFullRepaint) {
920                     if (hadRepaintLayoutRects)
921                         renderer().repaintUsingContainer(repaintContainer, oldRects.m_repaintRect);
922                     if (!hadRepaintLayoutRects || newRects.m_repaintRect != oldRects.m_repaintRect)
923                         renderer().repaintUsingContainer(repaintContainer, newRects.m_repaintRect);
924                 } else if (shouldRepaintAfterLayout()) {
925                     // FIXME: We will convert this to just take the old and new RepaintLayoutRects once
926                     // we change other callers to use RepaintLayoutRects.
927                     renderer().repaintAfterLayoutIfNeeded(repaintContainer, oldRects.m_repaintRect, oldRects.m_outlineBox, &newRects.m_repaintRect, &newRects.m_outlineBox);
928                 }
929             }
930         }
931     } else
932         clearRepaintRects();
933
934     m_repaintStatus = NeedsNormalRepaint;
935     m_hasTransformedAncestor = flags.contains(SeenTransformedLayer);
936     m_has3DTransformedAncestor = flags.contains(Seen3DTransformedLayer);
937     setHasCompositedScrollingAncestor(flags.contains(SeenCompositedScrollingLayer));
938
939     // Update the reflection's position and size.
940     if (m_reflection)
941         m_reflection->layout();
942
943     if (renderer().isInFlowRenderFragmentedFlow()) {
944         updatePagination();
945         flags.add(UpdatePagination);
946     }
947
948     if (transform()) {
949         flags.add(SeenTransformedLayer);
950         if (!transform()->isAffine())
951             flags.add(Seen3DTransformedLayer);
952     }
953     
954     if (hasCompositedScrollableOverflow())
955         flags.add(SeenCompositedScrollingLayer);
956
957     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
958         child->updateLayerPositions(geometryMap, flags);
959
960     // With all our children positioned, now update our marquee if we need to.
961     if (m_marquee) {
962         // FIXME: would like to use SetForScope<> but it doesn't work with bitfields.
963         bool oldUpdatingMarqueePosition = m_updatingMarqueePosition;
964         m_updatingMarqueePosition = true;
965         m_marquee->updateMarqueePosition();
966         m_updatingMarqueePosition = oldUpdatingMarqueePosition;
967     }
968
969     if (renderer().isFixedPositioned() && renderer().settings().acceleratedCompositingForFixedPositionEnabled()) {
970         bool intersectsViewport = compositor().fixedLayerIntersectsViewport(*this);
971         if (intersectsViewport != m_isFixedIntersectingViewport) {
972             m_isFixedIntersectingViewport = intersectsViewport;
973             setNeedsPostLayoutCompositingUpdate();
974         }
975     }
976
977     if (isComposited())
978         backing()->updateAfterLayout(flags.contains(ContainingClippingLayerChangedSize), flags.contains(NeedsFullRepaintInBacking));
979
980     if (geometryMap)
981         geometryMap->popMappingsToAncestor(parent());
982
983     renderer().document().markers().invalidateRectsForAllMarkers();
984 }
985
986 LayoutRect RenderLayer::repaintRectIncludingNonCompositingDescendants() const
987 {
988     LayoutRect repaintRect = renderer().repaintLayoutRects().m_repaintRect;
989     for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
990         // Don't include repaint rects for composited child layers; they will paint themselves and have a different origin.
991         if (child->isComposited())
992             continue;
993
994         repaintRect.uniteIfNonZero(child->repaintRectIncludingNonCompositingDescendants());
995     }
996     return repaintRect;
997 }
998
999 void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant()
1000 {
1001     for (RenderLayer* layer = this; layer; layer = layer->parent()) {
1002         if (!layer->m_hasSelfPaintingLayerDescendantDirty && layer->hasSelfPaintingLayerDescendant())
1003             break;
1004
1005         layer->m_hasSelfPaintingLayerDescendantDirty = false;
1006         layer->m_hasSelfPaintingLayerDescendant = true;
1007     }
1008 }
1009
1010 void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus()
1011 {
1012     for (RenderLayer* layer = this; layer; layer = layer->parent()) {
1013         layer->m_hasSelfPaintingLayerDescendantDirty = true;
1014         // If we have reached a self-painting layer, we know our parent should have a self-painting descendant
1015         // in this case, there is no need to dirty our ancestors further.
1016         if (layer->isSelfPaintingLayer()) {
1017             ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->hasSelfPaintingLayerDescendant());
1018             break;
1019         }
1020     }
1021 }
1022
1023 void RenderLayer::computeRepaintRects(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* geometryMap)
1024 {
1025     ASSERT(!m_visibleContentStatusDirty);
1026     renderer().computeRepaintLayoutRects(repaintContainer, geometryMap);
1027 }
1028
1029 void RenderLayer::computeRepaintRectsIncludingDescendants()
1030 {
1031     // FIXME: computeRepaintRects() has to walk up the parent chain for every layer to compute the rects.
1032     // We should make this more efficient.
1033     // FIXME: it's wrong to call this when layout is not up-to-date, which we do.
1034     computeRepaintRects(renderer().containerForRepaint());
1035
1036     for (RenderLayer* layer = firstChild(); layer; layer = layer->nextSibling())
1037         layer->computeRepaintRectsIncludingDescendants();
1038 }
1039
1040 void RenderLayer::clearRepaintRects()
1041 {
1042     ASSERT(!m_visibleContentStatusDirty);
1043
1044     renderer().clearRepaintLayoutRects();
1045 }
1046
1047 void RenderLayer::updateLayerPositionsAfterDocumentScroll()
1048 {
1049     ASSERT(this == renderer().view().layer());
1050
1051     LOG(Scrolling, "RenderLayer::updateLayerPositionsAfterDocumentScroll");
1052
1053     RenderGeometryMap geometryMap(UseTransforms);
1054     updateLayerPositionsAfterScroll(&geometryMap);
1055 }
1056
1057 void RenderLayer::updateLayerPositionsAfterOverflowScroll()
1058 {
1059     RenderGeometryMap geometryMap(UseTransforms);
1060     if (this != renderer().view().layer())
1061         geometryMap.pushMappingsToAncestor(parent(), nullptr);
1062
1063     // FIXME: why is it OK to not check the ancestors of this layer in order to
1064     // initialize the HasSeenViewportConstrainedAncestor and HasSeenAncestorWithOverflowClip flags?
1065     updateLayerPositionsAfterScroll(&geometryMap, IsOverflowScroll);
1066 }
1067
1068 void RenderLayer::updateLayerPositionsAfterScroll(RenderGeometryMap* geometryMap, OptionSet<UpdateLayerPositionsAfterScrollFlag> flags)
1069 {
1070     // FIXME: This shouldn't be needed, but there are some corner cases where
1071     // these flags are still dirty. Update so that the check below is valid.
1072     updateDescendantDependentFlags();
1073
1074     // If we have no visible content and no visible descendants, there is no point recomputing
1075     // our rectangles as they will be empty. If our visibility changes, we are expected to
1076     // recompute all our positions anyway.
1077     if (!m_hasVisibleDescendant && !m_hasVisibleContent)
1078         return;
1079
1080     bool positionChanged = updateLayerPosition();
1081     if (positionChanged)
1082         flags.add(HasChangedAncestor);
1083
1084     if (flags.containsAny({ HasChangedAncestor, HasSeenViewportConstrainedAncestor, IsOverflowScroll }))
1085         clearClipRects();
1086
1087     if (renderer().style().hasViewportConstrainedPosition())
1088         flags.add(HasSeenViewportConstrainedAncestor);
1089
1090     if (renderer().hasOverflowClip())
1091         flags.add(HasSeenAncestorWithOverflowClip);
1092     
1093     bool shouldComputeRepaintRects = (flags.contains(HasSeenViewportConstrainedAncestor) || flags.containsAll({ IsOverflowScroll, HasSeenAncestorWithOverflowClip })) && isSelfPaintingLayer();
1094     bool isVisuallyEmpty = !isVisuallyNonEmpty();
1095     bool shouldPushAndPopMappings = geometryMap && ((shouldComputeRepaintRects && !isVisuallyEmpty) || firstChild());
1096     if (shouldPushAndPopMappings)
1097         geometryMap->pushMappingsToAncestor(this, parent());
1098
1099     if (shouldComputeRepaintRects) {
1100         // When scrolling, we don't compute repaint rects for visually non-empty layers.
1101         if (isVisuallyEmpty)
1102             clearRepaintRects();
1103         else // FIXME: We could track the repaint container as we walk down the tree.
1104             computeRepaintRects(renderer().containerForRepaint(), geometryMap);
1105     } else if (!renderer().view().frameView().platformWidget()) {
1106         // When ScrollView's m_paintsEntireContents flag flips due to layer backing changes, the repaint area transitions from
1107         // visual to layout overflow. When this happens the cached repaint rects become invalid and they need to be recomputed (see webkit.org/b/188121).
1108         // Check that our cached rects are correct.
1109         ASSERT(!renderer().hasRepaintLayoutRects() || renderer().repaintLayoutRects().m_repaintRect == renderer().clippedOverflowRectForRepaint(renderer().containerForRepaint()));
1110         ASSERT(!renderer().hasRepaintLayoutRects() || renderer().repaintLayoutRects().m_outlineBox == renderer().outlineBoundsForRepaint(renderer().containerForRepaint()));
1111     }
1112     
1113     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
1114         child->updateLayerPositionsAfterScroll(geometryMap, flags);
1115
1116     // We don't update our reflection as scrolling is a translation which does not change the size()
1117     // of an object, thus RenderReplica will still repaint itself properly as the layer position was
1118     // updated above.
1119
1120     if (m_marquee) {
1121         bool oldUpdatingMarqueePosition = m_updatingMarqueePosition;
1122         m_updatingMarqueePosition = true;
1123         m_marquee->updateMarqueePosition();
1124         m_updatingMarqueePosition = oldUpdatingMarqueePosition;
1125     }
1126
1127     if (shouldPushAndPopMappings)
1128         geometryMap->popMappingsToAncestor(parent());
1129
1130     renderer().document().markers().invalidateRectsForAllMarkers();
1131 }
1132
1133 #if ENABLE(CSS_COMPOSITING)
1134
1135 void RenderLayer::updateBlendMode()
1136 {
1137     bool hadBlendMode = static_cast<BlendMode>(m_blendMode) != BlendMode::Normal;
1138     if (parent() && hadBlendMode != hasBlendMode()) {
1139         if (hasBlendMode())
1140             parent()->updateAncestorChainHasBlendingDescendants();
1141         else
1142             parent()->dirtyAncestorChainHasBlendingDescendants();
1143     }
1144
1145     BlendMode newBlendMode = renderer().style().blendMode();
1146     if (newBlendMode != static_cast<BlendMode>(m_blendMode))
1147         m_blendMode = static_cast<unsigned>(newBlendMode);
1148 }
1149
1150 void RenderLayer::updateAncestorChainHasBlendingDescendants()
1151 {
1152     for (auto* layer = this; layer; layer = layer->parent()) {
1153         if (!layer->hasNotIsolatedBlendingDescendantsStatusDirty() && layer->hasNotIsolatedBlendingDescendants())
1154             break;
1155         layer->m_hasNotIsolatedBlendingDescendants = true;
1156         layer->m_hasNotIsolatedBlendingDescendantsStatusDirty = false;
1157
1158         layer->updateSelfPaintingLayer();
1159
1160         if (layer->isCSSStackingContext())
1161             break;
1162     }
1163 }
1164
1165 void RenderLayer::dirtyAncestorChainHasBlendingDescendants()
1166 {
1167     for (auto* layer = this; layer; layer = layer->parent()) {
1168         if (layer->hasNotIsolatedBlendingDescendantsStatusDirty())
1169             break;
1170         
1171         layer->m_hasNotIsolatedBlendingDescendantsStatusDirty = true;
1172
1173         if (layer->isCSSStackingContext())
1174             break;
1175     }
1176 }
1177 #endif
1178
1179 void RenderLayer::updateTransform()
1180 {
1181     bool hasTransform = renderer().hasTransform();
1182     bool had3DTransform = has3DTransform();
1183
1184     bool hadTransform = !!m_transform;
1185     if (hasTransform != hadTransform) {
1186         if (hasTransform)
1187             m_transform = std::make_unique<TransformationMatrix>();
1188         else
1189             m_transform = nullptr;
1190         
1191         // Layers with transforms act as clip rects roots, so clear the cached clip rects here.
1192         clearClipRectsIncludingDescendants();
1193     }
1194     
1195     if (hasTransform) {
1196         RenderBox* box = renderBox();
1197         ASSERT(box);
1198         m_transform->makeIdentity();
1199         box->style().applyTransform(*m_transform, snapRectToDevicePixels(box->borderBoxRect(), box->document().deviceScaleFactor()), RenderStyle::IncludeTransformOrigin);
1200         makeMatrixRenderable(*m_transform, canRender3DTransforms());
1201     }
1202
1203     if (had3DTransform != has3DTransform()) {
1204         dirty3DTransformedDescendantStatus();
1205         // Having a 3D transform affects whether enclosing perspective and preserve-3d layers composite, so trigger an update.
1206         setNeedsPostLayoutCompositingUpdateOnAncestors();
1207     }
1208 }
1209
1210 TransformationMatrix RenderLayer::currentTransform(RenderStyle::ApplyTransformOrigin applyOrigin) const
1211 {
1212     if (!m_transform)
1213         return TransformationMatrix();
1214     
1215     RenderBox* box = renderBox();
1216
1217     if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
1218         if (auto* timeline = renderer().documentTimeline()) {
1219             if (timeline->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform)) {
1220                 TransformationMatrix currTransform;
1221                 FloatRect pixelSnappedBorderRect = snapRectToDevicePixels(box->borderBoxRect(), box->document().deviceScaleFactor());
1222                 std::unique_ptr<RenderStyle> style = timeline->animatedStyleForRenderer(renderer());
1223                 style->applyTransform(currTransform, pixelSnappedBorderRect, applyOrigin);
1224                 makeMatrixRenderable(currTransform, canRender3DTransforms());
1225                 return currTransform;
1226             }
1227         }
1228     } else {
1229         if (renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform)) {
1230             TransformationMatrix currTransform;
1231             FloatRect pixelSnappedBorderRect = snapRectToDevicePixels(box->borderBoxRect(), box->document().deviceScaleFactor());
1232             std::unique_ptr<RenderStyle> style = renderer().animation().animatedStyleForRenderer(renderer());
1233             style->applyTransform(currTransform, pixelSnappedBorderRect, applyOrigin);
1234             makeMatrixRenderable(currTransform, canRender3DTransforms());
1235             return currTransform;
1236         }
1237     }
1238
1239
1240     // m_transform includes transform-origin, so we need to recompute the transform here.
1241     if (applyOrigin == RenderStyle::ExcludeTransformOrigin) {
1242         TransformationMatrix currTransform;
1243         FloatRect pixelSnappedBorderRect = snapRectToDevicePixels(box->borderBoxRect(), box->document().deviceScaleFactor());
1244         box->style().applyTransform(currTransform, pixelSnappedBorderRect, RenderStyle::ExcludeTransformOrigin);
1245         makeMatrixRenderable(currTransform, canRender3DTransforms());
1246         return currTransform;
1247     }
1248
1249     return *m_transform;
1250 }
1251
1252 TransformationMatrix RenderLayer::renderableTransform(OptionSet<PaintBehavior> paintBehavior) const
1253 {
1254     if (!m_transform)
1255         return TransformationMatrix();
1256     
1257     if (paintBehavior & PaintBehavior::FlattenCompositingLayers) {
1258         TransformationMatrix matrix = *m_transform;
1259         makeMatrixRenderable(matrix, false /* flatten 3d */);
1260         return matrix;
1261     }
1262
1263     return *m_transform;
1264 }
1265
1266 RenderLayer* RenderLayer::enclosingOverflowClipLayer(IncludeSelfOrNot includeSelf) const
1267 {
1268     const RenderLayer* layer = (includeSelf == IncludeSelf) ? this : parent();
1269     while (layer) {
1270         if (layer->renderer().hasOverflowClip())
1271             return const_cast<RenderLayer*>(layer);
1272
1273         layer = layer->parent();
1274     }
1275     return nullptr;
1276 }
1277
1278 // FIXME: This is terrible. Bring back a cached bit for this someday. This crawl is going to slow down all
1279 // painting of content inside paginated layers.
1280 bool RenderLayer::hasCompositedLayerInEnclosingPaginationChain() const
1281 {
1282     // No enclosing layer means no compositing in the chain.
1283     if (!m_enclosingPaginationLayer)
1284         return false;
1285     
1286     // If the enclosing layer is composited, we don't have to check anything in between us and that
1287     // layer.
1288     if (m_enclosingPaginationLayer->isComposited())
1289         return true;
1290
1291     // If we are the enclosing pagination layer, then we can't be composited or we'd have passed the
1292     // previous check.
1293     if (m_enclosingPaginationLayer == this)
1294         return false;
1295
1296     // The enclosing paginated layer is our ancestor and is not composited, so we have to check
1297     // intermediate layers between us and the enclosing pagination layer. Start with our own layer.
1298     if (isComposited())
1299         return true;
1300     
1301     // For normal flow layers, we can recur up the layer tree.
1302     if (isNormalFlowOnly())
1303         return parent()->hasCompositedLayerInEnclosingPaginationChain();
1304     
1305     // Otherwise we have to go up the containing block chain. Find the first enclosing
1306     // containing block layer ancestor, and check that.
1307     for (const auto* containingBlock = renderer().containingBlock(); containingBlock && !is<RenderView>(*containingBlock); containingBlock = containingBlock->containingBlock()) {
1308         if (containingBlock->hasLayer())
1309             return containingBlock->layer()->hasCompositedLayerInEnclosingPaginationChain();
1310     }
1311     return false;
1312 }
1313
1314 void RenderLayer::updatePagination()
1315 {
1316     m_enclosingPaginationLayer = nullptr;
1317     
1318     if (!parent())
1319         return;
1320     
1321     // Each layer that is inside a multicolumn flow thread has to be checked individually and
1322     // genuinely know if it is going to have to split itself up when painting only its contents (and not any other descendant
1323     // layers). We track an enclosingPaginationLayer instead of using a simple bit, since we want to be able to get back
1324     // to that layer easily.
1325     if (renderer().isInFlowRenderFragmentedFlow()) {
1326         m_enclosingPaginationLayer = makeWeakPtr(*this);
1327         return;
1328     }
1329
1330     if (isNormalFlowOnly()) {
1331         // Content inside a transform is not considered to be paginated, since we simply
1332         // paint the transform multiple times in each column, so we don't have to use
1333         // fragments for the transformed content.
1334         if (parent()->hasTransform())
1335             m_enclosingPaginationLayer = nullptr;
1336         else
1337             m_enclosingPaginationLayer = makeWeakPtr(parent()->enclosingPaginationLayer(IncludeCompositedPaginatedLayers));
1338         return;
1339     }
1340
1341     // For the new columns code, we want to walk up our containing block chain looking for an enclosing layer. Once
1342     // we find one, then we just check its pagination status.
1343     for (const auto* containingBlock = renderer().containingBlock(); containingBlock && !is<RenderView>(*containingBlock); containingBlock = containingBlock->containingBlock()) {
1344         if (containingBlock->hasLayer()) {
1345             // Content inside a transform is not considered to be paginated, since we simply
1346             // paint the transform multiple times in each column, so we don't have to use
1347             // fragments for the transformed content.
1348             if (containingBlock->layer()->hasTransform())
1349                 m_enclosingPaginationLayer = nullptr;
1350             else
1351                 m_enclosingPaginationLayer = makeWeakPtr(containingBlock->layer()->enclosingPaginationLayer(IncludeCompositedPaginatedLayers));
1352             return;
1353         }
1354     }
1355 }
1356
1357 void RenderLayer::setHasVisibleContent()
1358
1359     if (m_hasVisibleContent && !m_visibleContentStatusDirty) {
1360         ASSERT(!parent() || parent()->hasVisibleDescendant());
1361         return;
1362     }
1363
1364     m_visibleContentStatusDirty = false; 
1365     m_hasVisibleContent = true;
1366     computeRepaintRects(renderer().containerForRepaint());
1367     if (!isNormalFlowOnly()) {
1368         // We don't collect invisible layers in z-order lists if we are not in compositing mode.
1369         // As we became visible, we need to dirty our stacking containers ancestors to be properly
1370         // collected. FIXME: When compositing, we could skip this dirtying phase.
1371         for (RenderLayer* sc = stackingContext(); sc; sc = sc->stackingContext()) {
1372             sc->dirtyZOrderLists();
1373             if (sc->hasVisibleContent())
1374                 break;
1375         }
1376     }
1377
1378     if (parent())
1379         parent()->setAncestorChainHasVisibleDescendant();
1380 }
1381
1382 void RenderLayer::dirtyVisibleContentStatus() 
1383
1384     m_visibleContentStatusDirty = true; 
1385     if (parent())
1386         parent()->dirtyAncestorChainVisibleDescendantStatus();
1387 }
1388
1389 void RenderLayer::dirtyAncestorChainVisibleDescendantStatus()
1390 {
1391     for (RenderLayer* layer = this; layer; layer = layer->parent()) {
1392         if (layer->m_visibleDescendantStatusDirty)
1393             break;
1394
1395         layer->m_visibleDescendantStatusDirty = true;
1396     }
1397 }
1398
1399 void RenderLayer::setAncestorChainHasVisibleDescendant()
1400 {
1401     for (RenderLayer* layer = this; layer; layer = layer->parent()) {
1402         if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendant())
1403             break;
1404
1405         layer->m_hasVisibleDescendant = true;
1406         layer->m_visibleDescendantStatusDirty = false;
1407     }
1408 }
1409
1410 void RenderLayer::updateDescendantDependentFlags()
1411 {
1412     if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || hasNotIsolatedBlendingDescendantsStatusDirty()) {
1413         bool hasVisibleDescendant = false;
1414         bool hasSelfPaintingLayerDescendant = false;
1415 #if ENABLE(CSS_COMPOSITING)
1416         bool hasNotIsolatedBlendingDescendants = false;
1417 #endif
1418
1419         for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
1420             child->updateDescendantDependentFlags();
1421
1422             hasVisibleDescendant |= child->m_hasVisibleContent || child->m_hasVisibleDescendant;
1423             hasSelfPaintingLayerDescendant |= child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant();
1424 #if ENABLE(CSS_COMPOSITING)
1425             hasNotIsolatedBlendingDescendants |= child->hasBlendMode() || (child->hasNotIsolatedBlendingDescendants() && !child->isolatesBlending());
1426 #endif
1427
1428             bool allFlagsSet = hasVisibleDescendant && hasSelfPaintingLayerDescendant;
1429 #if ENABLE(CSS_COMPOSITING)
1430             allFlagsSet &= hasNotIsolatedBlendingDescendants;
1431 #endif
1432             if (allFlagsSet)
1433                 break;
1434         }
1435
1436         m_hasVisibleDescendant = hasVisibleDescendant;
1437         m_visibleDescendantStatusDirty = false;
1438         m_hasSelfPaintingLayerDescendant = hasSelfPaintingLayerDescendant;
1439         m_hasSelfPaintingLayerDescendantDirty = false;
1440
1441 #if ENABLE(CSS_COMPOSITING)
1442         m_hasNotIsolatedBlendingDescendants = hasNotIsolatedBlendingDescendants;
1443         if (m_hasNotIsolatedBlendingDescendantsStatusDirty) {
1444             m_hasNotIsolatedBlendingDescendantsStatusDirty = false;
1445             updateSelfPaintingLayer();
1446         }
1447 #endif
1448     }
1449
1450     if (m_visibleContentStatusDirty) {
1451         if (renderer().style().visibility() == Visibility::Visible)
1452             m_hasVisibleContent = true;
1453         else {
1454             // layer may be hidden but still have some visible content, check for this
1455             m_hasVisibleContent = false;
1456             RenderObject* r = renderer().firstChild();
1457             while (r) {
1458                 if (r->style().visibility() == Visibility::Visible && !r->hasLayer()) {
1459                     m_hasVisibleContent = true;
1460                     break;
1461                 }
1462                 RenderObject* child = nullptr;
1463                 if (!r->hasLayer() && (child = r->firstChildSlow()))
1464                     r = child;
1465                 else if (r->nextSibling())
1466                     r = r->nextSibling();
1467                 else {
1468                     do {
1469                         r = r->parent();
1470                         if (r == &renderer())
1471                             r = nullptr;
1472                     } while (r && !r->nextSibling());
1473                     if (r)
1474                         r = r->nextSibling();
1475                 }
1476             }
1477         }    
1478         m_visibleContentStatusDirty = false; 
1479     }
1480 }
1481
1482 void RenderLayer::dirty3DTransformedDescendantStatus()
1483 {
1484     RenderLayer* curr = stackingContext();
1485     if (curr)
1486         curr->m_3DTransformedDescendantStatusDirty = true;
1487         
1488     // This propagates up through preserve-3d hierarchies to the enclosing flattening layer.
1489     // Note that preserves3D() creates stacking context, so we can just run up the stacking containers.
1490     while (curr && curr->preserves3D()) {
1491         curr->m_3DTransformedDescendantStatusDirty = true;
1492         curr = curr->stackingContext();
1493     }
1494 }
1495
1496 // Return true if this layer or any preserve-3d descendants have 3d.
1497 bool RenderLayer::update3DTransformedDescendantStatus()
1498 {
1499     if (m_3DTransformedDescendantStatusDirty) {
1500         m_has3DTransformedDescendant = false;
1501
1502         updateZOrderLists();
1503
1504         // Transformed or preserve-3d descendants can only be in the z-order lists, not
1505         // in the normal flow list, so we only need to check those.
1506         for (auto* layer : positiveZOrderLayers())
1507             m_has3DTransformedDescendant |= layer->update3DTransformedDescendantStatus();
1508
1509         // Now check our negative z-index children.
1510         for (auto* layer : negativeZOrderLayers())
1511             m_has3DTransformedDescendant |= layer->update3DTransformedDescendantStatus();
1512         
1513         m_3DTransformedDescendantStatusDirty = false;
1514     }
1515     
1516     // If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs
1517     // the m_has3DTransformedDescendant set.
1518     if (preserves3D())
1519         return has3DTransform() || m_has3DTransformedDescendant;
1520
1521     return has3DTransform();
1522 }
1523
1524 bool RenderLayer::updateLayerPosition(OptionSet<UpdateLayerPositionsFlag>* flags)
1525 {
1526     LayoutPoint localPoint;
1527     LayoutSize inlineBoundingBoxOffset; // We don't put this into the RenderLayer x/y for inlines, so we need to subtract it out when done.
1528     if (renderer().isInline() && is<RenderInline>(renderer())) {
1529         auto& inlineFlow = downcast<RenderInline>(renderer());
1530         IntRect lineBox = inlineFlow.linesBoundingBox();
1531         setSize(lineBox.size());
1532         inlineBoundingBoxOffset = toLayoutSize(lineBox.location());
1533         localPoint += inlineBoundingBoxOffset;
1534     } else if (RenderBox* box = renderBox()) {
1535         // FIXME: Is snapping the size really needed here for the RenderBox case?
1536         auto newSize = snappedIntRect(box->frameRect()).size();
1537         if (newSize != size()) {
1538             if (is<RenderWidget>(*box) && downcast<RenderWidget>(*box).requiresAcceleratedCompositing()) {
1539                 // Trigger RenderLayerCompositor::requiresCompositingForFrame() which depends on the contentBoxRect size.
1540                 setNeedsPostLayoutCompositingUpdate();
1541             }
1542
1543             if (flags && renderer().hasOverflowClip())
1544                 flags->add(ContainingClippingLayerChangedSize);
1545
1546             setSize(newSize);
1547         }
1548         
1549         box->applyTopLeftLocationOffset(localPoint);
1550     }
1551
1552     if (!renderer().isOutOfFlowPositioned()) {
1553         auto* ancestor = renderer().parent();
1554         // We must adjust our position by walking up the render tree looking for the
1555         // nearest enclosing object with a layer.
1556         while (ancestor && !ancestor->hasLayer()) {
1557             if (is<RenderBox>(*ancestor) && !is<RenderTableRow>(*ancestor)) {
1558                 // Rows and cells share the same coordinate space (that of the section).
1559                 // Omit them when computing our xpos/ypos.
1560                 localPoint += downcast<RenderBox>(*ancestor).topLeftLocationOffset();
1561             }
1562             ancestor = ancestor->parent();
1563         }
1564         if (is<RenderTableRow>(ancestor)) {
1565             // Put ourselves into the row coordinate space.
1566             localPoint -= downcast<RenderTableRow>(*ancestor).topLeftLocationOffset();
1567         }
1568     }
1569     
1570     // Subtract our parent's scroll offset.
1571     RenderLayer* positionedParent;
1572     if (renderer().isOutOfFlowPositioned() && (positionedParent = enclosingAncestorForPosition(renderer().style().position()))) {
1573         // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
1574         if (positionedParent->renderer().hasOverflowClip())
1575             localPoint -= toLayoutSize(positionedParent->scrollPosition());
1576         
1577         if (renderer().isOutOfFlowPositioned() && positionedParent->renderer().isInFlowPositioned() && is<RenderInline>(positionedParent->renderer())) {
1578             LayoutSize offset = downcast<RenderInline>(positionedParent->renderer()).offsetForInFlowPositionedInline(&downcast<RenderBox>(renderer()));
1579             localPoint += offset;
1580         }
1581     } else if (parent()) {
1582         if (parent()->renderer().hasOverflowClip())
1583             localPoint -= toLayoutSize(parent()->scrollPosition());
1584     }
1585     
1586     bool positionOrOffsetChanged = false;
1587     if (renderer().isInFlowPositioned()) {
1588         LayoutSize newOffset = downcast<RenderBoxModelObject>(renderer()).offsetForInFlowPosition();
1589         positionOrOffsetChanged = newOffset != m_offsetForInFlowPosition;
1590         m_offsetForInFlowPosition = newOffset;
1591         localPoint.move(m_offsetForInFlowPosition);
1592     } else {
1593         m_offsetForInFlowPosition = LayoutSize();
1594     }
1595
1596     // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
1597     localPoint -= inlineBoundingBoxOffset;
1598     
1599     positionOrOffsetChanged |= location() != localPoint;
1600     setLocation(localPoint);
1601     
1602     if (positionOrOffsetChanged && compositor().hasContentCompositingLayers()) {
1603         if (isComposited())
1604             setNeedsCompositingGeometryUpdate();
1605         // This layer's position can affect the location of a composited descendant (which may be a sibling in z-order),
1606         // so trigger a descendant walk from the paint-order parent.
1607         if (auto* paintParent = paintOrderParent())
1608             paintParent->setDescendantsNeedUpdateBackingAndHierarchyTraversal();
1609     }
1610
1611     return positionOrOffsetChanged;
1612 }
1613
1614 TransformationMatrix RenderLayer::perspectiveTransform() const
1615 {
1616     RenderBox* box = renderBox();
1617     if (!box)
1618         return TransformationMatrix();
1619     
1620     if (!box->hasTransformRelatedProperty())
1621         return TransformationMatrix();
1622
1623     const RenderStyle& style = box->style();
1624     if (!style.hasPerspective())
1625         return TransformationMatrix();
1626
1627     // Maybe fetch the perspective from the backing?
1628     const FloatRect borderBox = snapRectToDevicePixels(box->borderBoxRect(), box->document().deviceScaleFactor());
1629     float perspectiveOriginX = floatValueForLength(style.perspectiveOriginX(), borderBox.width());
1630     float perspectiveOriginY = floatValueForLength(style.perspectiveOriginY(), borderBox.height());
1631
1632     // A perspective origin of 0,0 makes the vanishing point in the center of the element.
1633     // We want it to be in the top-left, so subtract half the height and width.
1634     perspectiveOriginX -= borderBox.width() / 2.0f;
1635     perspectiveOriginY -= borderBox.height() / 2.0f;
1636     
1637     TransformationMatrix t;
1638     t.translate(perspectiveOriginX, perspectiveOriginY);
1639     t.applyPerspective(style.perspective());
1640     t.translate(-perspectiveOriginX, -perspectiveOriginY);
1641     
1642     return t;
1643 }
1644
1645 FloatPoint RenderLayer::perspectiveOrigin() const
1646 {
1647     if (!renderer().hasTransformRelatedProperty())
1648         return FloatPoint();
1649
1650     const LayoutRect borderBox = downcast<RenderBox>(renderer()).borderBoxRect();
1651     const RenderStyle& style = renderer().style();
1652
1653     return FloatPoint(floatValueForLength(style.perspectiveOriginX(), borderBox.width()),
1654                       floatValueForLength(style.perspectiveOriginY(), borderBox.height()));
1655 }
1656
1657 static inline bool isContainerForPositioned(RenderLayer& layer, PositionType position)
1658 {
1659     switch (position) {
1660     case PositionType::Fixed:
1661         return layer.renderer().canContainFixedPositionObjects();
1662
1663     case PositionType::Absolute:
1664         return layer.renderer().canContainAbsolutelyPositionedObjects();
1665     
1666     default:
1667         ASSERT_NOT_REACHED();
1668         return false;
1669     }
1670 }
1671
1672 bool RenderLayer::ancestorLayerIsInContainingBlockChain(const RenderLayer& ancestor, const RenderLayer* checkLimit) const
1673 {
1674     if (&ancestor == this)
1675         return true;
1676
1677     for (const auto* currentBlock = renderer().containingBlock(); currentBlock && !is<RenderView>(*currentBlock); currentBlock = currentBlock->containingBlock()) {
1678         auto* currLayer = currentBlock->layer();
1679         if (currLayer == &ancestor)
1680             return true;
1681         
1682         if (currLayer && currLayer == checkLimit)
1683             return false;
1684     }
1685     
1686     return false;
1687 }
1688
1689 RenderLayer* RenderLayer::enclosingAncestorForPosition(PositionType position) const
1690 {
1691     RenderLayer* curr = parent();
1692     while (curr && !isContainerForPositioned(*curr, position))
1693         curr = curr->parent();
1694
1695     return curr;
1696 }
1697
1698 static RenderLayer* enclosingFrameRenderLayer(const RenderLayer& layer)
1699 {
1700     auto* ownerElement = layer.renderer().document().ownerElement();
1701     if (!ownerElement)
1702         return nullptr;
1703
1704     auto* ownerRenderer = ownerElement->renderer();
1705     if (!ownerRenderer)
1706         return nullptr;
1707
1708     return ownerRenderer->enclosingLayer();
1709 }
1710
1711 static RenderLayer* parentLayerCrossFrame(const RenderLayer& layer)
1712 {
1713     if (auto* parent = layer.parent())
1714         return parent;
1715
1716     return enclosingFrameRenderLayer(layer);
1717 }
1718
1719 RenderLayer* RenderLayer::enclosingScrollableLayer() const
1720 {
1721     for (RenderLayer* nextLayer = parentLayerCrossFrame(*this); nextLayer; nextLayer = parentLayerCrossFrame(*nextLayer)) {
1722         if (is<RenderBox>(nextLayer->renderer()) && downcast<RenderBox>(nextLayer->renderer()).canBeScrolledAndHasScrollableArea())
1723             return nextLayer;
1724     }
1725
1726     return nullptr;
1727 }
1728
1729 IntRect RenderLayer::scrollableAreaBoundingBox(bool* isInsideFixed) const
1730 {
1731     return renderer().absoluteBoundingBoxRect(/* useTransforms */ true, isInsideFixed);
1732 }
1733
1734 bool RenderLayer::isRubberBandInProgress() const
1735 {
1736 #if ENABLE(RUBBER_BANDING)
1737     if (!scrollsOverflow())
1738         return false;
1739
1740     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
1741         return scrollAnimator->isRubberBandInProgress();
1742 #endif
1743
1744     return false;
1745 }
1746
1747 bool RenderLayer::forceUpdateScrollbarsOnMainThreadForPerformanceTesting() const
1748 {
1749     return renderer().settings().forceUpdateScrollbarsOnMainThreadForPerformanceTesting();
1750 }
1751
1752 RenderLayer* RenderLayer::enclosingTransformedAncestor() const
1753 {
1754     RenderLayer* curr = parent();
1755     while (curr && !curr->isRenderViewLayer() && !curr->transform())
1756         curr = curr->parent();
1757
1758     return curr;
1759 }
1760
1761 inline bool RenderLayer::shouldRepaintAfterLayout() const
1762 {
1763     if (m_repaintStatus == NeedsNormalRepaint)
1764         return true;
1765
1766     // Composited layers that were moved during a positioned movement only
1767     // layout, don't need to be repainted. They just need to be recomposited.
1768     ASSERT(m_repaintStatus == NeedsFullRepaintForPositionedMovementLayout);
1769     return !isComposited() || backing()->paintsIntoCompositedAncestor();
1770 }
1771
1772 void RenderLayer::setBackingProviderLayer(RenderLayer* backingProvider)
1773 {
1774     if (backingProvider == m_backingProviderLayer)
1775         return;
1776
1777     clearClipRectsIncludingDescendants();
1778     m_backingProviderLayer = makeWeakPtr(backingProvider);
1779 }
1780
1781 void RenderLayer::disconnectFromBackingProviderLayer()
1782 {
1783     if (!m_backingProviderLayer)
1784         return;
1785     
1786     ASSERT(m_backingProviderLayer->isComposited());
1787     if (m_backingProviderLayer->isComposited())
1788         m_backingProviderLayer->backing()->removeBackingSharingLayer(*this);
1789 }
1790
1791 bool compositedWithOwnBackingStore(const RenderLayer& layer)
1792 {
1793     return layer.isComposited() && !layer.backing()->paintsIntoCompositedAncestor();
1794 }
1795
1796 RenderLayer* RenderLayer::enclosingCompositingLayer(IncludeSelfOrNot includeSelf) const
1797 {
1798     if (includeSelf == IncludeSelf && isComposited())
1799         return const_cast<RenderLayer*>(this);
1800
1801     for (const RenderLayer* curr = paintOrderParent(); curr; curr = curr->paintOrderParent()) {
1802         if (curr->isComposited())
1803             return const_cast<RenderLayer*>(curr);
1804     }
1805          
1806     return nullptr;
1807 }
1808
1809 RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(IncludeSelfOrNot includeSelf) const
1810 {
1811     auto repaintTargetForLayer = [](const RenderLayer& layer) -> RenderLayer* {
1812         if (compositedWithOwnBackingStore(layer))
1813             return const_cast<RenderLayer*>(&layer);
1814         
1815         if (layer.paintsIntoProvidedBacking())
1816             return layer.backingProviderLayer();
1817         
1818         return nullptr;
1819     };
1820
1821     RenderLayer* repaintTarget = nullptr;
1822     if (includeSelf == IncludeSelf && (repaintTarget = repaintTargetForLayer(*this)))
1823         return repaintTarget;
1824
1825     for (const RenderLayer* curr = paintOrderParent(); curr; curr = curr->paintOrderParent()) {
1826         if ((repaintTarget = repaintTargetForLayer(*curr)))
1827             return repaintTarget;
1828     }
1829          
1830     return nullptr;
1831 }
1832
1833 RenderLayer* RenderLayer::enclosingFilterLayer(IncludeSelfOrNot includeSelf) const
1834 {
1835     const RenderLayer* curr = (includeSelf == IncludeSelf) ? this : parent();
1836     for (; curr; curr = curr->parent()) {
1837         if (curr->requiresFullLayerImageForFilters())
1838             return const_cast<RenderLayer*>(curr);
1839     }
1840     
1841     return nullptr;
1842 }
1843
1844 RenderLayer* RenderLayer::enclosingFilterRepaintLayer() const
1845 {
1846     for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
1847         if ((curr != this && curr->requiresFullLayerImageForFilters()) || compositedWithOwnBackingStore(*curr) || curr->isRenderViewLayer())
1848             return const_cast<RenderLayer*>(curr);
1849     }
1850     return nullptr;
1851 }
1852
1853 // FIXME: This neeeds a better name.
1854 void RenderLayer::setFilterBackendNeedsRepaintingInRect(const LayoutRect& rect)
1855 {
1856     ASSERT(requiresFullLayerImageForFilters());
1857     ASSERT(m_filters);
1858
1859     if (rect.isEmpty())
1860         return;
1861     
1862     LayoutRect rectForRepaint = rect;
1863     renderer().style().filterOutsets().expandRect(rectForRepaint);
1864
1865     m_filters->expandDirtySourceRect(rectForRepaint);
1866     
1867     RenderLayer* parentLayer = enclosingFilterRepaintLayer();
1868     ASSERT(parentLayer);
1869     FloatQuad repaintQuad(rectForRepaint);
1870     LayoutRect parentLayerRect = renderer().localToContainerQuad(repaintQuad, &parentLayer->renderer()).enclosingBoundingBox();
1871
1872     if (parentLayer->isComposited()) {
1873         if (!parentLayer->backing()->paintsIntoWindow()) {
1874             parentLayer->setBackingNeedsRepaintInRect(parentLayerRect);
1875             return;
1876         }
1877         // If the painting goes to window, redirect the painting to the parent RenderView.
1878         parentLayer = renderer().view().layer();
1879         parentLayerRect = renderer().localToContainerQuad(repaintQuad, &parentLayer->renderer()).enclosingBoundingBox();
1880     }
1881
1882     if (parentLayer->paintsWithFilters()) {
1883         parentLayer->setFilterBackendNeedsRepaintingInRect(parentLayerRect);
1884         return;        
1885     }
1886     
1887     if (parentLayer->isRenderViewLayer()) {
1888         downcast<RenderView>(parentLayer->renderer()).repaintViewRectangle(parentLayerRect);
1889         return;
1890     }
1891     
1892     ASSERT_NOT_REACHED();
1893 }
1894
1895 bool RenderLayer::hasAncestorWithFilterOutsets() const
1896 {
1897     for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
1898         if (curr->renderer().style().hasFilterOutsets())
1899             return true;
1900     }
1901     return false;
1902 }
1903
1904 RenderLayer* RenderLayer::clippingRootForPainting() const
1905 {
1906     if (isComposited())
1907         return const_cast<RenderLayer*>(this);
1908
1909     if (paintsIntoProvidedBacking())
1910         return backingProviderLayer();
1911
1912     const RenderLayer* current = this;
1913     while (current) {
1914         if (current->isRenderViewLayer())
1915             return const_cast<RenderLayer*>(current);
1916
1917         current = current->paintOrderParent();
1918         ASSERT(current);
1919         if (current->transform() || compositedWithOwnBackingStore(*current))
1920             return const_cast<RenderLayer*>(current);
1921
1922         if (current->paintsIntoProvidedBacking())
1923             return current->backingProviderLayer();
1924     }
1925
1926     ASSERT_NOT_REACHED();
1927     return nullptr;
1928 }
1929
1930 LayoutPoint RenderLayer::absoluteToContents(const LayoutPoint& absolutePoint) const
1931 {
1932     // We don't use convertToLayerCoords because it doesn't know about transforms
1933     return LayoutPoint(renderer().absoluteToLocal(absolutePoint, UseTransforms));
1934 }
1935
1936 bool RenderLayer::cannotBlitToWindow() const
1937 {
1938     if (isTransparent() || hasReflection() || hasTransform())
1939         return true;
1940     if (!parent())
1941         return false;
1942     return parent()->cannotBlitToWindow();
1943 }
1944
1945 RenderLayer* RenderLayer::transparentPaintingAncestor()
1946 {
1947     if (isComposited())
1948         return nullptr;
1949
1950     for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
1951         if (curr->isComposited())
1952             return nullptr;
1953         if (curr->isTransparent())
1954             return curr;
1955     }
1956     return nullptr;
1957 }
1958
1959 enum TransparencyClipBoxBehavior {
1960     PaintingTransparencyClipBox,
1961     HitTestingTransparencyClipBox
1962 };
1963
1964 enum TransparencyClipBoxMode {
1965     DescendantsOfTransparencyClipBox,
1966     RootOfTransparencyClipBox
1967 };
1968
1969 static LayoutRect transparencyClipBox(const RenderLayer&, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, OptionSet<PaintBehavior> = { });
1970
1971 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer& layer, const RenderLayer* rootLayer,
1972     TransparencyClipBoxBehavior transparencyBehavior, OptionSet<PaintBehavior> paintBehavior)
1973 {
1974     // If we have a mask, then the clip is limited to the border box area (and there is
1975     // no need to examine child layers).
1976     if (!layer.renderer().hasMask()) {
1977         // Note: we don't have to walk z-order lists since transparent elements always establish
1978         // a stacking container. This means we can just walk the layer tree directly.
1979         for (RenderLayer* curr = layer.firstChild(); curr; curr = curr->nextSibling()) {
1980             if (!layer.isReflectionLayer(*curr))
1981                 clipRect.unite(transparencyClipBox(*curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior));
1982         }
1983     }
1984
1985     // If we have a reflection, then we need to account for that when we push the clip.  Reflect our entire
1986     // current transparencyClipBox to catch all child layers.
1987     // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this
1988     // size into the parent layer.
1989     if (layer.renderer().hasReflection()) {
1990         LayoutSize delta = layer.offsetFromAncestor(rootLayer);
1991         clipRect.move(-delta);
1992         clipRect.unite(layer.renderBox()->reflectedRect(clipRect));
1993         clipRect.move(delta);
1994     }
1995 }
1996
1997 static LayoutRect transparencyClipBox(const RenderLayer& layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior,
1998     TransparencyClipBoxMode transparencyMode, OptionSet<PaintBehavior> paintBehavior)
1999 {
2000     // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
2001     // paintDirtyRect, and that should cut down on the amount we have to paint.  Still it
2002     // would be better to respect clips.
2003     
2004     if (rootLayer != &layer && ((transparencyBehavior == PaintingTransparencyClipBox && layer.paintsWithTransform(paintBehavior))
2005         || (transparencyBehavior == HitTestingTransparencyClipBox && layer.hasTransform()))) {
2006         // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
2007         // the transformed layer and all of its children.
2008         RenderLayer::PaginationInclusionMode mode = transparencyBehavior == HitTestingTransparencyClipBox ? RenderLayer::IncludeCompositedPaginatedLayers : RenderLayer::ExcludeCompositedPaginatedLayers;
2009         const RenderLayer* paginationLayer = transparencyMode == DescendantsOfTransparencyClipBox ? layer.enclosingPaginationLayer(mode) : nullptr;
2010         const RenderLayer* rootLayerForTransform = paginationLayer ? paginationLayer : rootLayer;
2011         LayoutSize delta = layer.offsetFromAncestor(rootLayerForTransform);
2012
2013         TransformationMatrix transform;
2014         transform.translate(delta.width(), delta.height());
2015         transform.multiply(*layer.transform());
2016
2017         // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
2018         // paints unfragmented.
2019         LayoutRect clipRect = layer.boundingBox(&layer);
2020         expandClipRectForDescendantsAndReflection(clipRect, layer, &layer, transparencyBehavior, paintBehavior);
2021         layer.renderer().style().filterOutsets().expandRect(clipRect);
2022         LayoutRect result = transform.mapRect(clipRect);
2023         if (!paginationLayer)
2024             return result;
2025         
2026         // We have to break up the transformed extent across our columns.
2027         // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
2028         // get our true bounding box.
2029         auto& enclosingFragmentedFlow = downcast<RenderFragmentedFlow>(paginationLayer->renderer());
2030         result = enclosingFragmentedFlow.fragmentsBoundingBox(result);
2031         result.move(paginationLayer->offsetFromAncestor(rootLayer));
2032         return result;
2033     }
2034     
2035     LayoutRect clipRect = layer.boundingBox(rootLayer, layer.offsetFromAncestor(rootLayer), transparencyBehavior == HitTestingTransparencyClipBox ? RenderLayer::UseFragmentBoxesIncludingCompositing : RenderLayer::UseFragmentBoxesExcludingCompositing);
2036     expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior);
2037     layer.renderer().style().filterOutsets().expandRect(clipRect);
2038
2039     return clipRect;
2040 }
2041
2042 static LayoutRect paintingExtent(const RenderLayer& currentLayer, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, OptionSet<PaintBehavior> paintBehavior)
2043 {
2044     return intersection(transparencyClipBox(currentLayer, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect);
2045 }
2046
2047 void RenderLayer::beginTransparencyLayers(GraphicsContext& context, const LayerPaintingInfo& paintingInfo, const LayoutRect& dirtyRect)
2048 {
2049     if (context.paintingDisabled() || (paintsWithTransparency(paintingInfo.paintBehavior) && m_usedTransparency))
2050         return;
2051
2052     RenderLayer* ancestor = transparentPaintingAncestor();
2053     if (ancestor)
2054         ancestor->beginTransparencyLayers(context, paintingInfo, dirtyRect);
2055     
2056     if (paintsWithTransparency(paintingInfo.paintBehavior)) {
2057         ASSERT(isCSSStackingContext());
2058         m_usedTransparency = true;
2059         context.save();
2060         LayoutRect adjustedClipRect = paintingExtent(*this, paintingInfo.rootLayer, dirtyRect, paintingInfo.paintBehavior);
2061         adjustedClipRect.move(paintingInfo.subpixelOffset);
2062         FloatRect pixelSnappedClipRect = snapRectToDevicePixels(adjustedClipRect, renderer().document().deviceScaleFactor());
2063         context.clip(pixelSnappedClipRect);
2064
2065 #if ENABLE(CSS_COMPOSITING)
2066         bool usesCompositeOperation = hasBlendMode() && !(renderer().isSVGRoot() && parent() && parent()->isRenderViewLayer());
2067         if (usesCompositeOperation)
2068             context.setCompositeOperation(context.compositeOperation(), blendMode());
2069 #endif
2070
2071         context.beginTransparencyLayer(renderer().opacity());
2072
2073 #if ENABLE(CSS_COMPOSITING)
2074         if (usesCompositeOperation)
2075             context.setCompositeOperation(context.compositeOperation(), BlendMode::Normal);
2076 #endif
2077
2078 #ifdef REVEAL_TRANSPARENCY_LAYERS
2079         context.setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f));
2080         context.fillRect(pixelSnappedClipRect);
2081 #endif
2082     }
2083 }
2084
2085 #if PLATFORM(IOS_FAMILY)
2086 void RenderLayer::willBeDestroyed()
2087 {
2088     if (RenderLayerBacking* layerBacking = backing())
2089         layerBacking->layerWillBeDestroyed();
2090 }
2091 #endif
2092
2093 bool RenderLayer::isDescendantOf(const RenderLayer& layer) const
2094 {
2095     for (auto* ancestor = this; ancestor; ancestor = ancestor->parent()) {
2096         if (&layer == ancestor)
2097             return true;
2098     }
2099     return false;
2100 }
2101
2102 void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& roundedLocation, ColumnOffsetAdjustment adjustForColumns) const
2103 {
2104     LayoutPoint location = convertToLayerCoords(ancestorLayer, roundedLocation, adjustForColumns);
2105     roundedLocation = roundedIntPoint(location);
2106 }
2107
2108 // Returns the layer reached on the walk up towards the ancestor.
2109 static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutPoint& location, RenderLayer::ColumnOffsetAdjustment adjustForColumns)
2110 {
2111     ASSERT(ancestorLayer != layer);
2112
2113     const RenderLayerModelObject& renderer = layer->renderer();
2114     auto position = renderer.style().position();
2115
2116     // FIXME: Special casing RenderFragmentedFlow so much for fixed positioning here is not great.
2117     RenderFragmentedFlow* fixedFragmentedFlowContainer = position == PositionType::Fixed ? renderer.enclosingFragmentedFlow() : nullptr;
2118     if (fixedFragmentedFlowContainer && !fixedFragmentedFlowContainer->isOutOfFlowPositioned())
2119         fixedFragmentedFlowContainer = nullptr;
2120
2121     // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in a RenderFragmentedFlow
2122     // may need to be revisited in a future patch.
2123     // If the fixed renderer is inside a RenderFragmentedFlow, we should not compute location using localToAbsolute,
2124     // since localToAbsolute maps the coordinates from named flow to regions coordinates and regions can be
2125     // positioned in a completely different place in the viewport (RenderView).
2126     if (position == PositionType::Fixed && !fixedFragmentedFlowContainer && (!ancestorLayer || ancestorLayer == renderer.view().layer())) {
2127         // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
2128         // localToAbsolute() on the RenderView.
2129         FloatPoint absPos = renderer.localToAbsolute(FloatPoint(), IsFixed);
2130         location += LayoutSize(absPos.x(), absPos.y());
2131         return ancestorLayer;
2132     }
2133
2134     // For the fixed positioned elements inside a render flow thread, we should also skip the code path below
2135     // Otherwise, for the case of ancestorLayer == rootLayer and fixed positioned element child of a transformed
2136     // element in render flow thread, we will hit the fixed positioned container before hitting the ancestor layer.
2137     if (position == PositionType::Fixed && !fixedFragmentedFlowContainer) {
2138         // For a fixed layers, we need to walk up to the root to see if there's a fixed position container
2139         // (e.g. a transformed layer). It's an error to call offsetFromAncestor() across a layer with a transform,
2140         // so we should always find the ancestor at or before we find the fixed position container.
2141         RenderLayer* fixedPositionContainerLayer = nullptr;
2142         bool foundAncestor = false;
2143         for (RenderLayer* currLayer = layer->parent(); currLayer; currLayer = currLayer->parent()) {
2144             if (currLayer == ancestorLayer)
2145                 foundAncestor = true;
2146
2147             if (isContainerForPositioned(*currLayer, PositionType::Fixed)) {
2148                 fixedPositionContainerLayer = currLayer;
2149                 ASSERT_UNUSED(foundAncestor, foundAncestor);
2150                 break;
2151             }
2152         }
2153         
2154         ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least.
2155
2156         if (fixedPositionContainerLayer != ancestorLayer) {
2157             LayoutSize fixedContainerCoords = layer->offsetFromAncestor(fixedPositionContainerLayer);
2158             LayoutSize ancestorCoords = ancestorLayer->offsetFromAncestor(fixedPositionContainerLayer);
2159             location += (fixedContainerCoords - ancestorCoords);
2160             return ancestorLayer;
2161         }
2162     }
2163
2164     if (position == PositionType::Fixed && fixedFragmentedFlowContainer) {
2165         ASSERT(ancestorLayer);
2166         if (ancestorLayer->isOutOfFlowRenderFragmentedFlow()) {
2167             location += toLayoutSize(layer->location());
2168             return ancestorLayer;
2169         }
2170
2171         if (ancestorLayer == renderer.view().layer()) {
2172             // Add location in flow thread coordinates.
2173             location += toLayoutSize(layer->location());
2174
2175             // Add flow thread offset in view coordinates since the view may be scrolled.
2176             FloatPoint absPos = renderer.view().localToAbsolute(FloatPoint(), IsFixed);
2177             location += LayoutSize(absPos.x(), absPos.y());
2178             return ancestorLayer;
2179         }
2180     }
2181
2182     RenderLayer* parentLayer;
2183     if (position == PositionType::Absolute || position == PositionType::Fixed) {
2184         // Do what enclosingAncestorForPosition() does, but check for ancestorLayer along the way.
2185         parentLayer = layer->parent();
2186         bool foundAncestorFirst = false;
2187         while (parentLayer) {
2188             // RenderFragmentedFlow is a positioned container, child of RenderView, positioned at (0,0).
2189             // This implies that, for out-of-flow positioned elements inside a RenderFragmentedFlow,
2190             // we are bailing out before reaching root layer.
2191             if (isContainerForPositioned(*parentLayer, position))
2192                 break;
2193
2194             if (parentLayer == ancestorLayer) {
2195                 foundAncestorFirst = true;
2196                 break;
2197             }
2198
2199             parentLayer = parentLayer->parent();
2200         }
2201
2202         // We should not reach RenderView layer past the RenderFragmentedFlow layer for any
2203         // children of the RenderFragmentedFlow.
2204         if (renderer.enclosingFragmentedFlow() && !layer->isOutOfFlowRenderFragmentedFlow())
2205             ASSERT(parentLayer != renderer.view().layer());
2206
2207         if (foundAncestorFirst) {
2208             // Found ancestorLayer before the abs. positioned container, so compute offset of both relative
2209             // to enclosingAncestorForPosition and subtract.
2210             RenderLayer* positionedAncestor = parentLayer->enclosingAncestorForPosition(position);
2211             LayoutSize thisCoords = layer->offsetFromAncestor(positionedAncestor);
2212             LayoutSize ancestorCoords = ancestorLayer->offsetFromAncestor(positionedAncestor);
2213             location += (thisCoords - ancestorCoords);
2214             return ancestorLayer;
2215         }
2216     } else
2217         parentLayer = layer->parent();
2218     
2219     if (!parentLayer)
2220         return nullptr;
2221
2222     location += toLayoutSize(layer->location());
2223
2224     if (adjustForColumns == RenderLayer::AdjustForColumns) {
2225         if (RenderLayer* parentLayer = layer->parent()) {
2226             if (is<RenderMultiColumnFlow>(parentLayer->renderer())) {
2227                 RenderFragmentContainer* fragment = downcast<RenderMultiColumnFlow>(parentLayer->renderer()).physicalTranslationFromFlowToFragment(location);
2228                 if (fragment)
2229                     location.moveBy(fragment->topLeftLocation() + -parentLayer->renderBox()->topLeftLocation());
2230             }
2231         }
2232     }
2233
2234     return parentLayer;
2235 }
2236
2237 LayoutPoint RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, const LayoutPoint& location, ColumnOffsetAdjustment adjustForColumns) const
2238 {
2239     if (ancestorLayer == this)
2240         return location;
2241
2242     const RenderLayer* currLayer = this;
2243     LayoutPoint locationInLayerCoords = location;
2244     while (currLayer && currLayer != ancestorLayer)
2245         currLayer = accumulateOffsetTowardsAncestor(currLayer, ancestorLayer, locationInLayerCoords, adjustForColumns);
2246     return locationInLayerCoords;
2247 }
2248
2249 LayoutSize RenderLayer::offsetFromAncestor(const RenderLayer* ancestorLayer, ColumnOffsetAdjustment adjustForColumns) const
2250 {
2251     return toLayoutSize(convertToLayerCoords(ancestorLayer, LayoutPoint(), adjustForColumns));
2252 }
2253
2254 bool RenderLayer::canUseCompositedScrolling() const
2255 {
2256     if (renderer().settings().asyncOverflowScrollingEnabled())
2257         return scrollsOverflow();
2258
2259 #if PLATFORM(IOS_FAMILY) && ENABLE(OVERFLOW_SCROLLING_TOUCH)
2260     return scrollsOverflow() && (renderer().style().useTouchOverflowScrolling() || renderer().settings().alwaysUseAcceleratedOverflowScroll());
2261 #else
2262     return false;
2263 #endif
2264 }
2265
2266 bool RenderLayer::hasCompositedScrollableOverflow() const
2267 {
2268     return canUseCompositedScrolling() && (hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
2269 }
2270
2271 #if ENABLE(IOS_TOUCH_EVENTS)
2272 bool RenderLayer::handleTouchEvent(const PlatformTouchEvent& touchEvent)
2273 {
2274     // If we have accelerated scrolling, let the scrolling be handled outside of WebKit.
2275     if (hasCompositedScrollableOverflow())
2276         return false;
2277
2278     return ScrollableArea::handleTouchEvent(touchEvent);
2279 }
2280
2281 void RenderLayer::registerAsTouchEventListenerForScrolling()
2282 {
2283     if (!renderer().element() || m_registeredAsTouchEventListenerForScrolling)
2284         return;
2285     
2286     renderer().document().addTouchEventHandler(*renderer().element());
2287     m_registeredAsTouchEventListenerForScrolling = true;
2288 }
2289
2290 void RenderLayer::unregisterAsTouchEventListenerForScrolling()
2291 {
2292     if (!renderer().element() || !m_registeredAsTouchEventListenerForScrolling)
2293         return;
2294
2295     renderer().document().removeTouchEventHandler(*renderer().element());
2296     m_registeredAsTouchEventListenerForScrolling = false;
2297 }
2298 #endif // ENABLE(IOS_TOUCH_EVENTS)
2299
2300 // FIXME: this is only valid after we've made layers.
2301 bool RenderLayer::usesCompositedScrolling() const
2302 {
2303     return isComposited() && backing()->hasScrollingLayer();
2304 }
2305
2306 // FIXME: this is only valid after we've made layers.
2307 bool RenderLayer::usesAsyncScrolling() const
2308 {
2309     return compositor().useCoordinatedScrollingForLayer(*this);
2310 }
2311
2312 static inline int adjustedScrollDelta(int beginningDelta)
2313 {
2314     // This implemention matches Firefox's.
2315     // http://mxr.mozilla.org/firefox/source/toolkit/content/widgets/browser.xml#856.
2316     const int speedReducer = 12;
2317
2318     int adjustedDelta = beginningDelta / speedReducer;
2319     if (adjustedDelta > 1)
2320         adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(adjustedDelta))) - 1;
2321     else if (adjustedDelta < -1)
2322         adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(-adjustedDelta))) + 1;
2323
2324     return adjustedDelta;
2325 }
2326
2327 static inline IntSize adjustedScrollDelta(const IntSize& delta)
2328 {
2329     return IntSize(adjustedScrollDelta(delta.width()), adjustedScrollDelta(delta.height()));
2330 }
2331
2332 void RenderLayer::panScrollFromPoint(const IntPoint& sourcePoint)
2333 {
2334     IntPoint lastKnownMousePosition = renderer().frame().eventHandler().lastKnownMousePosition();
2335     
2336     // We need to check if the last known mouse position is out of the window. When the mouse is out of the window, the position is incoherent
2337     static IntPoint previousMousePosition;
2338     if (lastKnownMousePosition.x() < 0 || lastKnownMousePosition.y() < 0)
2339         lastKnownMousePosition = previousMousePosition;
2340     else
2341         previousMousePosition = lastKnownMousePosition;
2342
2343     IntSize delta = lastKnownMousePosition - sourcePoint;
2344
2345     if (abs(delta.width()) <= ScrollView::noPanScrollRadius) // at the center we let the space for the icon
2346         delta.setWidth(0);
2347     if (abs(delta.height()) <= ScrollView::noPanScrollRadius)
2348         delta.setHeight(0);
2349
2350     scrollByRecursively(adjustedScrollDelta(delta));
2351 }
2352
2353 // FIXME: unify with the scrollRectToVisible() code below.
2354 void RenderLayer::scrollByRecursively(const IntSize& delta, ScrollableArea** scrolledArea)
2355 {
2356     if (delta.isZero())
2357         return;
2358
2359     bool restrictedByLineClamp = false;
2360     if (renderer().parent())
2361         restrictedByLineClamp = !renderer().parent()->style().lineClamp().isNone();
2362
2363     if (renderer().hasOverflowClip() && !restrictedByLineClamp) {
2364         ScrollOffset newScrollOffset = scrollOffset() + delta;
2365         scrollToOffset(newScrollOffset);
2366         if (scrolledArea)
2367             *scrolledArea = this;
2368
2369         // If this layer can't do the scroll we ask the next layer up that can scroll to try
2370         IntSize remainingScrollOffset = newScrollOffset - scrollOffset();
2371         if (!remainingScrollOffset.isZero() && renderer().parent()) {
2372             if (RenderLayer* scrollableLayer = enclosingScrollableLayer())
2373                 scrollableLayer->scrollByRecursively(remainingScrollOffset, scrolledArea);
2374
2375             renderer().frame().eventHandler().updateAutoscrollRenderer();
2376         }
2377     } else {
2378         // If we are here, we were called on a renderer that can be programmatically scrolled, but doesn't
2379         // have an overflow clip. Which means that it is a document node that can be scrolled.
2380         renderer().view().frameView().scrollBy(delta);
2381         if (scrolledArea)
2382             *scrolledArea = &renderer().view().frameView();
2383
2384         // FIXME: If we didn't scroll the whole way, do we want to try looking at the frames ownerElement? 
2385         // https://bugs.webkit.org/show_bug.cgi?id=28237
2386     }
2387 }
2388
2389 void RenderLayer::setPostLayoutScrollPosition(Optional<ScrollPosition> position)
2390 {
2391     m_postLayoutScrollPosition = position;
2392 }
2393
2394 void RenderLayer::applyPostLayoutScrollPositionIfNeeded()
2395 {
2396     if (!m_postLayoutScrollPosition)
2397         return;
2398
2399     scrollToOffset(scrollOffsetFromPosition(m_postLayoutScrollPosition.value()));
2400     m_postLayoutScrollPosition = WTF::nullopt;
2401 }
2402
2403 void RenderLayer::scrollToXPosition(int x, ScrollType scrollType, ScrollClamping clamping)
2404 {
2405     ScrollPosition position(x, m_scrollPosition.y());
2406     scrollToOffset(scrollOffsetFromPosition(position), scrollType, clamping);
2407 }
2408
2409 void RenderLayer::scrollToYPosition(int y, ScrollType scrollType, ScrollClamping clamping)
2410 {
2411     ScrollPosition position(m_scrollPosition.x(), y);
2412     scrollToOffset(scrollOffsetFromPosition(position), scrollType, clamping);
2413 }
2414
2415 ScrollOffset RenderLayer::clampScrollOffset(const ScrollOffset& scrollOffset) const
2416 {
2417     return scrollOffset.constrainedBetween(IntPoint(), maximumScrollOffset());
2418 }
2419
2420 void RenderLayer::scrollToOffset(const ScrollOffset& scrollOffset, ScrollType scrollType, ScrollClamping clamping)
2421 {
2422     ScrollOffset newScrollOffset = clamping == ScrollClamping::Clamped ? clampScrollOffset(scrollOffset) : scrollOffset;
2423     if (newScrollOffset == this->scrollOffset())
2424         return;
2425
2426     auto previousScrollType = currentScrollType();
2427     setCurrentScrollType(scrollType);
2428
2429     bool handled = false;
2430 #if ENABLE(ASYNC_SCROLLING)
2431     if (ScrollingCoordinator* scrollingCoordinator = page().scrollingCoordinator())
2432         handled = scrollingCoordinator->requestScrollPositionUpdate(*this, scrollPositionFromOffset(scrollOffset));
2433 #endif
2434
2435     if (!handled)
2436         scrollToOffsetWithoutAnimation(newScrollOffset, clamping);
2437
2438     setCurrentScrollType(previousScrollType);
2439 }
2440
2441 void RenderLayer::scrollTo(const ScrollPosition& position)
2442 {
2443     RenderBox* box = renderBox();
2444     if (!box)
2445         return;
2446
2447     LOG_WITH_STREAM(Scrolling, stream << "RenderLayer::scrollTo " << position << " from " << m_scrollPosition << " (is user scroll " << (currentScrollType() == ScrollType::User) << ")");
2448
2449     ScrollPosition newPosition = position;
2450     if (!box->isHTMLMarquee()) {
2451         // Ensure that the dimensions will be computed if they need to be (for overflow:hidden blocks).
2452         if (m_scrollDimensionsDirty)
2453             computeScrollDimensions();
2454 #if PLATFORM(IOS_FAMILY)
2455         if (adjustForIOSCaretWhenScrolling()) {
2456             // FIXME: It's not clear what this code is trying to do. Behavior seems reasonable with it removed.
2457             int maxOffset = scrollWidth() - roundToInt(box->clientWidth());
2458             ScrollOffset newOffset = scrollOffsetFromPosition(newPosition);
2459             int scrollXOffset = newOffset.x();
2460             if (scrollXOffset > maxOffset - caretWidth) {
2461                 scrollXOffset += caretWidth;
2462                 if (scrollXOffset <= caretWidth)
2463                     scrollXOffset = 0;
2464             } else if (scrollXOffset < m_scrollPosition.x() - caretWidth)
2465                 scrollXOffset -= caretWidth;
2466
2467             newOffset.setX(scrollXOffset);
2468             newPosition = scrollPositionFromOffset(newOffset);
2469         }
2470 #endif
2471     }
2472     
2473     if (m_scrollPosition == newPosition) {
2474         // FIXME: Nothing guarantees we get a scrollTo() with an unchanged position at the end of a user gesture.
2475         // The ScrollingCoordinator probably needs to message the main thread when a gesture ends.
2476         if (requiresScrollPositionReconciliation()) {
2477             setNeedsCompositingGeometryUpdate();
2478             updateCompositingLayersAfterScroll();
2479         }
2480         return;
2481     }
2482
2483     m_scrollPosition = newPosition;
2484
2485     RenderView& view = renderer().view();
2486
2487     // Update the positions of our child layers (if needed as only fixed layers should be impacted by a scroll).
2488     // We don't update compositing layers, because we need to do a deep update from the compositing ancestor.
2489     if (!view.frameView().layoutContext().isInRenderTreeLayout()) {
2490         // If we're in the middle of layout, we'll just update layers once layout has finished.
2491         updateLayerPositionsAfterOverflowScroll();
2492
2493         view.frameView().scheduleUpdateWidgetPositions();
2494
2495         if (!m_updatingMarqueePosition) {
2496             // Avoid updating compositing layers if, higher on the stack, we're already updating layer
2497             // positions. Updating layer positions requires a full walk of up-to-date RenderLayers, and
2498             // in this case we're still updating their positions; we'll update compositing layers later
2499             // when that completes.
2500             if (usesCompositedScrolling()) {
2501                 setNeedsCompositingGeometryUpdate();
2502                 setDescendantsNeedUpdateBackingAndHierarchyTraversal();
2503             }
2504
2505             updateCompositingLayersAfterScroll();
2506         }
2507
2508         // Update regions, scrolling may change the clip of a particular region.
2509         renderer().document().invalidateRenderingDependentRegions(Document::AnnotationsAction::Update);
2510         DebugPageOverlays::didLayout(renderer().frame());
2511     }
2512
2513     Frame& frame = renderer().frame();
2514     RenderLayerModelObject* repaintContainer = renderer().containerForRepaint();
2515     // The caret rect needs to be invalidated after scrolling
2516     frame.selection().setCaretRectNeedsUpdate();
2517     
2518     LayoutRect rectForRepaint = renderer().hasRepaintLayoutRects() ? renderer().repaintLayoutRects().m_repaintRect : renderer().clippedOverflowRectForRepaint(repaintContainer);
2519
2520     FloatQuad quadForFakeMouseMoveEvent = FloatQuad(rectForRepaint);
2521     if (repaintContainer)
2522         quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
2523     frame.eventHandler().dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
2524
2525     bool requiresRepaint = true;
2526     if (usesCompositedScrolling()) {
2527         setNeedsCompositingGeometryUpdate();
2528         setDescendantsNeedUpdateBackingAndHierarchyTraversal();
2529         requiresRepaint = false;
2530     }
2531
2532     // Just schedule a full repaint of our object.
2533     if (requiresRepaint)
2534         renderer().repaintUsingContainer(repaintContainer, rectForRepaint);
2535
2536     // Schedule the scroll and scroll-related DOM events.
2537     if (Element* element = renderer().element())
2538         element->document().eventQueue().enqueueOrDispatchScrollEvent(*element);
2539
2540     if (scrollsOverflow())
2541         view.frameView().didChangeScrollOffset();
2542
2543     view.frameView().viewportContentsChanged();
2544 }
2545
2546 static inline bool frameElementAndViewPermitScroll(HTMLFrameElementBase* frameElementBase, FrameView& frameView)
2547 {
2548     // If scrollbars aren't explicitly forbidden, permit scrolling.
2549     if (frameElementBase && frameElementBase->scrollingMode() != ScrollbarAlwaysOff)
2550         return true;
2551
2552     // If scrollbars are forbidden, user initiated scrolls should obviously be ignored.
2553     if (frameView.wasScrolledByUser())
2554         return false;
2555
2556     // Forbid autoscrolls when scrollbars are off, but permits other programmatic scrolls,
2557     // like navigation to an anchor.
2558     return !frameView.frame().eventHandler().autoscrollInProgress();
2559 }
2560
2561 bool RenderLayer::allowsCurrentScroll() const
2562 {
2563     if (!renderer().hasOverflowClip())
2564         return false;
2565
2566     // Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
2567     // FIXME: Is this still needed? It used to be relevant for Safari RSS.
2568     if (renderer().parent() && !renderer().parent()->style().lineClamp().isNone())
2569         return false;
2570
2571     RenderBox* box = renderBox();
2572     ASSERT(box); // Only boxes can have overflowClip set.
2573
2574     if (renderer().frame().eventHandler().autoscrollInProgress()) {
2575         // The "programmatically" here is misleading; this asks whether the box has scrollable overflow,
2576         // or is a special case like a form control.
2577         return box->canBeProgramaticallyScrolled();
2578     }
2579
2580     // Programmatic scrolls can scroll overflow:hidden.
2581     return box->hasHorizontalOverflow() || box->hasVerticalOverflow();
2582 }
2583
2584 void RenderLayer::scrollRectToVisible(const LayoutRect& absoluteRect, bool insideFixed, const ScrollRectToVisibleOptions& options)
2585 {
2586     LOG_WITH_STREAM(Scrolling, stream << "Layer " << this << " scrollRectToVisible " << absoluteRect);
2587
2588     RenderLayer* parentLayer = nullptr;
2589     LayoutRect newRect = absoluteRect;
2590
2591     // We may end up propagating a scroll event. It is important that we suspend events until 
2592     // the end of the function since they could delete the layer or the layer's renderer().
2593     FrameView& frameView = renderer().view().frameView();
2594
2595     if (renderer().parent())
2596         parentLayer = renderer().parent()->enclosingLayer();
2597
2598     if (allowsCurrentScroll()) {
2599         // Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
2600         // This will prevent us from revealing text hidden by the slider in Safari RSS.
2601         RenderBox* box = renderBox();
2602         ASSERT(box);
2603         LayoutRect localExposeRect(box->absoluteToLocalQuad(FloatQuad(FloatRect(absoluteRect))).boundingBox());
2604         LayoutRect layerBounds(0_lu, 0_lu, box->clientWidth(), box->clientHeight());
2605         LayoutRect revealRect = getRectToExpose(layerBounds, localExposeRect, insideFixed, options.alignX, options.alignY);
2606
2607         ScrollOffset clampedScrollOffset = clampScrollOffset(scrollOffset() + toIntSize(roundedIntRect(revealRect).location()));
2608         if (clampedScrollOffset != scrollOffset()) {
2609             ScrollOffset oldScrollOffset = scrollOffset();
2610             scrollToOffset(clampedScrollOffset);
2611             IntSize scrollOffsetDifference = scrollOffset() - oldScrollOffset;
2612             localExposeRect.move(-scrollOffsetDifference);
2613             newRect = LayoutRect(box->localToAbsoluteQuad(FloatQuad(FloatRect(localExposeRect)), UseTransforms).boundingBox());
2614         }
2615     } else if (!parentLayer && renderer().isRenderView()) {
2616         HTMLFrameOwnerElement* ownerElement = renderer().document().ownerElement();
2617
2618         if (ownerElement && ownerElement->renderer()) {
2619             HTMLFrameElementBase* frameElementBase = nullptr;
2620
2621             if (is<HTMLFrameElementBase>(*ownerElement))
2622                 frameElementBase = downcast<HTMLFrameElementBase>(ownerElement);
2623
2624             if (frameElementAndViewPermitScroll(frameElementBase, frameView)) {
2625                 // If this assertion fires we need to protect the ownerElement from being destroyed.
2626                 ScriptDisallowedScope::InMainThread scriptDisallowedScope;
2627
2628                 LayoutRect viewRect = frameView.visibleContentRect(LegacyIOSDocumentVisibleRect);
2629                 LayoutRect exposeRect = getRectToExpose(viewRect, absoluteRect, insideFixed, options.alignX, options.alignY);
2630
2631                 IntPoint scrollOffset(roundedIntPoint(exposeRect.location()));
2632                 // Adjust offsets if they're outside of the allowable range.
2633                 scrollOffset = scrollOffset.constrainedBetween(IntPoint(), IntPoint(frameView.contentsSize()));
2634                 frameView.setScrollPosition(scrollOffset);
2635
2636                 if (options.shouldAllowCrossOriginScrolling == ShouldAllowCrossOriginScrolling::Yes || frameView.safeToPropagateScrollToParent()) {
2637                     parentLayer = ownerElement->renderer()->enclosingLayer();
2638                     // Convert the rect into the coordinate space of the parent frame's document.
2639                     newRect = frameView.contentsToContainingViewContents(enclosingIntRect(newRect));
2640                     insideFixed = false; // FIXME: ideally need to determine if this <iframe> is inside position:fixed.
2641                 } else
2642                     parentLayer = nullptr;
2643             }
2644         } else {
2645             if (options.revealMode == SelectionRevealMode::RevealUpToMainFrame && frameView.frame().isMainFrame())
2646                 return;
2647
2648             auto minScrollPosition = frameView.minimumScrollPosition();
2649             auto maxScrollPosition = frameView.maximumScrollPosition();
2650
2651 #if !PLATFORM(IOS_FAMILY)
2652             LayoutRect viewRect = frameView.visibleContentRect();
2653 #else
2654             // FIXME: ContentInsets should be taken care of in UI process side.
2655             // To do that, getRectToExpose needs to return the additional scrolling to do beyond content rect.
2656             LayoutRect viewRect = frameView.visualViewportRectExpandedByContentInsets();
2657
2658             auto contentInsets = page().contentInsets();
2659             minScrollPosition.move(-contentInsets.left(), -contentInsets.top());
2660             maxScrollPosition.move(contentInsets.right(), contentInsets.bottom());
2661 #endif
2662             // Move the target rect into "scrollView contents" coordinates.
2663             LayoutRect targetRect = absoluteRect;
2664             targetRect.move(0, frameView.headerHeight());
2665
2666             LayoutRect revealRect = getRectToExpose(viewRect, targetRect, insideFixed, options.alignX, options.alignY);
2667             ScrollOffset clampedScrollPosition = roundedIntPoint(revealRect.location()).constrainedBetween(minScrollPosition, maxScrollPosition);
2668             frameView.setScrollPosition(clampedScrollPosition);
2669
2670             // This is the outermost view of a web page, so after scrolling this view we
2671             // scroll its container by calling Page::scrollRectIntoView.
2672             // This only has an effect on the Mac platform in applications
2673             // that put web views into scrolling containers, such as Mac OS X Mail.
2674             // The canAutoscroll function in EventHandler also knows about this.
2675             page().chrome().scrollRectIntoView(snappedIntRect(absoluteRect));
2676         }
2677     }
2678     
2679     if (parentLayer)
2680         parentLayer->scrollRectToVisible(newRect, insideFixed, options);
2681 }
2682
2683 void RenderLayer::updateCompositingLayersAfterScroll()
2684 {
2685     if (compositor().hasContentCompositingLayers()) {
2686         // Our stacking container is guaranteed to contain all of our descendants that may need
2687         // repositioning, so update compositing layers from there.
2688         if (RenderLayer* compositingAncestor = stackingContext()->enclosingCompositingLayer()) {
2689             if (usesCompositedScrolling())
2690                 compositor().updateCompositingLayers(CompositingUpdateType::OnCompositedScroll, compositingAncestor);
2691             else {
2692                 // FIXME: would be nice to only dirty layers whose positions were affected by scrolling.
2693                 compositingAncestor->setDescendantsNeedUpdateBackingAndHierarchyTraversal();
2694                 compositor().updateCompositingLayers(CompositingUpdateType::OnScroll, compositingAncestor);
2695             }
2696         }
2697     }
2698 }
2699
2700 LayoutRect RenderLayer::getRectToExpose(const LayoutRect& visibleRect, const LayoutRect& exposeRect, bool insideFixed, const ScrollAlignment& alignX, const ScrollAlignment& alignY) const
2701 {
2702     FrameView& frameView = renderer().view().frameView();
2703     if (renderer().isRenderView() && insideFixed) {
2704         // If the element is inside position:fixed and we're not scaled, no amount of scrolling is going to move things around.
2705         if (frameView.frameScaleFactor() == 1)
2706             return visibleRect;
2707
2708         if (renderer().settings().visualViewportEnabled()) {
2709             // exposeRect is in absolute coords, affected by page scale. Unscale it.
2710             LayoutRect unscaledExposeRect = exposeRect;
2711             unscaledExposeRect.scale(1 / frameView.frameScaleFactor());
2712             unscaledExposeRect.move(0, -frameView.headerHeight());
2713
2714             // These are both in unscaled coordinates.
2715             LayoutRect layoutViewport = frameView.layoutViewportRect();
2716             LayoutRect visualViewport = frameView.visualViewportRect();
2717
2718             // The rect to expose may be partially offscreen, which we can't do anything about with position:fixed.
2719             unscaledExposeRect.intersect(layoutViewport);
2720             // Make sure it's not larger than the visual viewport; if so, we'll just move to the top left.
2721             unscaledExposeRect.setSize(unscaledExposeRect.size().shrunkTo(visualViewport.size()));
2722
2723             // Compute how much we have to move the visualViewport to reveal the part of the layoutViewport that contains exposeRect.
2724             LayoutRect requiredVisualViewport = getRectToExpose(visualViewport, unscaledExposeRect, false, alignX, alignY);
2725             // Scale it back up.
2726             requiredVisualViewport.scale(frameView.frameScaleFactor());
2727             requiredVisualViewport.move(0, frameView.headerHeight());
2728             return requiredVisualViewport;
2729         }
2730     }
2731
2732     // Determine the appropriate X behavior.
2733     ScrollAlignment::Behavior scrollX;
2734     LayoutRect exposeRectX(exposeRect.x(), visibleRect.y(), exposeRect.width(), visibleRect.height());
2735     LayoutUnit intersectWidth = intersection(visibleRect, exposeRectX).width();
2736     if (intersectWidth == exposeRect.width() || intersectWidth >= MIN_INTERSECT_FOR_REVEAL)
2737         // If the rectangle is fully visible, use the specified visible behavior.
2738         // If the rectangle is partially visible, but over a certain threshold,
2739         // then treat it as fully visible to avoid unnecessary horizontal scrolling
2740         scrollX = ScrollAlignment::getVisibleBehavior(alignX);
2741     else if (intersectWidth == visibleRect.width()) {
2742         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
2743         scrollX = ScrollAlignment::getVisibleBehavior(alignX);
2744         if (scrollX == ScrollAlignment::Behavior::AlignCenter)
2745             scrollX = ScrollAlignment::Behavior::NoScroll;
2746     } else if (intersectWidth > 0)
2747         // If the rectangle is partially visible, but not above the minimum threshold, use the specified partial behavior
2748         scrollX = ScrollAlignment::getPartialBehavior(alignX);
2749     else
2750         scrollX = ScrollAlignment::getHiddenBehavior(alignX);
2751     // If we're trying to align to the closest edge, and the exposeRect is further right
2752     // than the visibleRect, and not bigger than the visible area, then align with the right.
2753     if (scrollX == ScrollAlignment::Behavior::AlignToClosestEdge && exposeRect.maxX() > visibleRect.maxX() && exposeRect.width() < visibleRect.width())
2754         scrollX = ScrollAlignment::Behavior::AlignRight;
2755
2756     // Given the X behavior, compute the X coordinate.
2757     LayoutUnit x;
2758     if (scrollX == ScrollAlignment::Behavior::NoScroll)
2759         x = visibleRect.x();
2760     else if (scrollX == ScrollAlignment::Behavior::AlignRight)
2761         x = exposeRect.maxX() - visibleRect.width();
2762     else if (scrollX == ScrollAlignment::Behavior::AlignCenter)
2763         x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2;
2764     else
2765         x = exposeRect.x();
2766
2767     // Determine the appropriate Y behavior.
2768     ScrollAlignment::Behavior scrollY;
2769     LayoutRect exposeRectY(visibleRect.x(), exposeRect.y(), visibleRect.width(), exposeRect.height());
2770     LayoutUnit intersectHeight = intersection(visibleRect, exposeRectY).height();
2771     if (intersectHeight == exposeRect.height())
2772         // If the rectangle is fully visible, use the specified visible behavior.
2773         scrollY = ScrollAlignment::getVisibleBehavior(alignY);
2774     else if (intersectHeight == visibleRect.height()) {
2775         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
2776         scrollY = ScrollAlignment::getVisibleBehavior(alignY);
2777         if (scrollY == ScrollAlignment::Behavior::AlignCenter)
2778             scrollY = ScrollAlignment::Behavior::NoScroll;
2779     } else if (intersectHeight > 0)
2780         // If the rectangle is partially visible, use the specified partial behavior
2781         scrollY = ScrollAlignment::getPartialBehavior(alignY);
2782     else
2783         scrollY = ScrollAlignment::getHiddenBehavior(alignY);
2784     // If we're trying to align to the closest edge, and the exposeRect is further down
2785     // than the visibleRect, and not bigger than the visible area, then align with the bottom.
2786     if (scrollY == ScrollAlignment::Behavior::AlignToClosestEdge && exposeRect.maxY() > visibleRect.maxY() && exposeRect.height() < visibleRect.height())
2787         scrollY = ScrollAlignment::Behavior::AlignBottom;
2788
2789     // Given the Y behavior, compute the Y coordinate.
2790     LayoutUnit y;
2791     if (scrollY == ScrollAlignment::Behavior::NoScroll)
2792         y = visibleRect.y();
2793     else if (scrollY == ScrollAlignment::Behavior::AlignBottom)
2794         y = exposeRect.maxY() - visibleRect.height();
2795     else if (scrollY == ScrollAlignment::Behavior::AlignCenter)
2796         y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2;
2797     else
2798         y = exposeRect.y();
2799
2800     return LayoutRect(LayoutPoint(x, y), visibleRect.size());
2801 }
2802
2803 void RenderLayer::autoscroll(const IntPoint& positionInWindow)
2804 {
2805     IntPoint currentDocumentPosition = renderer().view().frameView().windowToContents(positionInWindow);
2806     scrollRectToVisible(LayoutRect(currentDocumentPosition, LayoutSize(1, 1)), false, { SelectionRevealMode::Reveal, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded, ShouldAllowCrossOriginScrolling::Yes });
2807 }
2808
2809 bool RenderLayer::canResize() const
2810 {
2811     // We need a special case for <iframe> because they never have
2812     // hasOverflowClip(). However, they do "implicitly" clip their contents, so
2813     // we want to allow resizing them also.
2814     return (renderer().hasOverflowClip() || renderer().isRenderIFrame()) && renderer().style().resize() != Resize::None;
2815 }
2816
2817 void RenderLayer::resize(const PlatformMouseEvent& evt, const LayoutSize& oldOffset)
2818 {
2819     // FIXME: This should be possible on generated content but is not right now.
2820     if (!inResizeMode() || !canResize() || !renderer().element())
2821         return;
2822
2823     // FIXME: The only case where renderer->element()->renderer() != renderer is with continuations. Do they matter here?
2824     // If they do it would still be better to deal with them explicitly.
2825     Element* element = renderer().element();
2826     auto* renderer = downcast<RenderBox>(element->renderer());
2827
2828     Document& document = element->document();
2829     if (!document.frame()->eventHandler().mousePressed())
2830         return;
2831
2832     float zoomFactor = renderer->style().effectiveZoom();
2833
2834     LayoutSize newOffset = offsetFromResizeCorner(document.view()->windowToContents(evt.position()));
2835     newOffset.setWidth(newOffset.width() / zoomFactor);
2836     newOffset.setHeight(newOffset.height() / zoomFactor);
2837     
2838     LayoutSize currentSize = LayoutSize(renderer->width() / zoomFactor, renderer->height() / zoomFactor);
2839     LayoutSize minimumSize = element->minimumSizeForResizing().shrunkTo(currentSize);
2840     element->setMinimumSizeForResizing(minimumSize);
2841     
2842     LayoutSize adjustedOldOffset = LayoutSize(oldOffset.width() / zoomFactor, oldOffset.height() / zoomFactor);
2843     if (shouldPlaceBlockDirectionScrollbarOnLeft()) {
2844         newOffset.setWidth(-newOffset.width());
2845         adjustedOldOffset.setWidth(-adjustedOldOffset.width());
2846     }
2847     
2848     LayoutSize difference = (currentSize + newOffset - adjustedOldOffset).expandedTo(minimumSize) - currentSize;
2849
2850     StyledElement* styledElement = downcast<StyledElement>(element);
2851     bool isBoxSizingBorder = renderer->style().boxSizing() == BoxSizing::BorderBox;
2852
2853     Resize resize = renderer->style().resize();
2854     if (resize != Resize::Vertical && difference.width()) {
2855         if (is<HTMLFormControlElement>(*element)) {
2856             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
2857             styledElement->setInlineStyleProperty(CSSPropertyMarginLeft, renderer->marginLeft() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2858             styledElement->setInlineStyleProperty(CSSPropertyMarginRight, renderer->marginRight() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2859         }
2860         LayoutUnit baseWidth = renderer->width() - (isBoxSizingBorder ? 0_lu : renderer->horizontalBorderAndPaddingExtent());
2861         baseWidth = baseWidth / zoomFactor;
2862         styledElement->setInlineStyleProperty(CSSPropertyWidth, roundToInt(baseWidth + difference.width()), CSSPrimitiveValue::CSS_PX);
2863     }
2864
2865     if (resize != Resize::Horizontal && difference.height()) {
2866         if (is<HTMLFormControlElement>(*element)) {
2867             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
2868             styledElement->setInlineStyleProperty(CSSPropertyMarginTop, renderer->marginTop() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2869             styledElement->setInlineStyleProperty(CSSPropertyMarginBottom, renderer->marginBottom() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2870         }
2871         LayoutUnit baseHeight = renderer->height() - (isBoxSizingBorder ? 0_lu : renderer->verticalBorderAndPaddingExtent());
2872         baseHeight = baseHeight / zoomFactor;
2873         styledElement->setInlineStyleProperty(CSSPropertyHeight, roundToInt(baseHeight + difference.height()), CSSPrimitiveValue::CSS_PX);
2874     }
2875
2876     document.updateLayout();
2877
2878     // FIXME (Radar 4118564): We should also autoscroll the window as necessary to keep the point under the cursor in view.
2879 }
2880
2881 int RenderLayer::scrollSize(ScrollbarOrientation orientation) const
2882 {
2883     Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_hBar : m_vBar).get();
2884     return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
2885 }
2886
2887 void RenderLayer::setScrollOffset(const ScrollOffset& offset)
2888 {
2889     scrollTo(scrollPositionFromOffset(offset));
2890 }
2891
2892 int RenderLayer::scrollOffset(ScrollbarOrientation orientation) const
2893 {
2894     if (orientation == HorizontalScrollbar)
2895         return scrollOffset().x();
2896
2897     if (orientation == VerticalScrollbar)
2898         return scrollOffset().y();
2899
2900     return 0;
2901 }
2902
2903 ScrollingNodeID RenderLayer::scrollingNodeID() const
2904 {
2905     if (!isComposited())
2906         return 0;
2907
2908     return backing()->scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling);
2909 }
2910
2911 IntRect RenderLayer::visibleContentRectInternal(VisibleContentRectIncludesScrollbars scrollbarInclusion, VisibleContentRectBehavior) const
2912 {
2913     IntSize scrollbarSpace;
2914     if (showsOverflowControls() && scrollbarInclusion == IncludeScrollbars)
2915         scrollbarSpace = scrollbarIntrusion();
2916     
2917     auto visibleSize = this->visibleSize();
2918     return { scrollPosition(), { std::max(0, visibleSize.width() - scrollbarSpace.width()), std::max(0, visibleSize.height() - scrollbarSpace.height()) } };
2919 }
2920
2921 IntSize RenderLayer::overhangAmount() const
2922 {
2923 #if ENABLE(RUBBER_BANDING)
2924     if (!renderer().settings().rubberBandingForSubScrollableRegionsEnabled())
2925         return IntSize();
2926
2927     IntSize stretch;
2928
2929     // FIXME: use maximumScrollOffset(), or just move this to ScrollableArea.
2930     ScrollOffset scrollOffset = scrollOffsetFromPosition(scrollPosition());
2931     auto reachableSize = reachableTotalContentsSize();
2932     if (scrollOffset.y() < 0)
2933         stretch.setHeight(scrollOffset.y());
2934     else if (reachableSize.height() && scrollOffset.y() > reachableSize.height() - visibleHeight())
2935         stretch.setHeight(scrollOffset.y() - (reachableSize.height() - visibleHeight()));
2936
2937     if (scrollOffset.x() < 0)
2938         stretch.setWidth(scrollOffset.x());
2939     else if (reachableSize.width() && scrollOffset.x() > reachableSize.width() - visibleWidth())
2940         stretch.setWidth(scrollOffset.x() - (reachableSize.width() - visibleWidth()));
2941
2942     return stretch;
2943 #else
2944     return IntSize();
2945 #endif
2946 }
2947
2948 bool RenderLayer::isActive() const
2949 {
2950     return page().focusController().isActive();
2951 }
2952
2953 static int cornerStart(const RenderLayer& layer, int minX, int maxX, int thickness)
2954 {
2955     if (layer.shouldPlaceBlockDirectionScrollbarOnLeft())
2956         return minX + layer.renderer().style().borderLeftWidth();
2957     return maxX - thickness - layer.renderer().style().borderRightWidth();
2958 }
2959
2960 static LayoutRect cornerRect(const RenderLayer& layer, const LayoutRect& bounds)
2961 {
2962     int horizontalThickness;
2963     int verticalThickness;
2964     if (!layer.verticalScrollbar() && !layer.horizontalScrollbar()) {
2965         // FIXME: This isn't right.  We need to know the thickness of custom scrollbars
2966         // even when they don't exist in order to set the resizer square size properly.
2967         horizontalThickness = ScrollbarTheme::theme().scrollbarThickness();
2968         verticalThickness = horizontalThickness;
2969     } else if (layer.verticalScrollbar() && !layer.horizontalScrollbar()) {
2970         horizontalThickness = layer.verticalScrollbar()->width();
2971         verticalThickness = horizontalThickness;
2972     } else if (layer.horizontalScrollbar() && !layer.verticalScrollbar()) {
2973         verticalThickness = layer.horizontalScrollbar()->height();
2974         horizontalThickness = verticalThickness;
2975     } else {
2976         horizontalThickness = layer.verticalScrollbar()->width();
2977         verticalThickness = layer.horizontalScrollbar()->height();
2978     }
2979     return LayoutRect(cornerStart(layer, bounds.x(), bounds.maxX(), horizontalThickness),
2980         bounds.maxY() - verticalThickness - layer.renderer().style().borderBottomWidth(),
2981         horizontalThickness, verticalThickness);
2982 }
2983
2984 IntRect RenderLayer::scrollCornerRect() const
2985 {
2986     // We have a scrollbar corner when a non overlay scrollbar is visible and not filling the entire length of the box.
2987     // This happens when:
2988     // (a) A resizer is present and at least one non overlay scrollbar is present
2989     // (b) Both non overlay scrollbars are present.
2990     // Overlay scrollbars always fill the entire length of the box so we never have scroll corner in that case.
2991     bool hasHorizontalBar = m_hBar && !m_hBar->isOverlayScrollbar();
2992     bool hasVerticalBar = m_vBar && !m_vBar->isOverlayScrollbar();
2993     bool hasResizer = renderer().style().resize() != Resize::None;
2994     if ((hasHorizontalBar && hasVerticalBar) || (hasResizer && (hasHorizontalBar || hasVerticalBar)))
2995         return snappedIntRect(cornerRect(*this, renderBox()->borderBoxRect()));
2996     return IntRect();
2997 }
2998
2999 static LayoutRect resizerCornerRect(const RenderLayer& layer, const LayoutRect& bounds)
3000 {
3001     ASSERT(layer.renderer().isBox());
3002     if (layer.renderer().style().resize() == Resize::None)
3003         return LayoutRect();
3004     return cornerRect(layer, bounds);
3005 }
3006
3007 LayoutRect RenderLayer::scrollCornerAndResizerRect() const
3008 {
3009     RenderBox* box = renderBox();
3010     if (!box)
3011         return LayoutRect();
3012     LayoutRect scrollCornerAndResizer = scrollCornerRect();
3013     if (scrollCornerAndResizer.isEmpty())
3014         scrollCornerAndResizer = resizerCornerRect(*this, box->borderBoxRect());
3015     return scrollCornerAndResizer;
3016 }
3017
3018 bool RenderLayer::isScrollCornerVisible() const
3019 {
3020     ASSERT(renderer().isBox());
3021     return !scrollCornerRect().isEmpty();
3022 }
3023
3024 IntRect RenderLayer::convertFromScrollbarToContainingView(const Scrollbar& scrollbar, const IntRect& scrollbarRect) const
3025 {
3026     IntRect rect = scrollbarRect;
3027     rect.move(scrollbarOffset(scrollbar));
3028
3029     return renderer().view().frameView().convertFromRendererToContainingView(&renderer(), rect);
3030 }
3031
3032 IntRect RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar& scrollbar, const IntRect& parentRect) const
3033 {
3034     IntRect rect = renderer().view().frameView().convertFromContainingViewToRenderer(&renderer(), parentRect);
3035     rect.move(-scrollbarOffset(scrollbar));
3036     return rect;
3037 }
3038
3039 IntPoint RenderLayer::convertFromScrollbarToContainingView(const Scrollbar& scrollbar, const IntPoint& scrollbarPoint) const
3040 {
3041     IntPoint point = scrollbarPoint;
3042     point.move(scrollbarOffset(scrollbar));
3043     return renderer().view().frameView().convertFromRendererToContainingView(&renderer(), point);
3044 }
3045
3046 IntPoint RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar& scrollbar, const IntPoint& parentPoint) const
3047 {
3048     IntPoint point = renderer().view().frameView().convertFromContainingViewToRenderer(&renderer(), parentPoint);
3049     point.move(-scrollbarOffset(scrollbar));
3050     return point;
3051 }
3052
3053 IntSize RenderLayer::visibleSize() const
3054 {
3055     RenderBox* box = renderBox();
3056     if (!box)
3057         return IntSize();
3058
3059     return IntSize(roundToInt(box->clientWidth()), roundToInt(box->clientHeight()));
3060 }
3061
3062 IntSize RenderLayer::contentsSize() const
3063 {
3064     return IntSize(scrollWidth(), scrollHeight());
3065 }
3066
3067 IntSize RenderLayer::reachableTotalContentsSize() const
3068 {
3069     IntSize contentsSize = this->contentsSize();
3070
3071     if (!hasScrollableHorizontalOverflow())
3072         contentsSize.setWidth(std::min(contentsSize.width(), visibleSize().width()));
3073
3074     if (!hasScrollableVerticalOverflow())
3075         contentsSize.setHeight(std::min(contentsSize.height(), visibleSize().height()));
3076
3077     return contentsSize;
3078 }
3079
3080 void RenderLayer::availableContentSizeChanged(AvailableSizeChangeReason reason)
3081 {
3082     ScrollableArea::availableContentSizeChanged(reason);
3083
3084     if (reason == AvailableSizeChangeReason::ScrollbarsChanged) {
3085         if (is<RenderBlock>(renderer()))
3086             downcast<RenderBlock>(renderer()).setShouldForceRelayoutChildren(true);
3087         renderer().setNeedsLayout();
3088     }
3089 }
3090
3091 bool RenderLayer::shouldSuspendScrollAnimations() const
3092 {
3093     return renderer().view().frameView().shouldSuspendScrollAnimations();
3094 }
3095
3096 #if PLATFORM(IOS_FAMILY)
3097 void RenderLayer::didStartScroll()
3098 {
3099     page().chrome().client().didStartOverflowScroll();
3100 }
3101
3102 void RenderLayer::didEndScroll()
3103 {
3104     page().chrome().client().didEndOverflowScroll();
3105 }
3106     
3107 void RenderLayer::didUpdateScroll()
3108 {
3109     // Send this notification when we scroll, since this is how we keep selection updated.
3110     page().chrome().client().didLayout(ChromeClient::Scroll);
3111 }
3112 #endif
3113
3114 IntPoint RenderLayer::lastKnownMousePosition() const
3115 {
3116     return renderer().frame().eventHandler().lastKnownMousePosition();
3117 }
3118
3119 bool RenderLayer::isHandlingWheelEvent() const
3120 {
3121     return renderer().frame().eventHandler().isHandlingWheelEvent();
3122 }
3123
3124 IntRect RenderLayer::rectForHorizontalScrollbar(const IntRect& borderBoxRect) const
3125 {
3126     if (!m_hBar)
3127         return IntRect();
3128
3129     const RenderBox* box = renderBox();
3130     const IntRect& scrollCorner = scrollCornerRect();
3131
3132     return IntRect(horizontalScrollbarStart(borderBoxRect.x()),
3133         borderBoxRect.maxY() - box->borderBottom() - m_hBar->height(),
3134         borderBoxRect.width() - (box->borderLeft() + box->borderRight()) - scrollCorner.width(),
3135         m_hBar->height());
3136 }
3137
3138 IntRect RenderLayer::rectForVerticalScrollbar(const IntRect& borderBoxRect) const
3139 {
3140     if (!m_vBar)
3141         return IntRect();
3142
3143     const RenderBox* box = renderBox();
3144     const IntRect& scrollCorner = scrollCornerRect();
3145
3146     return IntRect(verticalScrollbarStart(borderBoxRect.x(), borderBoxRect.maxX()),
3147         borderBoxRect.y() + box->borderTop(),
3148         m_vBar->width(),
3149         borderBoxRect.height() - (box->borderTop() + box->borderBottom()) - scrollCorner.height());
3150 }
3151
3152 LayoutUnit RenderLayer::verticalScrollbarStart(int minX, int maxX) const
3153 {
3154     const RenderBox* box = renderBox();
3155     if (shouldPlaceBlockDirectionScrollbarOnLeft())
3156         return minX + box->borderLeft();
3157     return maxX - box->borderRight() - m_vBar->width();
3158 }
3159
3160 LayoutUnit RenderLayer::horizontalScrollbarStart(int minX) const
3161 {
3162     const RenderBox* box = renderBox();
3163     int x = minX + box->borderLeft();
3164     if (shouldPlaceBlockDirectionScrollbarOnLeft())
3165         x += m_vBar ? m_vBar->width() : roundToInt(resizerCornerRect(*this, box->borderBoxRect()).width());
3166     return x;
3167 }
3168
3169 IntSize RenderLayer::scrollbarOffset(const Scrollbar& scrollbar) const
3170 {
3171     RenderBox* box = renderBox();
3172
3173     if (&scrollbar == m_vBar.get())
3174         return IntSize(verticalScrollbarStart(0, box->width()), box->borderTop());
3175
3176     if (&scrollbar == m_hBar.get())
3177         return IntSize(horizontalScrollbarStart(0), box->height() - box->borderBottom() - scrollbar.height());
3178     
3179     ASSERT_NOT_REACHED();
3180     return IntSize();
3181 }
3182
3183 void RenderLayer::invalidateScrollbarRect(Scrollbar& scrollbar, const IntRect& rect)
3184 {
3185     if (!showsOverflowControls())
3186         return;
3187
3188     if (&scrollbar == m_vBar.get()) {
3189         if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
3190             layer->setNeedsDisplayInRect(rect);
3191             return;
3192         }
3193     } else {
3194         if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
3195             layer->setNeedsDisplayInRect(rect);
3196             return;
3197         }
3198     }
3199
3200     IntRect scrollRect = rect;
3201     RenderBox* box = renderBox();
3202     ASSERT(box);
3203     // If we are not yet inserted into the tree, there is no need to repaint.
3204     if (!box->parent())
3205         return;
3206
3207     if (&scrollbar == m_vBar.get())
3208         scrollRect.move(verticalScrollbarStart(0, box->width()), box->borderTop());
3209     else
3210         scrollRect.move(horizontalScrollbarStart(0), box->height() - box->borderBottom() - scrollbar.height());
3211     LayoutRect repaintRect = scrollRect;
3212     renderBox()->flipForWritingMode(repaintRect);
3213     renderer().repaintRectangle(repaintRect);
3214 }
3215
3216 void RenderLayer::invalidateScrollCornerRect(const IntRect& rect)
3217 {
3218     if (!showsOverflowControls())
3219         return;
3220
3221     if (GraphicsLayer* layer = layerForScrollCorner()) {
3222         layer->setNeedsDisplayInRect(rect);
3223         return;
3224     }
3225
3226     if (m_scrollCorner)
3227         m_scrollCorner->repaintRectangle(rect);
3228     if (m_resizer)
3229         m_resizer->repaintRectangle(rect);
3230 }
3231
3232 static bool scrollbarHiddenByStyle(Scrollbar* scrollbar)
3233 {
3234     if (!scrollbar || !scrollbar->isCustomScrollbar())
3235         return false;
3236
3237     std::unique_ptr<RenderStyle> scrollbarStyle = static_cast<RenderScrollbar*>(scrollbar)->getScrollbarPseudoStyle(ScrollbarBGPart, PseudoId::Scrollbar);
3238
3239     return scrollbarStyle && scrollbarStyle->display() == DisplayType::None;
3240 }
3241
3242 bool RenderLayer::horizontalScrollbarHiddenByStyle() const
3243 {
3244     return scrollbarHiddenByStyle(horizontalScrollbar());
3245 }
3246
3247 bool RenderLayer::verticalScrollbarHiddenByStyle() const
3248 {
3249     return scrollbarHiddenByStyle(verticalScrollbar());
3250 }
3251
3252 static inline RenderElement* rendererForScrollbar(RenderLayerModelObject& renderer)
3253 {
3254     if (Element* element = renderer.element()) {
3255         if (ShadowRoot* shadowRoot = element->containingShadowRoot()) {
3256             if (shadowRoot->mode() == ShadowRootMode::UserAgent)
3257                 return shadowRoot->host()->renderer();
3258         }
3259     }
3260
3261     return &renderer;
3262 }
3263
3264 Ref<Scrollbar> RenderLayer::createScrollbar(ScrollbarOrientation orientation)
3265 {
3266     RefPtr<Scrollbar> widget;
3267     ASSERT(rendererForScrollbar(renderer()));
3268     auto& actualRenderer = *rendererForScrollbar(renderer());
3269     bool hasCustomScrollbarStyle = is<RenderBox>(actualRenderer) && downcast<RenderBox>(actualRenderer).style().hasPseudoStyle(PseudoId::Scrollbar);
3270     if (hasCustomScrollbarStyle)
3271         widget = RenderScrollbar::createCustomScrollbar(*this, orientation, downcast<RenderBox>(actualRenderer).element());
3272     else {
3273         widget = Scrollbar::createNativeScrollbar(*this, orientation, RegularScrollbar);
3274         didAddScrollbar(widget.get(), orientation);
3275         if (page().expectsWheelEventTriggers())
3276             scrollAnimator().setWheelEventTestTrigger(page().testTrigger());
3277     }
3278     renderer().view().frameView().addChild(*widget);
3279     return widget.releaseNonNull();
3280 }
3281
3282 void RenderLayer::destroyScrollbar(ScrollbarOrientation orientation)
3283 {
3284     RefPtr<Scrollbar>& scrollbar = orientation == HorizontalScrollbar ? m_hBar : m_vBar;
3285     if (!scrollbar)
3286         return;
3287
3288     if (!scrollbar->isCustomScrollbar())
3289         willRemoveScrollbar(scrollbar.get(), orientation);
3290
3291     scrollbar->removeFromParent();
3292     scrollbar = nullptr;
3293 }
3294
3295 bool RenderLayer::scrollsOverflow() const
3296 {
3297     if (!is<RenderBox>(renderer()))
3298         return false;
3299
3300     return downcast<RenderBox>(renderer()).scrollsOverflow();
3301 }
3302
3303 void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
3304 {
3305     if (hasScrollbar == hasHorizontalScrollbar())
3306         return;
3307
3308     if (hasScrollbar) {
3309         m_hBar = createScrollbar(HorizontalScrollbar);
3310 #if ENABLE(RUBBER_BANDING)
3311         ScrollElasticity elasticity = scrollsOverflow() && renderer().settings().rubberBandingForSubScrollableRegionsEnabled() ? ScrollElasticityAutomatic : ScrollElasticityNone;
3312         ScrollableArea::setHorizontalScrollElasticity(elasticity);
3313 #endif
3314     } else {
3315         destroyScrollbar(HorizontalScrollbar);
3316 #if ENABLE(RUBBER_BANDING)
3317         ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityNone);
3318 #endif
3319     }
3320
3321     // Destroying or creating one bar can cause our scrollbar corner to come and go.  We need to update the opposite scrollbar's style.
3322     if (m_hBar)
3323         m_hBar->styleChanged();
3324     if (m_vBar)
3325         m_vBar->styleChanged();
3326
3327     renderer().document().invalidateScrollbarDependentRegions();
3328 }
3329
3330 void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
3331 {
3332     if (hasScrollbar == hasVerticalScrollbar())
3333         return;
3334
3335     if (hasScrollbar) {
3336         m_vBar = createScrollbar(VerticalScrollbar);
3337 #if ENABLE(RUBBER_BANDING)
3338         ScrollElasticity elasticity = scrollsOverflow() && renderer().settings().rubberBandingForSubScrollableRegionsEnabled() ? ScrollElasticityAutomatic : ScrollElasticityNone;
3339         ScrollableArea::setVerticalScrollElasticity(elasticity);
3340 #endif
3341     } else {
3342         destroyScrollbar(VerticalScrollbar);
3343 #if ENABLE(RUBBER_BANDING)
3344         ScrollableArea::setVerticalScrollElasticity(ScrollElasticityNone);
3345 #endif
3346     }
3347
3348      // Destroying or creating one bar can cause our scrollbar corner to come and go.  We need to update the opposite scrollbar's style.
3349     if (m_hBar)
3350         m_hBar->styleChanged();
3351     if (m_vBar)
3352         m_vBar->styleChanged();
3353
3354     renderer().document().invalidateScrollbarDependentRegions();
3355 }
3356
3357 ScrollableArea* RenderLayer::enclosingScrollableArea() const
3358 {
3359     if (RenderLayer* scrollableLayer = enclosingScrollableLayer())
3360         return scrollableLayer;
3361
3362     // FIXME: We should return the frame view here (or possibly an ancestor frame view,
3363     // if the frame view isn't scrollable.
3364     return nullptr;
3365 }
3366
3367 bool RenderLayer::isScrollableOrRubberbandable()
3368 {
3369     return renderer().isScrollableOrRubberbandableBox();
3370 }
3371
3372 bool RenderLayer::hasScrollableOrRubberbandableAncestor()
3373 {
3374     for (RenderLayer* nextLayer = parentLayerCrossFrame(*this); nextLayer; nextLayer = parentLayerCrossFrame(*nextLayer)) {
3375         if (nextLayer->isScrollableOrRubberbandable())
3376             return true;
3377     }
3378
3379     return false;
3380 }
3381
3382 bool RenderLayer::useDarkAppearance() const
3383 {
3384     return renderer().useDarkAppearance();
3385 }
3386
3387 #if ENABLE(CSS_SCROLL_SNAP)
3388 void RenderLayer::updateSnapOffsets()
3389 {
3390     // FIXME: Extend support beyond HTMLElements.
3391     if (!is<HTMLElement>(enclosingElement()) || !enclosingElement()->renderBox())
3392         return;
3393
3394     RenderBox* box = enclosingElement()->renderBox();
3395     updateSnapOffsetsForScrollableArea(*this, *downcast<HTMLElement>(enclosingElement()), *box, box->style());
3396 }
3397
3398 bool RenderLayer::isScrollSnapInProgress() const
3399 {
3400     if (!scrollsOverflow())
3401         return false;
3402     
3403     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
3404         return scrollAnimator->isScrollSnapInProgress();
3405     
3406     return false;
3407 }
3408 #endif
3409
3410 bool RenderLayer::usesMockScrollAnimator() const
3411 {
3412     return DeprecatedGlobalSettings::usesMockScrollAnimator();
3413 }
3414
3415 void RenderLayer::logMockScrollAnimatorMessage(const String& message) const
3416 {
3417     renderer().document().addConsoleMessage(MessageSource::Other, MessageLevel::Debug, "RenderLayer: " + message);
3418 }
3419
3420 int RenderLayer::verticalScrollbarWidth(OverlayScrollbarSizeRelevancy relevancy) const