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