REGRESSION (r246899): Subtitles show twice when controls show/hide on hulu.com
[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         clearClipRectsIncludingDescendants();
1801
1802     m_backingProviderLayer = makeWeakPtr(backingProvider);
1803 }
1804
1805 void RenderLayer::disconnectFromBackingProviderLayer()
1806 {
1807     if (!m_backingProviderLayer)
1808         return;
1809     
1810     ASSERT(m_backingProviderLayer->isComposited());
1811     if (m_backingProviderLayer->isComposited())
1812         m_backingProviderLayer->backing()->removeBackingSharingLayer(*this);
1813 }
1814
1815 bool compositedWithOwnBackingStore(const RenderLayer& layer)
1816 {
1817     return layer.isComposited() && !layer.backing()->paintsIntoCompositedAncestor();
1818 }
1819
1820 RenderLayer* RenderLayer::enclosingCompositingLayer(IncludeSelfOrNot includeSelf) const
1821 {
1822     if (includeSelf == IncludeSelf && isComposited())
1823         return const_cast<RenderLayer*>(this);
1824
1825     for (const RenderLayer* curr = paintOrderParent(); curr; curr = curr->paintOrderParent()) {
1826         if (curr->isComposited())
1827             return const_cast<RenderLayer*>(curr);
1828     }
1829          
1830     return nullptr;
1831 }
1832
1833 RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(IncludeSelfOrNot includeSelf) const
1834 {
1835     auto repaintTargetForLayer = [](const RenderLayer& layer) -> RenderLayer* {
1836         if (compositedWithOwnBackingStore(layer))
1837             return const_cast<RenderLayer*>(&layer);
1838         
1839         if (layer.paintsIntoProvidedBacking())
1840             return layer.backingProviderLayer();
1841         
1842         return nullptr;
1843     };
1844
1845     RenderLayer* repaintTarget = nullptr;
1846     if (includeSelf == IncludeSelf && (repaintTarget = repaintTargetForLayer(*this)))
1847         return repaintTarget;
1848
1849     for (const RenderLayer* curr = paintOrderParent(); curr; curr = curr->paintOrderParent()) {
1850         if ((repaintTarget = repaintTargetForLayer(*curr)))
1851             return repaintTarget;
1852     }
1853          
1854     return nullptr;
1855 }
1856
1857 RenderLayer* RenderLayer::enclosingFilterLayer(IncludeSelfOrNot includeSelf) const
1858 {
1859     const RenderLayer* curr = (includeSelf == IncludeSelf) ? this : parent();
1860     for (; curr; curr = curr->parent()) {
1861         if (curr->requiresFullLayerImageForFilters())
1862             return const_cast<RenderLayer*>(curr);
1863     }
1864     
1865     return nullptr;
1866 }
1867
1868 RenderLayer* RenderLayer::enclosingFilterRepaintLayer() const
1869 {
1870     for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
1871         if ((curr != this && curr->requiresFullLayerImageForFilters()) || compositedWithOwnBackingStore(*curr) || curr->isRenderViewLayer())
1872             return const_cast<RenderLayer*>(curr);
1873     }
1874     return nullptr;
1875 }
1876
1877 // FIXME: This neeeds a better name.
1878 void RenderLayer::setFilterBackendNeedsRepaintingInRect(const LayoutRect& rect)
1879 {
1880     ASSERT(requiresFullLayerImageForFilters());
1881     ASSERT(m_filters);
1882
1883     if (rect.isEmpty())
1884         return;
1885     
1886     LayoutRect rectForRepaint = rect;
1887     renderer().style().filterOutsets().expandRect(rectForRepaint);
1888
1889     m_filters->expandDirtySourceRect(rectForRepaint);
1890     
1891     RenderLayer* parentLayer = enclosingFilterRepaintLayer();
1892     ASSERT(parentLayer);
1893     FloatQuad repaintQuad(rectForRepaint);
1894     LayoutRect parentLayerRect = renderer().localToContainerQuad(repaintQuad, &parentLayer->renderer()).enclosingBoundingBox();
1895
1896     if (parentLayer->isComposited()) {
1897         if (!parentLayer->backing()->paintsIntoWindow()) {
1898             parentLayer->setBackingNeedsRepaintInRect(parentLayerRect);
1899             return;
1900         }
1901         // If the painting goes to window, redirect the painting to the parent RenderView.
1902         parentLayer = renderer().view().layer();
1903         parentLayerRect = renderer().localToContainerQuad(repaintQuad, &parentLayer->renderer()).enclosingBoundingBox();
1904     }
1905
1906     if (parentLayer->paintsWithFilters()) {
1907         parentLayer->setFilterBackendNeedsRepaintingInRect(parentLayerRect);
1908         return;        
1909     }
1910     
1911     if (parentLayer->isRenderViewLayer()) {
1912         downcast<RenderView>(parentLayer->renderer()).repaintViewRectangle(parentLayerRect);
1913         return;
1914     }
1915     
1916     ASSERT_NOT_REACHED();
1917 }
1918
1919 bool RenderLayer::hasAncestorWithFilterOutsets() const
1920 {
1921     for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
1922         if (curr->renderer().style().hasFilterOutsets())
1923             return true;
1924     }
1925     return false;
1926 }
1927
1928 RenderLayer* RenderLayer::clippingRootForPainting() const
1929 {
1930     if (isComposited())
1931         return const_cast<RenderLayer*>(this);
1932
1933     if (paintsIntoProvidedBacking())
1934         return backingProviderLayer();
1935
1936     const RenderLayer* current = this;
1937     while (current) {
1938         if (current->isRenderViewLayer())
1939             return const_cast<RenderLayer*>(current);
1940
1941         current = current->paintOrderParent();
1942         ASSERT(current);
1943         if (current->transform() || compositedWithOwnBackingStore(*current))
1944             return const_cast<RenderLayer*>(current);
1945
1946         if (current->paintsIntoProvidedBacking())
1947             return current->backingProviderLayer();
1948     }
1949
1950     ASSERT_NOT_REACHED();
1951     return nullptr;
1952 }
1953
1954 LayoutPoint RenderLayer::absoluteToContents(const LayoutPoint& absolutePoint) const
1955 {
1956     // We don't use convertToLayerCoords because it doesn't know about transforms
1957     return LayoutPoint(renderer().absoluteToLocal(absolutePoint, UseTransforms));
1958 }
1959
1960 bool RenderLayer::cannotBlitToWindow() const
1961 {
1962     if (isTransparent() || hasReflection() || hasTransform())
1963         return true;
1964     if (!parent())
1965         return false;
1966     return parent()->cannotBlitToWindow();
1967 }
1968
1969 RenderLayer* RenderLayer::transparentPaintingAncestor()
1970 {
1971     if (isComposited())
1972         return nullptr;
1973
1974     for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
1975         if (curr->isComposited())
1976             return nullptr;
1977         if (curr->isTransparent())
1978             return curr;
1979     }
1980     return nullptr;
1981 }
1982
1983 enum TransparencyClipBoxBehavior {
1984     PaintingTransparencyClipBox,
1985     HitTestingTransparencyClipBox
1986 };
1987
1988 enum TransparencyClipBoxMode {
1989     DescendantsOfTransparencyClipBox,
1990     RootOfTransparencyClipBox
1991 };
1992
1993 static LayoutRect transparencyClipBox(const RenderLayer&, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, OptionSet<PaintBehavior> = { });
1994
1995 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer& layer, const RenderLayer* rootLayer,
1996     TransparencyClipBoxBehavior transparencyBehavior, OptionSet<PaintBehavior> paintBehavior)
1997 {
1998     // If we have a mask, then the clip is limited to the border box area (and there is
1999     // no need to examine child layers).
2000     if (!layer.renderer().hasMask()) {
2001         // Note: we don't have to walk z-order lists since transparent elements always establish
2002         // a stacking container. This means we can just walk the layer tree directly.
2003         for (RenderLayer* curr = layer.firstChild(); curr; curr = curr->nextSibling()) {
2004             if (!layer.isReflectionLayer(*curr))
2005                 clipRect.unite(transparencyClipBox(*curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior));
2006         }
2007     }
2008
2009     // If we have a reflection, then we need to account for that when we push the clip.  Reflect our entire
2010     // current transparencyClipBox to catch all child layers.
2011     // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this
2012     // size into the parent layer.
2013     if (layer.renderer().hasReflection()) {
2014         LayoutSize delta = layer.offsetFromAncestor(rootLayer);
2015         clipRect.move(-delta);
2016         clipRect.unite(layer.renderBox()->reflectedRect(clipRect));
2017         clipRect.move(delta);
2018     }
2019 }
2020
2021 static LayoutRect transparencyClipBox(const RenderLayer& layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior,
2022     TransparencyClipBoxMode transparencyMode, OptionSet<PaintBehavior> paintBehavior)
2023 {
2024     // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
2025     // paintDirtyRect, and that should cut down on the amount we have to paint.  Still it
2026     // would be better to respect clips.
2027     
2028     if (rootLayer != &layer && ((transparencyBehavior == PaintingTransparencyClipBox && layer.paintsWithTransform(paintBehavior))
2029         || (transparencyBehavior == HitTestingTransparencyClipBox && layer.hasTransform()))) {
2030         // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
2031         // the transformed layer and all of its children.
2032         RenderLayer::PaginationInclusionMode mode = transparencyBehavior == HitTestingTransparencyClipBox ? RenderLayer::IncludeCompositedPaginatedLayers : RenderLayer::ExcludeCompositedPaginatedLayers;
2033         const RenderLayer* paginationLayer = transparencyMode == DescendantsOfTransparencyClipBox ? layer.enclosingPaginationLayer(mode) : nullptr;
2034         const RenderLayer* rootLayerForTransform = paginationLayer ? paginationLayer : rootLayer;
2035         LayoutSize delta = layer.offsetFromAncestor(rootLayerForTransform);
2036
2037         TransformationMatrix transform;
2038         transform.translate(delta.width(), delta.height());
2039         transform.multiply(*layer.transform());
2040
2041         // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
2042         // paints unfragmented.
2043         LayoutRect clipRect = layer.boundingBox(&layer);
2044         expandClipRectForDescendantsAndReflection(clipRect, layer, &layer, transparencyBehavior, paintBehavior);
2045         layer.renderer().style().filterOutsets().expandRect(clipRect);
2046         LayoutRect result = transform.mapRect(clipRect);
2047         if (!paginationLayer)
2048             return result;
2049         
2050         // We have to break up the transformed extent across our columns.
2051         // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
2052         // get our true bounding box.
2053         auto& enclosingFragmentedFlow = downcast<RenderFragmentedFlow>(paginationLayer->renderer());
2054         result = enclosingFragmentedFlow.fragmentsBoundingBox(result);
2055         result.move(paginationLayer->offsetFromAncestor(rootLayer));
2056         return result;
2057     }
2058     
2059     LayoutRect clipRect = layer.boundingBox(rootLayer, layer.offsetFromAncestor(rootLayer), transparencyBehavior == HitTestingTransparencyClipBox ? RenderLayer::UseFragmentBoxesIncludingCompositing : RenderLayer::UseFragmentBoxesExcludingCompositing);
2060     expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior);
2061     layer.renderer().style().filterOutsets().expandRect(clipRect);
2062
2063     return clipRect;
2064 }
2065
2066 static LayoutRect paintingExtent(const RenderLayer& currentLayer, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, OptionSet<PaintBehavior> paintBehavior)
2067 {
2068     return intersection(transparencyClipBox(currentLayer, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect);
2069 }
2070
2071 void RenderLayer::beginTransparencyLayers(GraphicsContext& context, const LayerPaintingInfo& paintingInfo, const LayoutRect& dirtyRect)
2072 {
2073     if (context.paintingDisabled() || (paintsWithTransparency(paintingInfo.paintBehavior) && m_usedTransparency))
2074         return;
2075
2076     RenderLayer* ancestor = transparentPaintingAncestor();
2077     if (ancestor)
2078         ancestor->beginTransparencyLayers(context, paintingInfo, dirtyRect);
2079     
2080     if (paintsWithTransparency(paintingInfo.paintBehavior)) {
2081         ASSERT(isCSSStackingContext());
2082         m_usedTransparency = true;
2083         context.save();
2084         LayoutRect adjustedClipRect = paintingExtent(*this, paintingInfo.rootLayer, dirtyRect, paintingInfo.paintBehavior);
2085         adjustedClipRect.move(paintingInfo.subpixelOffset);
2086         FloatRect pixelSnappedClipRect = snapRectToDevicePixels(adjustedClipRect, renderer().document().deviceScaleFactor());
2087         context.clip(pixelSnappedClipRect);
2088
2089 #if ENABLE(CSS_COMPOSITING)
2090         bool usesCompositeOperation = hasBlendMode() && !(renderer().isSVGRoot() && parent() && parent()->isRenderViewLayer());
2091         if (usesCompositeOperation)
2092             context.setCompositeOperation(context.compositeOperation(), blendMode());
2093 #endif
2094
2095         context.beginTransparencyLayer(renderer().opacity());
2096
2097 #if ENABLE(CSS_COMPOSITING)
2098         if (usesCompositeOperation)
2099             context.setCompositeOperation(context.compositeOperation(), BlendMode::Normal);
2100 #endif
2101
2102 #ifdef REVEAL_TRANSPARENCY_LAYERS
2103         context.setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f));
2104         context.fillRect(pixelSnappedClipRect);
2105 #endif
2106     }
2107 }
2108
2109 #if PLATFORM(IOS_FAMILY)
2110 void RenderLayer::willBeDestroyed()
2111 {
2112     if (RenderLayerBacking* layerBacking = backing())
2113         layerBacking->layerWillBeDestroyed();
2114 }
2115 #endif
2116
2117 bool RenderLayer::isDescendantOf(const RenderLayer& layer) const
2118 {
2119     for (auto* ancestor = this; ancestor; ancestor = ancestor->parent()) {
2120         if (&layer == ancestor)
2121             return true;
2122     }
2123     return false;
2124 }
2125
2126 void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& roundedLocation, ColumnOffsetAdjustment adjustForColumns) const
2127 {
2128     LayoutPoint location = convertToLayerCoords(ancestorLayer, roundedLocation, adjustForColumns);
2129     roundedLocation = roundedIntPoint(location);
2130 }
2131
2132 // Returns the layer reached on the walk up towards the ancestor.
2133 static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutPoint& location, RenderLayer::ColumnOffsetAdjustment adjustForColumns)
2134 {
2135     ASSERT(ancestorLayer != layer);
2136
2137     const RenderLayerModelObject& renderer = layer->renderer();
2138     auto position = renderer.style().position();
2139
2140     // FIXME: Special casing RenderFragmentedFlow so much for fixed positioning here is not great.
2141     RenderFragmentedFlow* fixedFragmentedFlowContainer = position == PositionType::Fixed ? renderer.enclosingFragmentedFlow() : nullptr;
2142     if (fixedFragmentedFlowContainer && !fixedFragmentedFlowContainer->isOutOfFlowPositioned())
2143         fixedFragmentedFlowContainer = nullptr;
2144
2145     // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in a RenderFragmentedFlow
2146     // may need to be revisited in a future patch.
2147     // If the fixed renderer is inside a RenderFragmentedFlow, we should not compute location using localToAbsolute,
2148     // since localToAbsolute maps the coordinates from named flow to regions coordinates and regions can be
2149     // positioned in a completely different place in the viewport (RenderView).
2150     if (position == PositionType::Fixed && !fixedFragmentedFlowContainer && (!ancestorLayer || ancestorLayer == renderer.view().layer())) {
2151         // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
2152         // localToAbsolute() on the RenderView.
2153         FloatPoint absPos = renderer.localToAbsolute(FloatPoint(), IsFixed);
2154         location += LayoutSize(absPos.x(), absPos.y());
2155         return ancestorLayer;
2156     }
2157
2158     // For the fixed positioned elements inside a render flow thread, we should also skip the code path below
2159     // Otherwise, for the case of ancestorLayer == rootLayer and fixed positioned element child of a transformed
2160     // element in render flow thread, we will hit the fixed positioned container before hitting the ancestor layer.
2161     if (position == PositionType::Fixed && !fixedFragmentedFlowContainer) {
2162         // For a fixed layers, we need to walk up to the root to see if there's a fixed position container
2163         // (e.g. a transformed layer). It's an error to call offsetFromAncestor() across a layer with a transform,
2164         // so we should always find the ancestor at or before we find the fixed position container.
2165         RenderLayer* fixedPositionContainerLayer = nullptr;
2166         bool foundAncestor = false;
2167         for (RenderLayer* currLayer = layer->parent(); currLayer; currLayer = currLayer->parent()) {
2168             if (currLayer == ancestorLayer)
2169                 foundAncestor = true;
2170
2171             if (isContainerForPositioned(*currLayer, PositionType::Fixed)) {
2172                 fixedPositionContainerLayer = currLayer;
2173                 ASSERT_UNUSED(foundAncestor, foundAncestor);
2174                 break;
2175             }
2176         }
2177         
2178         ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least.
2179
2180         if (fixedPositionContainerLayer != ancestorLayer) {
2181             LayoutSize fixedContainerCoords = layer->offsetFromAncestor(fixedPositionContainerLayer);
2182             LayoutSize ancestorCoords = ancestorLayer->offsetFromAncestor(fixedPositionContainerLayer);
2183             location += (fixedContainerCoords - ancestorCoords);
2184             return ancestorLayer;
2185         }
2186     }
2187
2188     if (position == PositionType::Fixed && fixedFragmentedFlowContainer) {
2189         ASSERT(ancestorLayer);
2190         if (ancestorLayer->isOutOfFlowRenderFragmentedFlow()) {
2191             location += toLayoutSize(layer->location());
2192             return ancestorLayer;
2193         }
2194
2195         if (ancestorLayer == renderer.view().layer()) {
2196             // Add location in flow thread coordinates.
2197             location += toLayoutSize(layer->location());
2198
2199             // Add flow thread offset in view coordinates since the view may be scrolled.
2200             FloatPoint absPos = renderer.view().localToAbsolute(FloatPoint(), IsFixed);
2201             location += LayoutSize(absPos.x(), absPos.y());
2202             return ancestorLayer;
2203         }
2204     }
2205
2206     RenderLayer* parentLayer;
2207     if (position == PositionType::Absolute || position == PositionType::Fixed) {
2208         // Do what enclosingAncestorForPosition() does, but check for ancestorLayer along the way.
2209         parentLayer = layer->parent();
2210         bool foundAncestorFirst = false;
2211         while (parentLayer) {
2212             // RenderFragmentedFlow is a positioned container, child of RenderView, positioned at (0,0).
2213             // This implies that, for out-of-flow positioned elements inside a RenderFragmentedFlow,
2214             // we are bailing out before reaching root layer.
2215             if (isContainerForPositioned(*parentLayer, position))
2216                 break;
2217
2218             if (parentLayer == ancestorLayer) {
2219                 foundAncestorFirst = true;
2220                 break;
2221             }
2222
2223             parentLayer = parentLayer->parent();
2224         }
2225
2226         // We should not reach RenderView layer past the RenderFragmentedFlow layer for any
2227         // children of the RenderFragmentedFlow.
2228         if (renderer.enclosingFragmentedFlow() && !layer->isOutOfFlowRenderFragmentedFlow())
2229             ASSERT(parentLayer != renderer.view().layer());
2230
2231         if (foundAncestorFirst) {
2232             // Found ancestorLayer before the abs. positioned container, so compute offset of both relative
2233             // to enclosingAncestorForPosition and subtract.
2234             RenderLayer* positionedAncestor = parentLayer->enclosingAncestorForPosition(position);
2235             LayoutSize thisCoords = layer->offsetFromAncestor(positionedAncestor);
2236             LayoutSize ancestorCoords = ancestorLayer->offsetFromAncestor(positionedAncestor);
2237             location += (thisCoords - ancestorCoords);
2238             return ancestorLayer;
2239         }
2240     } else
2241         parentLayer = layer->parent();
2242     
2243     if (!parentLayer)
2244         return nullptr;
2245
2246     location += toLayoutSize(layer->location());
2247
2248     if (adjustForColumns == RenderLayer::AdjustForColumns) {
2249         if (RenderLayer* parentLayer = layer->parent()) {
2250             if (is<RenderMultiColumnFlow>(parentLayer->renderer())) {
2251                 RenderFragmentContainer* fragment = downcast<RenderMultiColumnFlow>(parentLayer->renderer()).physicalTranslationFromFlowToFragment(location);
2252                 if (fragment)
2253                     location.moveBy(fragment->topLeftLocation() + -parentLayer->renderBox()->topLeftLocation());
2254             }
2255         }
2256     }
2257
2258     return parentLayer;
2259 }
2260
2261 LayoutPoint RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, const LayoutPoint& location, ColumnOffsetAdjustment adjustForColumns) const
2262 {
2263     if (ancestorLayer == this)
2264         return location;
2265
2266     const RenderLayer* currLayer = this;
2267     LayoutPoint locationInLayerCoords = location;
2268     while (currLayer && currLayer != ancestorLayer)
2269         currLayer = accumulateOffsetTowardsAncestor(currLayer, ancestorLayer, locationInLayerCoords, adjustForColumns);
2270     return locationInLayerCoords;
2271 }
2272
2273 LayoutSize RenderLayer::offsetFromAncestor(const RenderLayer* ancestorLayer, ColumnOffsetAdjustment adjustForColumns) const
2274 {
2275     return toLayoutSize(convertToLayerCoords(ancestorLayer, LayoutPoint(), adjustForColumns));
2276 }
2277
2278 bool RenderLayer::canUseCompositedScrolling() const
2279 {
2280     bool isVisible = renderer().style().visibility() == Visibility::Visible;
2281     if (renderer().settings().asyncOverflowScrollingEnabled())
2282         return isVisible && scrollsOverflow();
2283
2284 #if PLATFORM(IOS_FAMILY) && ENABLE(OVERFLOW_SCROLLING_TOUCH)
2285     return isVisible && scrollsOverflow() && (renderer().style().useTouchOverflowScrolling() || renderer().settings().alwaysUseAcceleratedOverflowScroll());
2286 #else
2287     return false;
2288 #endif
2289 }
2290
2291 bool RenderLayer::hasCompositedScrollableOverflow() const
2292 {
2293     return canUseCompositedScrolling() && (hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
2294 }
2295
2296 #if ENABLE(IOS_TOUCH_EVENTS)
2297 bool RenderLayer::handleTouchEvent(const PlatformTouchEvent& touchEvent)
2298 {
2299     // If we have accelerated scrolling, let the scrolling be handled outside of WebKit.
2300     if (hasCompositedScrollableOverflow())
2301         return false;
2302
2303     return ScrollableArea::handleTouchEvent(touchEvent);
2304 }
2305
2306 void RenderLayer::registerAsTouchEventListenerForScrolling()
2307 {
2308     if (!renderer().element() || m_registeredAsTouchEventListenerForScrolling)
2309         return;
2310     
2311     renderer().document().addTouchEventHandler(*renderer().element());
2312     m_registeredAsTouchEventListenerForScrolling = true;
2313 }
2314
2315 void RenderLayer::unregisterAsTouchEventListenerForScrolling()
2316 {
2317     if (!renderer().element() || !m_registeredAsTouchEventListenerForScrolling)
2318         return;
2319
2320     renderer().document().removeTouchEventHandler(*renderer().element());
2321     m_registeredAsTouchEventListenerForScrolling = false;
2322 }
2323 #endif // ENABLE(IOS_TOUCH_EVENTS)
2324
2325 // FIXME: this is only valid after we've made layers.
2326 bool RenderLayer::usesCompositedScrolling() const
2327 {
2328     return isComposited() && backing()->hasScrollingLayer();
2329 }
2330
2331 // FIXME: this is only valid after we've made layers.
2332 bool RenderLayer::usesAsyncScrolling() const
2333 {
2334     return compositor().useCoordinatedScrollingForLayer(*this);
2335 }
2336
2337 static inline int adjustedScrollDelta(int beginningDelta)
2338 {
2339     // This implemention matches Firefox's.
2340     // http://mxr.mozilla.org/firefox/source/toolkit/content/widgets/browser.xml#856.
2341     const int speedReducer = 12;
2342
2343     int adjustedDelta = beginningDelta / speedReducer;
2344     if (adjustedDelta > 1)
2345         adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(adjustedDelta))) - 1;
2346     else if (adjustedDelta < -1)
2347         adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(-adjustedDelta))) + 1;
2348
2349     return adjustedDelta;
2350 }
2351
2352 static inline IntSize adjustedScrollDelta(const IntSize& delta)
2353 {
2354     return IntSize(adjustedScrollDelta(delta.width()), adjustedScrollDelta(delta.height()));
2355 }
2356
2357 void RenderLayer::panScrollFromPoint(const IntPoint& sourcePoint)
2358 {
2359     IntPoint lastKnownMousePosition = renderer().frame().eventHandler().lastKnownMousePosition();
2360     
2361     // 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
2362     static IntPoint previousMousePosition;
2363     if (lastKnownMousePosition.x() < 0 || lastKnownMousePosition.y() < 0)
2364         lastKnownMousePosition = previousMousePosition;
2365     else
2366         previousMousePosition = lastKnownMousePosition;
2367
2368     IntSize delta = lastKnownMousePosition - sourcePoint;
2369
2370     if (abs(delta.width()) <= ScrollView::noPanScrollRadius) // at the center we let the space for the icon
2371         delta.setWidth(0);
2372     if (abs(delta.height()) <= ScrollView::noPanScrollRadius)
2373         delta.setHeight(0);
2374
2375     scrollByRecursively(adjustedScrollDelta(delta));
2376 }
2377
2378 // FIXME: unify with the scrollRectToVisible() code below.
2379 void RenderLayer::scrollByRecursively(const IntSize& delta, ScrollableArea** scrolledArea)
2380 {
2381     if (delta.isZero())
2382         return;
2383
2384     bool restrictedByLineClamp = false;
2385     if (renderer().parent())
2386         restrictedByLineClamp = !renderer().parent()->style().lineClamp().isNone();
2387
2388     if (renderer().hasOverflowClip() && !restrictedByLineClamp) {
2389         ScrollOffset newScrollOffset = scrollOffset() + delta;
2390         scrollToOffset(newScrollOffset);
2391         if (scrolledArea)
2392             *scrolledArea = this;
2393
2394         // If this layer can't do the scroll we ask the next layer up that can scroll to try
2395         IntSize remainingScrollOffset = newScrollOffset - scrollOffset();
2396         if (!remainingScrollOffset.isZero() && renderer().parent()) {
2397             if (RenderLayer* scrollableLayer = enclosingScrollableLayer())
2398                 scrollableLayer->scrollByRecursively(remainingScrollOffset, scrolledArea);
2399
2400             renderer().frame().eventHandler().updateAutoscrollRenderer();
2401         }
2402     } else {
2403         // If we are here, we were called on a renderer that can be programmatically scrolled, but doesn't
2404         // have an overflow clip. Which means that it is a document node that can be scrolled.
2405         renderer().view().frameView().scrollBy(delta);
2406         if (scrolledArea)
2407             *scrolledArea = &renderer().view().frameView();
2408
2409         // FIXME: If we didn't scroll the whole way, do we want to try looking at the frames ownerElement? 
2410         // https://bugs.webkit.org/show_bug.cgi?id=28237
2411     }
2412 }
2413
2414 void RenderLayer::setPostLayoutScrollPosition(Optional<ScrollPosition> position)
2415 {
2416     m_postLayoutScrollPosition = position;
2417 }
2418
2419 void RenderLayer::applyPostLayoutScrollPositionIfNeeded()
2420 {
2421     if (!m_postLayoutScrollPosition)
2422         return;
2423
2424     scrollToOffset(scrollOffsetFromPosition(m_postLayoutScrollPosition.value()));
2425     m_postLayoutScrollPosition = WTF::nullopt;
2426 }
2427
2428 void RenderLayer::scrollToXPosition(int x, ScrollType scrollType, ScrollClamping clamping)
2429 {
2430     ScrollPosition position(x, m_scrollPosition.y());
2431     scrollToOffset(scrollOffsetFromPosition(position), scrollType, clamping);
2432 }
2433
2434 void RenderLayer::scrollToYPosition(int y, ScrollType scrollType, ScrollClamping clamping)
2435 {
2436     ScrollPosition position(m_scrollPosition.x(), y);
2437     scrollToOffset(scrollOffsetFromPosition(position), scrollType, clamping);
2438 }
2439
2440 ScrollOffset RenderLayer::clampScrollOffset(const ScrollOffset& scrollOffset) const
2441 {
2442     return scrollOffset.constrainedBetween(IntPoint(), maximumScrollOffset());
2443 }
2444
2445 void RenderLayer::scrollToOffset(const ScrollOffset& scrollOffset, ScrollType scrollType, ScrollClamping clamping)
2446 {
2447     ScrollOffset clampedScrollOffset = clamping == ScrollClamping::Clamped ? clampScrollOffset(scrollOffset) : scrollOffset;
2448     if (clampedScrollOffset == this->scrollOffset())
2449         return;
2450
2451     auto previousScrollType = currentScrollType();
2452     setCurrentScrollType(scrollType);
2453
2454     bool handled = false;
2455 #if ENABLE(ASYNC_SCROLLING)
2456     if (ScrollingCoordinator* scrollingCoordinator = page().scrollingCoordinator())
2457         handled = scrollingCoordinator->requestScrollPositionUpdate(*this, scrollPositionFromOffset(clampedScrollOffset));
2458 #endif
2459
2460     if (!handled)
2461         scrollToOffsetWithoutAnimation(clampedScrollOffset, clamping);
2462
2463     setCurrentScrollType(previousScrollType);
2464 }
2465
2466 void RenderLayer::scrollTo(const ScrollPosition& position)
2467 {
2468     RenderBox* box = renderBox();
2469     if (!box)
2470         return;
2471
2472     LOG_WITH_STREAM(Scrolling, stream << "RenderLayer::scrollTo " << position << " from " << m_scrollPosition << " (is user scroll " << (currentScrollType() == ScrollType::User) << ")");
2473
2474     ScrollPosition newPosition = position;
2475     if (!box->isHTMLMarquee()) {
2476         // Ensure that the dimensions will be computed if they need to be (for overflow:hidden blocks).
2477         if (m_scrollDimensionsDirty)
2478             computeScrollDimensions();
2479 #if PLATFORM(IOS_FAMILY)
2480         if (adjustForIOSCaretWhenScrolling()) {
2481             // FIXME: It's not clear what this code is trying to do. Behavior seems reasonable with it removed.
2482             int maxOffset = scrollWidth() - roundToInt(box->clientWidth());
2483             ScrollOffset newOffset = scrollOffsetFromPosition(newPosition);
2484             int scrollXOffset = newOffset.x();
2485             if (scrollXOffset > maxOffset - caretWidth) {
2486                 scrollXOffset += caretWidth;
2487                 if (scrollXOffset <= caretWidth)
2488                     scrollXOffset = 0;
2489             } else if (scrollXOffset < m_scrollPosition.x() - caretWidth)
2490                 scrollXOffset -= caretWidth;
2491
2492             newOffset.setX(scrollXOffset);
2493             newPosition = scrollPositionFromOffset(newOffset);
2494         }
2495 #endif
2496     }
2497     
2498     if (m_scrollPosition == newPosition) {
2499         // FIXME: Nothing guarantees we get a scrollTo() with an unchanged position at the end of a user gesture.
2500         // The ScrollingCoordinator probably needs to message the main thread when a gesture ends.
2501         if (requiresScrollPositionReconciliation()) {
2502             setNeedsCompositingGeometryUpdate();
2503             updateCompositingLayersAfterScroll();
2504         }
2505         return;
2506     }
2507
2508     m_scrollPosition = newPosition;
2509
2510     RenderView& view = renderer().view();
2511
2512     // Update the positions of our child layers (if needed as only fixed layers should be impacted by a scroll).
2513     // We don't update compositing layers, because we need to do a deep update from the compositing ancestor.
2514     if (!view.frameView().layoutContext().isInRenderTreeLayout()) {
2515         // If we're in the middle of layout, we'll just update layers once layout has finished.
2516         updateLayerPositionsAfterOverflowScroll();
2517
2518         view.frameView().scheduleUpdateWidgetPositions();
2519
2520         if (!m_updatingMarqueePosition) {
2521             // Avoid updating compositing layers if, higher on the stack, we're already updating layer
2522             // positions. Updating layer positions requires a full walk of up-to-date RenderLayers, and
2523             // in this case we're still updating their positions; we'll update compositing layers later
2524             // when that completes.
2525             if (usesCompositedScrolling()) {
2526                 setNeedsCompositingGeometryUpdate();
2527
2528                 // Scroll position can affect the location of a composited descendant (which may be a sibling in z-order),
2529                 // so trigger a descendant walk from the paint-order parent.
2530                 if (auto* paintParent = paintOrderParent())
2531                     paintParent->setDescendantsNeedUpdateBackingAndHierarchyTraversal();
2532             }
2533
2534             updateCompositingLayersAfterScroll();
2535         }
2536
2537         // Update regions, scrolling may change the clip of a particular region.
2538         renderer().document().invalidateRenderingDependentRegions();
2539         DebugPageOverlays::didLayout(renderer().frame());
2540     }
2541
2542     Frame& frame = renderer().frame();
2543     RenderLayerModelObject* repaintContainer = renderer().containerForRepaint();
2544     // The caret rect needs to be invalidated after scrolling
2545     frame.selection().setCaretRectNeedsUpdate();
2546     
2547     LayoutRect rectForRepaint = renderer().hasRepaintLayoutRects() ? renderer().repaintLayoutRects().m_repaintRect : renderer().clippedOverflowRectForRepaint(repaintContainer);
2548
2549     FloatQuad quadForFakeMouseMoveEvent = FloatQuad(rectForRepaint);
2550     if (repaintContainer)
2551         quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
2552     frame.eventHandler().dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
2553
2554     bool requiresRepaint = true;
2555     if (usesCompositedScrolling()) {
2556         setNeedsCompositingGeometryUpdate();
2557         setDescendantsNeedUpdateBackingAndHierarchyTraversal();
2558         requiresRepaint = false;
2559     }
2560
2561     // Just schedule a full repaint of our object.
2562     if (requiresRepaint)
2563         renderer().repaintUsingContainer(repaintContainer, rectForRepaint);
2564
2565     // Schedule the scroll and scroll-related DOM events.
2566     if (Element* element = renderer().element())
2567         element->document().eventQueue().enqueueOrDispatchScrollEvent(*element);
2568
2569     if (scrollsOverflow())
2570         view.frameView().didChangeScrollOffset();
2571
2572     view.frameView().viewportContentsChanged();
2573 }
2574
2575 static inline bool frameElementAndViewPermitScroll(HTMLFrameElementBase* frameElementBase, FrameView& frameView)
2576 {
2577     // If scrollbars aren't explicitly forbidden, permit scrolling.
2578     if (frameElementBase && frameElementBase->scrollingMode() != ScrollbarAlwaysOff)
2579         return true;
2580
2581     // If scrollbars are forbidden, user initiated scrolls should obviously be ignored.
2582     if (frameView.wasScrolledByUser())
2583         return false;
2584
2585     // Forbid autoscrolls when scrollbars are off, but permits other programmatic scrolls,
2586     // like navigation to an anchor.
2587     return !frameView.frame().eventHandler().autoscrollInProgress();
2588 }
2589
2590 bool RenderLayer::allowsCurrentScroll() const
2591 {
2592     if (!renderer().hasOverflowClip())
2593         return false;
2594
2595     // Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
2596     // FIXME: Is this still needed? It used to be relevant for Safari RSS.
2597     if (renderer().parent() && !renderer().parent()->style().lineClamp().isNone())
2598         return false;
2599
2600     RenderBox* box = renderBox();
2601     ASSERT(box); // Only boxes can have overflowClip set.
2602
2603     if (renderer().frame().eventHandler().autoscrollInProgress()) {
2604         // The "programmatically" here is misleading; this asks whether the box has scrollable overflow,
2605         // or is a special case like a form control.
2606         return box->canBeProgramaticallyScrolled();
2607     }
2608
2609     // Programmatic scrolls can scroll overflow:hidden.
2610     return box->hasHorizontalOverflow() || box->hasVerticalOverflow();
2611 }
2612
2613 void RenderLayer::scrollRectToVisible(const LayoutRect& absoluteRect, bool insideFixed, const ScrollRectToVisibleOptions& options)
2614 {
2615     LOG_WITH_STREAM(Scrolling, stream << "Layer " << this << " scrollRectToVisible " << absoluteRect);
2616
2617     RenderLayer* parentLayer = nullptr;
2618     LayoutRect newRect = absoluteRect;
2619
2620     // We may end up propagating a scroll event. It is important that we suspend events until 
2621     // the end of the function since they could delete the layer or the layer's renderer().
2622     FrameView& frameView = renderer().view().frameView();
2623
2624     if (renderer().parent())
2625         parentLayer = renderer().parent()->enclosingLayer();
2626
2627     if (allowsCurrentScroll()) {
2628         // Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
2629         // This will prevent us from revealing text hidden by the slider in Safari RSS.
2630         RenderBox* box = renderBox();
2631         ASSERT(box);
2632         LayoutRect localExposeRect(box->absoluteToLocalQuad(FloatQuad(FloatRect(absoluteRect))).boundingBox());
2633         if (shouldPlaceBlockDirectionScrollbarOnLeft()) {
2634             // For direction: rtl; writing-mode: horizontal-tb box, the scroll bar is on the left side. The visible rect
2635             // starts from the right side of scroll bar. So the x of localExposeRect should start from the same position too.
2636             localExposeRect.moveBy(LayoutPoint(-verticalScrollbarWidth(), 0));
2637         }
2638         LayoutRect layerBounds(0_lu, 0_lu, box->clientWidth(), box->clientHeight());
2639         LayoutRect revealRect = getRectToExpose(layerBounds, localExposeRect, insideFixed, options.alignX, options.alignY);
2640
2641         ScrollOffset clampedScrollOffset = clampScrollOffset(scrollOffset() + toIntSize(roundedIntRect(revealRect).location()));
2642         if (clampedScrollOffset != scrollOffset()) {
2643             ScrollOffset oldScrollOffset = scrollOffset();
2644             scrollToOffset(clampedScrollOffset);
2645             IntSize scrollOffsetDifference = scrollOffset() - oldScrollOffset;
2646             localExposeRect.move(-scrollOffsetDifference);
2647             newRect = LayoutRect(box->localToAbsoluteQuad(FloatQuad(FloatRect(localExposeRect)), UseTransforms).boundingBox());
2648         }
2649     } else if (!parentLayer && renderer().isRenderView()) {
2650         HTMLFrameOwnerElement* ownerElement = renderer().document().ownerElement();
2651
2652         if (ownerElement && ownerElement->renderer()) {
2653             HTMLFrameElementBase* frameElementBase = nullptr;
2654
2655             if (is<HTMLFrameElementBase>(*ownerElement))
2656                 frameElementBase = downcast<HTMLFrameElementBase>(ownerElement);
2657
2658             if (frameElementAndViewPermitScroll(frameElementBase, frameView)) {
2659                 // If this assertion fires we need to protect the ownerElement from being destroyed.
2660                 ScriptDisallowedScope::InMainThread scriptDisallowedScope;
2661
2662                 LayoutRect viewRect = frameView.visibleContentRect(LegacyIOSDocumentVisibleRect);
2663                 LayoutRect exposeRect = getRectToExpose(viewRect, absoluteRect, insideFixed, options.alignX, options.alignY);
2664
2665                 IntPoint scrollOffset(roundedIntPoint(exposeRect.location()));
2666                 // Adjust offsets if they're outside of the allowable range.
2667                 scrollOffset = scrollOffset.constrainedBetween(IntPoint(), IntPoint(frameView.contentsSize()));
2668                 frameView.setScrollPosition(scrollOffset);
2669
2670                 if (options.shouldAllowCrossOriginScrolling == ShouldAllowCrossOriginScrolling::Yes || frameView.safeToPropagateScrollToParent()) {
2671                     parentLayer = ownerElement->renderer()->enclosingLayer();
2672                     // Convert the rect into the coordinate space of the parent frame's document.
2673                     newRect = frameView.contentsToContainingViewContents(enclosingIntRect(newRect));
2674                     insideFixed = false; // FIXME: ideally need to determine if this <iframe> is inside position:fixed.
2675                 } else
2676                     parentLayer = nullptr;
2677             }
2678         } else {
2679             if (options.revealMode == SelectionRevealMode::RevealUpToMainFrame && frameView.frame().isMainFrame())
2680                 return;
2681
2682             auto minScrollPosition = frameView.minimumScrollPosition();
2683             auto maxScrollPosition = frameView.maximumScrollPosition();
2684
2685 #if !PLATFORM(IOS_FAMILY)
2686             LayoutRect viewRect = frameView.visibleContentRect();
2687 #else
2688             // FIXME: ContentInsets should be taken care of in UI process side. webkit.org/b/199682
2689             // To do that, getRectToExpose needs to return the additional scrolling to do beyond content rect.
2690             LayoutRect viewRect = frameView.viewRectExpandedByContentInsets();
2691
2692             // FIXME: webkit.org/b/199683 FrameView::visibleContentRect is wrong when content insets are present
2693             maxScrollPosition = frameView.scrollPositionFromOffset(ScrollPosition(frameView.totalContentsSize() - flooredIntSize(viewRect.size())));
2694
2695             auto contentInsets = page().contentInsets();
2696             minScrollPosition.move(-contentInsets.left(), -contentInsets.top());
2697             maxScrollPosition.move(contentInsets.right(), contentInsets.bottom());
2698 #endif
2699             // Move the target rect into "scrollView contents" coordinates.
2700             LayoutRect targetRect = absoluteRect;
2701             targetRect.move(0, frameView.headerHeight());
2702
2703             LayoutRect revealRect = getRectToExpose(viewRect, targetRect, insideFixed, options.alignX, options.alignY);
2704             ScrollOffset clampedScrollPosition = roundedIntPoint(revealRect.location()).constrainedBetween(minScrollPosition, maxScrollPosition);
2705             frameView.setScrollPosition(clampedScrollPosition);
2706
2707             // This is the outermost view of a web page, so after scrolling this view we
2708             // scroll its container by calling Page::scrollRectIntoView.
2709             // This only has an effect on the Mac platform in applications
2710             // that put web views into scrolling containers, such as Mac OS X Mail.
2711             // The canAutoscroll function in EventHandler also knows about this.
2712             page().chrome().scrollRectIntoView(snappedIntRect(absoluteRect));
2713         }
2714     }
2715     
2716     if (parentLayer)
2717         parentLayer->scrollRectToVisible(newRect, insideFixed, options);
2718 }
2719
2720 void RenderLayer::updateCompositingLayersAfterScroll()
2721 {
2722     if (compositor().hasContentCompositingLayers()) {
2723         // Our stacking container is guaranteed to contain all of our descendants that may need
2724         // repositioning, so update compositing layers from there.
2725         if (RenderLayer* compositingAncestor = stackingContext()->enclosingCompositingLayer()) {
2726             if (usesCompositedScrolling())
2727                 compositor().updateCompositingLayers(CompositingUpdateType::OnCompositedScroll, compositingAncestor);
2728             else {
2729                 // FIXME: would be nice to only dirty layers whose positions were affected by scrolling.
2730                 compositingAncestor->setDescendantsNeedUpdateBackingAndHierarchyTraversal();
2731                 compositor().updateCompositingLayers(CompositingUpdateType::OnScroll, compositingAncestor);
2732             }
2733         }
2734     }
2735 }
2736
2737 LayoutRect RenderLayer::getRectToExpose(const LayoutRect& visibleRect, const LayoutRect& exposeRect, bool insideFixed, const ScrollAlignment& alignX, const ScrollAlignment& alignY) const
2738 {
2739     FrameView& frameView = renderer().view().frameView();
2740     if (renderer().isRenderView() && insideFixed) {
2741         // If the element is inside position:fixed and we're not scaled, no amount of scrolling is going to move things around.
2742         if (frameView.frameScaleFactor() == 1)
2743             return visibleRect;
2744
2745         if (renderer().settings().visualViewportEnabled()) {
2746             // exposeRect is in absolute coords, affected by page scale. Unscale it.
2747             LayoutRect unscaledExposeRect = exposeRect;
2748             unscaledExposeRect.scale(1 / frameView.frameScaleFactor());
2749             unscaledExposeRect.move(0, -frameView.headerHeight());
2750
2751             // These are both in unscaled coordinates.
2752             LayoutRect layoutViewport = frameView.layoutViewportRect();
2753             LayoutRect visualViewport = frameView.visualViewportRect();
2754
2755             // The rect to expose may be partially offscreen, which we can't do anything about with position:fixed.
2756             unscaledExposeRect.intersect(layoutViewport);
2757             // Make sure it's not larger than the visual viewport; if so, we'll just move to the top left.
2758             unscaledExposeRect.setSize(unscaledExposeRect.size().shrunkTo(visualViewport.size()));
2759
2760             // Compute how much we have to move the visualViewport to reveal the part of the layoutViewport that contains exposeRect.
2761             LayoutRect requiredVisualViewport = getRectToExpose(visualViewport, unscaledExposeRect, false, alignX, alignY);
2762             // Scale it back up.
2763             requiredVisualViewport.scale(frameView.frameScaleFactor());
2764             requiredVisualViewport.move(0, frameView.headerHeight());
2765             return requiredVisualViewport;
2766         }
2767     }
2768
2769     // Determine the appropriate X behavior.
2770     ScrollAlignment::Behavior scrollX;
2771     LayoutRect exposeRectX(exposeRect.x(), visibleRect.y(), exposeRect.width(), visibleRect.height());
2772     LayoutUnit intersectWidth = intersection(visibleRect, exposeRectX).width();
2773     if (intersectWidth == exposeRect.width() || intersectWidth >= MIN_INTERSECT_FOR_REVEAL)
2774         // If the rectangle is fully visible, use the specified visible behavior.
2775         // If the rectangle is partially visible, but over a certain threshold,
2776         // then treat it as fully visible to avoid unnecessary horizontal scrolling
2777         scrollX = ScrollAlignment::getVisibleBehavior(alignX);
2778     else if (intersectWidth == visibleRect.width()) {
2779         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
2780         scrollX = ScrollAlignment::getVisibleBehavior(alignX);
2781         if (scrollX == ScrollAlignment::Behavior::AlignCenter)
2782             scrollX = ScrollAlignment::Behavior::NoScroll;
2783     } else if (intersectWidth > 0)
2784         // If the rectangle is partially visible, but not above the minimum threshold, use the specified partial behavior
2785         scrollX = ScrollAlignment::getPartialBehavior(alignX);
2786     else
2787         scrollX = ScrollAlignment::getHiddenBehavior(alignX);
2788     // If we're trying to align to the closest edge, and the exposeRect is further right
2789     // than the visibleRect, and not bigger than the visible area, then align with the right.
2790     if (scrollX == ScrollAlignment::Behavior::AlignToClosestEdge && exposeRect.maxX() > visibleRect.maxX() && exposeRect.width() < visibleRect.width())
2791         scrollX = ScrollAlignment::Behavior::AlignRight;
2792
2793     // Given the X behavior, compute the X coordinate.
2794     LayoutUnit x;
2795     if (scrollX == ScrollAlignment::Behavior::NoScroll)
2796         x = visibleRect.x();
2797     else if (scrollX == ScrollAlignment::Behavior::AlignRight)
2798         x = exposeRect.maxX() - visibleRect.width();
2799     else if (scrollX == ScrollAlignment::Behavior::AlignCenter)
2800         x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2;
2801     else
2802         x = exposeRect.x();
2803
2804     // Determine the appropriate Y behavior.
2805     ScrollAlignment::Behavior scrollY;
2806     LayoutRect exposeRectY(visibleRect.x(), exposeRect.y(), visibleRect.width(), exposeRect.height());
2807     LayoutUnit intersectHeight = intersection(visibleRect, exposeRectY).height();
2808     if (intersectHeight == exposeRect.height())
2809         // If the rectangle is fully visible, use the specified visible behavior.
2810         scrollY = ScrollAlignment::getVisibleBehavior(alignY);
2811     else if (intersectHeight == visibleRect.height()) {
2812         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
2813         scrollY = ScrollAlignment::getVisibleBehavior(alignY);
2814         if (scrollY == ScrollAlignment::Behavior::AlignCenter)
2815             scrollY = ScrollAlignment::Behavior::NoScroll;
2816     } else if (intersectHeight > 0)
2817         // If the rectangle is partially visible, use the specified partial behavior
2818         scrollY = ScrollAlignment::getPartialBehavior(alignY);
2819     else
2820         scrollY = ScrollAlignment::getHiddenBehavior(alignY);
2821     // If we're trying to align to the closest edge, and the exposeRect is further down
2822     // than the visibleRect, and not bigger than the visible area, then align with the bottom.
2823     if (scrollY == ScrollAlignment::Behavior::AlignToClosestEdge && exposeRect.maxY() > visibleRect.maxY() && exposeRect.height() < visibleRect.height())
2824         scrollY = ScrollAlignment::Behavior::AlignBottom;
2825
2826     // Given the Y behavior, compute the Y coordinate.
2827     LayoutUnit y;
2828     if (scrollY == ScrollAlignment::Behavior::NoScroll)
2829         y = visibleRect.y();
2830     else if (scrollY == ScrollAlignment::Behavior::AlignBottom)
2831         y = exposeRect.maxY() - visibleRect.height();
2832     else if (scrollY == ScrollAlignment::Behavior::AlignCenter)
2833         y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2;
2834     else
2835         y = exposeRect.y();
2836
2837     return LayoutRect(LayoutPoint(x, y), visibleRect.size());
2838 }
2839
2840 void RenderLayer::autoscroll(const IntPoint& positionInWindow)
2841 {
2842     IntPoint currentDocumentPosition = renderer().view().frameView().windowToContents(positionInWindow);
2843     scrollRectToVisible(LayoutRect(currentDocumentPosition, LayoutSize(1, 1)), false, { SelectionRevealMode::Reveal, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded, ShouldAllowCrossOriginScrolling::Yes });
2844 }
2845
2846 bool RenderLayer::canResize() const
2847 {
2848     // We need a special case for <iframe> because they never have
2849     // hasOverflowClip(). However, they do "implicitly" clip their contents, so
2850     // we want to allow resizing them also.
2851     return (renderer().hasOverflowClip() || renderer().isRenderIFrame()) && renderer().style().resize() != Resize::None;
2852 }
2853
2854 void RenderLayer::resize(const PlatformMouseEvent& evt, const LayoutSize& oldOffset)
2855 {
2856     // FIXME: This should be possible on generated content but is not right now.
2857     if (!inResizeMode() || !canResize() || !renderer().element())
2858         return;
2859
2860     // FIXME: The only case where renderer->element()->renderer() != renderer is with continuations. Do they matter here?
2861     // If they do it would still be better to deal with them explicitly.
2862     Element* element = renderer().element();
2863     auto* renderer = downcast<RenderBox>(element->renderer());
2864
2865     Document& document = element->document();
2866     if (!document.frame()->eventHandler().mousePressed())
2867         return;
2868
2869     float zoomFactor = renderer->style().effectiveZoom();
2870
2871     LayoutSize newOffset = offsetFromResizeCorner(document.view()->windowToContents(evt.position()));
2872     newOffset.setWidth(newOffset.width() / zoomFactor);
2873     newOffset.setHeight(newOffset.height() / zoomFactor);
2874     
2875     LayoutSize currentSize = LayoutSize(renderer->width() / zoomFactor, renderer->height() / zoomFactor);
2876     LayoutSize minimumSize = element->minimumSizeForResizing().shrunkTo(currentSize);
2877     element->setMinimumSizeForResizing(minimumSize);
2878     
2879     LayoutSize adjustedOldOffset = LayoutSize(oldOffset.width() / zoomFactor, oldOffset.height() / zoomFactor);
2880     if (shouldPlaceBlockDirectionScrollbarOnLeft()) {
2881         newOffset.setWidth(-newOffset.width());
2882         adjustedOldOffset.setWidth(-adjustedOldOffset.width());
2883     }
2884     
2885     LayoutSize difference = (currentSize + newOffset - adjustedOldOffset).expandedTo(minimumSize) - currentSize;
2886
2887     StyledElement* styledElement = downcast<StyledElement>(element);
2888     bool isBoxSizingBorder = renderer->style().boxSizing() == BoxSizing::BorderBox;
2889
2890     Resize resize = renderer->style().resize();
2891     if (resize != Resize::Vertical && difference.width()) {
2892         if (is<HTMLFormControlElement>(*element)) {
2893             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
2894             styledElement->setInlineStyleProperty(CSSPropertyMarginLeft, renderer->marginLeft() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2895             styledElement->setInlineStyleProperty(CSSPropertyMarginRight, renderer->marginRight() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2896         }
2897         LayoutUnit baseWidth = renderer->width() - (isBoxSizingBorder ? 0_lu : renderer->horizontalBorderAndPaddingExtent());
2898         baseWidth = baseWidth / zoomFactor;
2899         styledElement->setInlineStyleProperty(CSSPropertyWidth, roundToInt(baseWidth + difference.width()), CSSPrimitiveValue::CSS_PX);
2900     }
2901
2902     if (resize != Resize::Horizontal && difference.height()) {
2903         if (is<HTMLFormControlElement>(*element)) {
2904             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
2905             styledElement->setInlineStyleProperty(CSSPropertyMarginTop, renderer->marginTop() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2906             styledElement->setInlineStyleProperty(CSSPropertyMarginBottom, renderer->marginBottom() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2907         }
2908         LayoutUnit baseHeight = renderer->height() - (isBoxSizingBorder ? 0_lu : renderer->verticalBorderAndPaddingExtent());
2909         baseHeight = baseHeight / zoomFactor;
2910         styledElement->setInlineStyleProperty(CSSPropertyHeight, roundToInt(baseHeight + difference.height()), CSSPrimitiveValue::CSS_PX);
2911     }
2912
2913     document.updateLayout();
2914
2915     // FIXME (Radar 4118564): We should also autoscroll the window as necessary to keep the point under the cursor in view.
2916 }
2917
2918 void RenderLayer::setScrollOffset(const ScrollOffset& offset)
2919 {
2920     scrollTo(scrollPositionFromOffset(offset));
2921 }
2922
2923 ScrollingNodeID RenderLayer::scrollingNodeID() const
2924 {
2925     if (!isComposited())
2926         return 0;
2927
2928     return backing()->scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling);
2929 }
2930
2931 IntRect RenderLayer::visibleContentRectInternal(VisibleContentRectIncludesScrollbars scrollbarInclusion, VisibleContentRectBehavior) const
2932 {
2933     IntSize scrollbarSpace;
2934     if (showsOverflowControls() && scrollbarInclusion == IncludeScrollbars)
2935         scrollbarSpace = scrollbarIntrusion();
2936     
2937     auto visibleSize = this->visibleSize();
2938     return { scrollPosition(), { std::max(0, visibleSize.width() - scrollbarSpace.width()), std::max(0, visibleSize.height() - scrollbarSpace.height()) } };
2939 }
2940
2941 IntSize RenderLayer::overhangAmount() const
2942 {
2943 #if ENABLE(RUBBER_BANDING)
2944     if (!renderer().settings().rubberBandingForSubScrollableRegionsEnabled())
2945         return IntSize();
2946
2947     IntSize stretch;
2948
2949     // FIXME: use maximumScrollOffset(), or just move this to ScrollableArea.
2950     ScrollOffset scrollOffset = scrollOffsetFromPosition(scrollPosition());
2951     auto reachableSize = reachableTotalContentsSize();
2952     if (scrollOffset.y() < 0)
2953         stretch.setHeight(scrollOffset.y());
2954     else if (reachableSize.height() && scrollOffset.y() > reachableSize.height() - visibleHeight())
2955         stretch.setHeight(scrollOffset.y() - (reachableSize.height() - visibleHeight()));
2956
2957     if (scrollOffset.x() < 0)
2958         stretch.setWidth(scrollOffset.x());
2959     else if (reachableSize.width() && scrollOffset.x() > reachableSize.width() - visibleWidth())
2960         stretch.setWidth(scrollOffset.x() - (reachableSize.width() - visibleWidth()));
2961
2962     return stretch;
2963 #else
2964     return IntSize();
2965 #endif
2966 }
2967
2968 bool RenderLayer::isActive() const
2969 {
2970     return page().focusController().isActive();
2971 }
2972
2973 static int cornerStart(const RenderLayer& layer, int minX, int maxX, int thickness)
2974 {
2975     if (layer.shouldPlaceBlockDirectionScrollbarOnLeft())
2976         return minX + layer.renderer().style().borderLeftWidth();
2977     return maxX - thickness - layer.renderer().style().borderRightWidth();
2978 }
2979
2980 static LayoutRect cornerRect(const RenderLayer& layer, const LayoutRect& bounds)
2981 {
2982     int horizontalThickness;
2983     int verticalThickness;
2984     if (!layer.verticalScrollbar() && !layer.horizontalScrollbar()) {
2985         // FIXME: This isn't right.  We need to know the thickness of custom scrollbars
2986         // even when they don't exist in order to set the resizer square size properly.
2987         horizontalThickness = ScrollbarTheme::theme().scrollbarThickness();
2988         verticalThickness = horizontalThickness;
2989     } else if (layer.verticalScrollbar() && !layer.horizontalScrollbar()) {
2990         horizontalThickness = layer.verticalScrollbar()->width();
2991         verticalThickness = horizontalThickness;
2992     } else if (layer.horizontalScrollbar() && !layer.verticalScrollbar()) {
2993         verticalThickness = layer.horizontalScrollbar()->height();
2994         horizontalThickness = verticalThickness;
2995     } else {
2996         horizontalThickness = layer.verticalScrollbar()->width();
2997         verticalThickness = layer.horizontalScrollbar()->height();
2998     }
2999     return LayoutRect(cornerStart(layer, bounds.x(), bounds.maxX(), horizontalThickness),
3000         bounds.maxY() - verticalThickness - layer.renderer().style().borderBottomWidth(),
3001         horizontalThickness, verticalThickness);
3002 }
3003
3004 IntRect RenderLayer::scrollCornerRect() const
3005 {
3006     // We have a scrollbar corner when a non overlay scrollbar is visible and not filling the entire length of the box.
3007     // This happens when:
3008     // (a) A resizer is present and at least one non overlay scrollbar is present
3009     // (b) Both non overlay scrollbars are present.
3010     // Overlay scrollbars always fill the entire length of the box so we never have scroll corner in that case.
3011     bool hasHorizontalBar = m_hBar && !m_hBar->isOverlayScrollbar();
3012     bool hasVerticalBar = m_vBar && !m_vBar->isOverlayScrollbar();
3013     bool hasResizer = renderer().style().resize() != Resize::None;
3014     if ((hasHorizontalBar && hasVerticalBar) || (hasResizer && (hasHorizontalBar || hasVerticalBar)))
3015         return snappedIntRect(cornerRect(*this, renderBox()->borderBoxRect()));
3016     return IntRect();
3017 }
3018
3019 static LayoutRect resizerCornerRect(const RenderLayer& layer, const LayoutRect& bounds)
3020 {
3021     ASSERT(layer.renderer().isBox());
3022     if (layer.renderer().style().resize() == Resize::None)
3023         return LayoutRect();
3024     return cornerRect(layer, bounds);
3025 }
3026
3027 LayoutRect RenderLayer::scrollCornerAndResizerRect() const
3028 {
3029     RenderBox* box = renderBox();
3030     if (!box)
3031         return LayoutRect();
3032     LayoutRect scrollCornerAndResizer = scrollCornerRect();
3033     if (scrollCornerAndResizer.isEmpty())
3034         scrollCornerAndResizer = resizerCornerRect(*this, box->borderBoxRect());
3035     return scrollCornerAndResizer;
3036 }
3037
3038 bool RenderLayer::isScrollCornerVisible() const
3039 {
3040     ASSERT(renderer().isBox());
3041     return !scrollCornerRect().isEmpty();
3042 }
3043
3044 IntRect RenderLayer::convertFromScrollbarToContainingView(const Scrollbar& scrollbar, const IntRect& scrollbarRect) const
3045 {
3046     IntRect rect = scrollbarRect;
3047     rect.move(scrollbarOffset(scrollbar));
3048
3049     return renderer().view().frameView().convertFromRendererToContainingView(&renderer(), rect);
3050 }
3051
3052 IntRect RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar& scrollbar, const IntRect& parentRect) const
3053 {
3054     IntRect rect = renderer().view().frameView().convertFromContainingViewToRenderer(&renderer(), parentRect);
3055     rect.move(-scrollbarOffset(scrollbar));
3056     return rect;
3057 }
3058
3059 IntPoint RenderLayer::convertFromScrollbarToContainingView(const Scrollbar& scrollbar, const IntPoint& scrollbarPoint) const
3060 {
3061     IntPoint point = scrollbarPoint;
3062     point.move(scrollbarOffset(scrollbar));
3063     return renderer().view().frameView().convertFromRendererToContainingView(&renderer(), point);
3064 }
3065
3066 IntPoint RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar& scrollbar, const IntPoint& parentPoint) const
3067 {
3068     IntPoint point = renderer().view().frameView().convertFromContainingViewToRenderer(&renderer(), parentPoint);
3069     point.move(-scrollbarOffset(scrollbar));
3070     return point;
3071 }
3072
3073 IntSize RenderLayer::visibleSize() const
3074 {
3075     RenderBox* box = renderBox();
3076     if (!box)
3077         return IntSize();
3078
3079     return IntSize(roundToInt(box->clientWidth()), roundToInt(box->clientHeight()));
3080 }
3081
3082 IntSize RenderLayer::contentsSize() const
3083 {
3084     return IntSize(scrollWidth(), scrollHeight());
3085 }
3086
3087 IntSize RenderLayer::reachableTotalContentsSize() const
3088 {
3089     IntSize contentsSize = this->contentsSize();
3090
3091     if (!hasScrollableHorizontalOverflow())
3092         contentsSize.setWidth(std::min(contentsSize.width(), visibleSize().width()));
3093
3094     if (!hasScrollableVerticalOverflow())
3095         contentsSize.setHeight(std::min(contentsSize.height(), visibleSize().height()));
3096
3097     return contentsSize;
3098 }
3099
3100 void RenderLayer::availableContentSizeChanged(AvailableSizeChangeReason reason)
3101 {
3102     ScrollableArea::availableContentSizeChanged(reason);
3103
3104     if (reason == AvailableSizeChangeReason::ScrollbarsChanged) {
3105         if (is<RenderBlock>(renderer()))
3106             downcast<RenderBlock>(renderer()).setShouldForceRelayoutChildren(true);
3107         renderer().setNeedsLayout();
3108     }
3109 }
3110
3111 bool RenderLayer::shouldSuspendScrollAnimations() const
3112 {
3113     return renderer().view().frameView().shouldSuspendScrollAnimations();
3114 }
3115
3116 #if PLATFORM(IOS_FAMILY)
3117 void RenderLayer::didStartScroll()
3118 {
3119     page().chrome().client().didStartOverflowScroll();
3120 }
3121
3122 void RenderLayer::didEndScroll()
3123 {
3124     page().chrome().client().didEndOverflowScroll();
3125 }
3126     
3127 void RenderLayer::didUpdateScroll()
3128 {
3129     // Send this notification when we scroll, since this is how we keep selection updated.
3130     page().chrome().client().didLayout(ChromeClient::Scroll);
3131 }
3132 #endif
3133
3134 IntPoint RenderLayer::lastKnownMousePosition() const
3135 {
3136     return renderer().frame().eventHandler().lastKnownMousePosition();
3137 }
3138
3139 bool RenderLayer::isHandlingWheelEvent() const
3140 {
3141     return renderer().frame().eventHandler().isHandlingWheelEvent();
3142 }
3143
3144 IntRect RenderLayer::rectForHorizontalScrollbar(const IntRect& borderBoxRect) const
3145 {
3146     if (!m_hBar)
3147         return IntRect();
3148
3149     const RenderBox* box = renderBox();
3150     const IntRect& scrollCorner = scrollCornerRect();
3151
3152     return IntRect(horizontalScrollbarStart(borderBoxRect.x()),
3153         borderBoxRect.maxY() - box->borderBottom() - m_hBar->height(),
3154         borderBoxRect.width() - (box->borderLeft() + box->borderRight()) - scrollCorner.width(),
3155         m_hBar->height());
3156 }
3157
3158 IntRect RenderLayer::rectForVerticalScrollbar(const IntRect& borderBoxRect) const
3159 {
3160     if (!m_vBar)
3161         return IntRect();
3162
3163     const RenderBox* box = renderBox();
3164     const IntRect& scrollCorner = scrollCornerRect();
3165
3166     return IntRect(verticalScrollbarStart(borderBoxRect.x(), borderBoxRect.maxX()),
3167         borderBoxRect.y() + box->borderTop(),
3168         m_vBar->width(),
3169         borderBoxRect.height() - (box->borderTop() + box->borderBottom()) - scrollCorner.height());
3170 }
3171
3172 LayoutUnit RenderLayer::verticalScrollbarStart(int minX, int maxX) const
3173 {
3174     const RenderBox* box = renderBox();
3175     if (shouldPlaceBlockDirectionScrollbarOnLeft())
3176         return minX + box->borderLeft();
3177     return maxX - box->borderRight() - m_vBar->width();
3178 }
3179
3180 LayoutUnit RenderLayer::horizontalScrollbarStart(int minX) const
3181 {
3182     const RenderBox* box = renderBox();
3183     int x = minX + box->borderLeft();
3184     if (shouldPlaceBlockDirectionScrollbarOnLeft())
3185         x += m_vBar ? m_vBar->width() : roundToInt(resizerCornerRect(*this, box->borderBoxRect()).width());
3186     return x;
3187 }
3188
3189 IntSize RenderLayer::scrollbarOffset(const Scrollbar& scrollbar) const
3190 {
3191     RenderBox* box = renderBox();
3192
3193     if (&scrollbar == m_vBar.get())
3194         return IntSize(verticalScrollbarStart(0, box->width()), box->borderTop());
3195
3196     if (&scrollbar == m_hBar.get())
3197         return IntSize(horizontalScrollbarStart(0), box->height() - box->borderBottom() - scrollbar.height());
3198     
3199     ASSERT_NOT_REACHED();
3200     return IntSize();
3201 }
3202
3203 void RenderLayer::invalidateScrollbarRect(Scrollbar& scrollbar, const IntRect& rect)
3204 {
3205     if (!showsOverflowControls())
3206         return;
3207
3208     if (&scrollbar == m_vBar.get()) {
3209         if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
3210             layer->setNeedsDisplayInRect(rect);
3211             return;
3212         }
3213     } else {
3214         if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
3215             layer->setNeedsDisplayInRect(rect);
3216             return;
3217         }
3218     }
3219
3220     IntRect scrollRect = rect;
3221     RenderBox* box = renderBox();
3222     ASSERT(box);
3223     // If we are not yet inserted into the tree, there is no need to repaint.
3224     if (!box->parent())
3225         return;
3226
3227     if (&scrollbar == m_vBar.get())
3228         scrollRect.move(verticalScrollbarStart(0, box->width()), box->borderTop());
3229     else
3230         scrollRect.move(horizontalScrollbarStart(0), box->height() - box->borderBottom() - scrollbar.height());
3231     LayoutRect repaintRect = scrollRect;
3232     renderBox()->flipForWritingMode(repaintRect);
3233     renderer().repaintRectangle(repaintRect);
3234 }
3235
3236 void RenderLayer::invalidateScrollCornerRect(const IntRect& rect)
3237 {
3238     if (!showsOverflowControls())
3239         return;
3240
3241     if (GraphicsLayer* layer = layerForScrollCorner()) {
3242         layer->setNeedsDisplayInRect(rect);
3243         return;
3244     }
3245
3246     if (m_scrollCorner)
3247         m_scrollCorner->repaintRectangle(rect);
3248     if (m_resizer)
3249         m_resizer->repaintRectangle(rect);
3250 }
3251
3252 static bool scrollbarHiddenByStyle(Scrollbar* scrollbar)
3253 {
3254     if (!scrollbar || !scrollbar->isCustomScrollbar())
3255         return false;
3256
3257     std::unique_ptr<RenderStyle> scrollbarStyle = static_cast<RenderScrollbar*>(scrollbar)->getScrollbarPseudoStyle(ScrollbarBGPart, PseudoId::Scrollbar);
3258
3259     return scrollbarStyle && scrollbarStyle->display() == DisplayType::None;
3260 }
3261
3262 bool RenderLayer::horizontalScrollbarHiddenByStyle() const
3263 {
3264     return scrollbarHiddenByStyle(horizontalScrollbar());
3265 }
3266
3267 bool RenderLayer::verticalScrollbarHiddenByStyle() const
3268 {
3269     return scrollbarHiddenByStyle(verticalScrollbar());
3270 }
3271
3272 static inline RenderElement* rendererForScrollbar(RenderLayerModelObject& renderer)
3273 {
3274     if (Element* element = renderer.element()) {
3275         if (ShadowRoot* shadowRoot = element->containingShadowRoot()) {
3276             if (shadowRoot->mode() == ShadowRootMode::UserAgent)
3277                 return shadowRoot->host()->renderer();
3278         }
3279     }
3280
3281     return &renderer;
3282 }
3283
3284 Ref<Scrollbar> RenderLayer::createScrollbar(ScrollbarOrientation orientation)
3285 {
3286     RefPtr<Scrollbar> widget;
3287     ASSERT(rendererForScrollbar(renderer()));
3288     auto& actualRenderer = *rendererForScrollbar(renderer());
3289     bool hasCustomScrollbarStyle = is<RenderBox>(actualRenderer) && downcast<RenderBox>(actualRenderer).style().hasPseudoStyle(PseudoId::Scrollbar);
3290     if (hasCustomScrollbarStyle)
3291         widget = RenderScrollbar::createCustomScrollbar(*this, orientation, downcast<RenderBox>(actualRenderer).element());
3292     else {
3293         widget = Scrollbar::createNativeScrollbar(*this, orientation, RegularScrollbar);
3294         didAddScrollbar(widget.get(), orientation);
3295         if (page().expectsWheelEventTriggers())
3296             scrollAnimator().setWheelEventTestTrigger(page().testTrigger());
3297     }
3298     renderer().view().frameView().addChild(*widget);
3299     return widget.releaseNonNull();
3300 }
3301
3302 void RenderLayer::destroyScrollbar(ScrollbarOrientation orientation)
3303 {
3304     RefPtr<Scrollbar>& scrollbar = orientation == HorizontalScrollbar ? m_hBar : m_vBar;
3305     if (!scrollbar)
3306         return;
3307
3308     if (!scrollbar->isCustomScrollbar())
3309         willRemoveScrollbar(scrollbar.get(), orientation);
3310
3311     scrollbar->removeFromParent();
3312     scrollbar = nullptr;
3313 }
3314
3315 bool RenderLayer::scrollsOverflow() const
3316 {
3317     if (!is<RenderBox>(renderer()))
3318         return false;
3319
3320     return downcast<RenderBox>(renderer()).scrollsOverflow();
3321 }
3322
3323 void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
3324 {
3325     if (hasScrollbar == hasHorizontalScrollbar())
3326         return;
3327
3328     if (hasScrollbar) {
3329         m_hBar = createScrollbar(HorizontalScrollbar);
3330 #if ENABLE(RUBBER_BANDING)
3331         ScrollElasticity elasticity = scrollsOverflow() && renderer().settings().rubberBandingForSubScrollableRegionsEnabled() ? ScrollElasticityAutomatic : ScrollElasticityNone;
3332         ScrollableArea::setHorizontalScrollElasticity(elasticity);
3333 #endif
3334     } else {
3335         destroyScrollbar(HorizontalScrollbar);
3336 #if ENABLE(RUBBER_BANDING)
3337         ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityNone);
3338 #endif
3339     }
3340
3341     // Destroying or creating one bar can cause our scrollbar corner to come and go.  We need to update the opposite scrollbar's style.
3342     if (m_hBar)
3343         m_hBar->styleChanged();
3344     if (m_vBar)
3345         m_vBar->styleChanged();
3346 }
3347
3348 void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
3349 {
3350     if (hasScrollbar == hasVerticalScrollbar())
3351         return;
3352
3353     if (hasScrollbar) {
3354         m_vBar = createScrollbar(VerticalScrollbar);
3355 #if ENABLE(RUBBER_BANDING)
3356         ScrollElasticity elasticity = scrollsOverflow() && renderer().settings().rubberBandingForSubScrollableRegionsEnabled() ? ScrollElasticityAutomatic : ScrollElasticityNone;
3357         ScrollableArea::setVerticalScrollElasticity(elasticity);
3358 #endif
3359     } else {
3360         destroyScrollbar(VerticalScrollbar);
3361 #if ENABLE(RUBBER_BANDING)
3362         ScrollableArea::setVerticalScrollElasticity(ScrollElasticityNone);
3363 #endif
3364     }
3365
3366      // Destroying or creating one bar can cause our scrollbar corner to come and go.  We need to update the opposite scrollbar's style.
3367     if (m_hBar)
3368         m_hBar->styleChanged();
3369     if (m_vBar)
3370         m_vBar->styleChanged();
3371 }
3372
3373 ScrollableArea* RenderLayer::enclosingScrollableArea() const
3374 {
3375     if (RenderLayer* scrollableLayer = enclosingScrollableLayer())
3376         return scrollableLayer;
3377
3378     // FIXME: We should return the frame view here (or possibly an ancestor frame view,
3379     // if the frame view isn't scrollable.
3380     return nullptr;
3381 }
3382
3383 bool RenderLayer::isScrollableOrRubberbandable()
3384 {
3385     return renderer().isScrollableOrRubberbandableBox();
3386 }
3387
3388 bool RenderLayer::hasScrollableOrRubberbandableAncestor()
3389 {
3390     for (RenderLayer* nextLayer = parentLayerCrossFrame(*this); nextLayer; nextLayer = parentLayerCrossFrame(*nextLayer)) {
3391         if (nextLayer->isScrollableOrRubberbandable())
3392             return true;
3393     }
3394
3395     return false;
3396 }
3397
3398 bool RenderLayer::useDarkAppearance() const
3399 {
3400     return renderer().useDarkAppearance();
3401 }
3402
3403 #if ENABLE(CSS_SCROLL_SNAP)
3404 void RenderLayer::updateSnapOffsets()
3405 {
3406     // FIXME: Extend support beyond HTMLElements.
3407     if (!is<HTMLElement>(enclosingElement()) || !enclosingElement()->renderBox())
3408         return;
3409
3410     RenderBox* box = enclosingElement()->renderBox();
3411     updateSnapOffsetsForScrollableArea(*this, *downcast<HTMLElement>(enclosingElement()), *box, box->style());
3412 }