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