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