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