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