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