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