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