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