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