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