1/*
2 * Copyright (C) 2006-2014 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 "Document.h"
52#include "DocumentEventQueue.h"
53#include "Element.h"
54#include "EventHandler.h"
55#include "FloatConversion.h"
56#include "FloatPoint3D.h"
57#include "FloatRect.h"
58#include "FloatRoundedRect.h"
59#include "FlowThreadController.h"
60#include "FocusController.h"
61#include "Frame.h"
62#include "FrameLoader.h"
63#include "FrameLoaderClient.h"
64#include "FrameSelection.h"
65#include "FrameTree.h"
66#include "FrameView.h"
67#include "Gradient.h"
68#include "GraphicsContext.h"
69#include "HTMLFrameElement.h"
70#include "HTMLFrameOwnerElement.h"
71#include "HTMLNames.h"
72#include "HitTestingTransformState.h"
73#include "HitTestRequest.h"
74#include "HitTestResult.h"
75#include "InspectorInstrumentation.h"
76#include "OverflowEvent.h"
77#include "OverlapTestRequestClient.h"
78#include "Page.h"
79#include "PlatformMouseEvent.h"
80#include "RenderFlowThread.h"
81#include "RenderGeometryMap.h"
82#include "RenderInline.h"
83#include "RenderIterator.h"
84#include "RenderLayerBacking.h"
85#include "RenderLayerCompositor.h"
86#include "RenderMarquee.h"
87#include "RenderMultiColumnFlowThread.h"
88#include "RenderNamedFlowFragment.h"
89#include "RenderNamedFlowThread.h"
90#include "RenderRegion.h"
91#include "RenderReplica.h"
92#include "RenderSVGResourceClipper.h"
93#include "RenderScrollbar.h"
94#include "RenderScrollbarPart.h"
95#include "RenderTableCell.h"
96#include "RenderTableRow.h"
97#include "RenderTheme.h"
98#include "RenderTreeAsText.h"
99#include "RenderView.h"
100#include "SVGNames.h"
101#include "ScaleTransformOperation.h"
102#include "ScrollAnimator.h"
103#include "Scrollbar.h"
104#include "ScrollbarTheme.h"
105#include "ScrollingCoordinator.h"
106#include "Settings.h"
107#include "ShadowRoot.h"
108#include "SourceGraphic.h"
109#include "StyleProperties.h"
110#include "StyleResolver.h"
111#include "TextStream.h"
112#include "TransformationMatrix.h"
113#include "TranslateTransformOperation.h"
114#include <stdio.h>
115#include <wtf/StdLibExtras.h>
116#include <wtf/text/CString.h>
117
118#if ENABLE(CSS_FILTERS)
119#include "FEColorMatrix.h"
120#include "FEMerge.h"
121#include "FilterEffectRenderer.h"
122#include "RenderLayerFilterInfo.h"
123#endif
124
125#define MIN_INTERSECT_FOR_REVEAL 32
126
127namespace WebCore {
128
129using namespace HTMLNames;
130
131bool ClipRect::intersects(const HitTestLocation& hitTestLocation) const
132{
133    return hitTestLocation.intersects(m_rect);
134}
135
136void makeMatrixRenderable(TransformationMatrix& matrix, bool has3DRendering)
137{
138#if !ENABLE(3D_RENDERING)
139    UNUSED_PARAM(has3DRendering);
140    matrix.makeAffine();
141#else
142    if (!has3DRendering)
143        matrix.makeAffine();
144#endif
145}
146
147RenderLayer::RenderLayer(RenderLayerModelObject& rendererLayerModelObject)
148    : m_inResizeMode(false)
149    , m_scrollDimensionsDirty(true)
150    , m_normalFlowListDirty(true)
151    , m_hasSelfPaintingLayerDescendant(false)
152    , m_hasSelfPaintingLayerDescendantDirty(false)
153    , m_hasOutOfFlowPositionedDescendant(false)
154    , m_hasOutOfFlowPositionedDescendantDirty(true)
155    , m_needsCompositedScrolling(false)
156    , m_descendantsAreContiguousInStackingOrder(false)
157    , m_isRootLayer(rendererLayerModelObject.isRenderView())
158    , m_usedTransparency(false)
159    , m_paintingInsideReflection(false)
160    , m_inOverflowRelayout(false)
161    , m_repaintStatus(NeedsNormalRepaint)
162    , m_visibleContentStatusDirty(true)
163    , m_hasVisibleContent(false)
164    , m_visibleDescendantStatusDirty(false)
165    , m_hasVisibleDescendant(false)
166    , m_3DTransformedDescendantStatusDirty(true)
167    , m_has3DTransformedDescendant(false)
168    , m_hasCompositingDescendant(false)
169    , m_hasTransformedAncestor(false)
170    , m_has3DTransformedAncestor(false)
171    , m_indirectCompositingReason(static_cast<unsigned>(IndirectCompositingReason::None))
172    , m_viewportConstrainedNotCompositedReason(NoNotCompositedReason)
173#if PLATFORM(IOS)
174    , m_adjustForIOSCaretWhenScrolling(false)
175    , m_registeredAsTouchEventListenerForScrolling(false)
176    , m_inUserScroll(false)
177    , m_requiresScrollBoundsOriginUpdate(false)
178#endif
179    , m_containsDirtyOverlayScrollbars(false)
180    , m_updatingMarqueePosition(false)
181#if !ASSERT_DISABLED
182    , m_layerListMutationAllowed(true)
183#endif
184#if ENABLE(CSS_FILTERS)
185    , m_hasFilterInfo(false)
186#endif
187#if ENABLE(CSS_COMPOSITING)
188    , m_blendMode(BlendModeNormal)
189    , m_hasNotIsolatedCompositedBlendingDescendants(false)
190    , m_hasNotIsolatedBlendingDescendants(false)
191    , m_hasNotIsolatedBlendingDescendantsStatusDirty(false)
192#endif
193    , m_renderer(rendererLayerModelObject)
194    , m_parent(0)
195    , m_previous(0)
196    , m_next(0)
197    , m_first(0)
198    , m_last(0)
199    , m_staticInlinePosition(0)
200    , m_staticBlockPosition(0)
201    , m_enclosingPaginationLayer(0)
202{
203    m_isNormalFlowOnly = shouldBeNormalFlowOnly();
204    m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
205
206    // Non-stacking containers should have empty z-order lists. As this is already the case,
207    // there is no need to dirty / recompute these lists.
208    m_zOrderListsDirty = isStackingContainer();
209
210    ScrollableArea::setConstrainsScrollingToContentEdge(false);
211
212    if (!renderer().firstChild()) {
213        m_visibleContentStatusDirty = false;
214        m_hasVisibleContent = renderer().style().visibility() == VISIBLE;
215    }
216
217    if (Element* element = renderer().element()) {
218        // We save and restore only the scrollOffset as the other scroll values are recalculated.
219        m_scrollOffset = element->savedLayerScrollOffset();
220        if (!m_scrollOffset.isZero())
221            scrollAnimator()->setCurrentPosition(FloatPoint(m_scrollOffset.width(), m_scrollOffset.height()));
222        element->setSavedLayerScrollOffset(IntSize());
223    }
224}
225
226RenderLayer::~RenderLayer()
227{
228    if (inResizeMode() && !renderer().documentBeingDestroyed())
229        renderer().frame().eventHandler().resizeLayerDestroyed();
230
231    renderer().view().frameView().removeScrollableArea(this);
232
233    if (!renderer().documentBeingDestroyed()) {
234#if PLATFORM(IOS)
235        unregisterAsTouchEventListenerForScrolling();
236#endif
237        if (Element* element = renderer().element())
238            element->setSavedLayerScrollOffset(m_scrollOffset);
239    }
240
241    destroyScrollbar(HorizontalScrollbar);
242    destroyScrollbar(VerticalScrollbar);
243
244    if (renderer().frame().page()) {
245        if (ScrollingCoordinator* scrollingCoordinator = renderer().frame().page()->scrollingCoordinator())
246            scrollingCoordinator->willDestroyScrollableArea(this);
247    }
248
249    if (m_reflection)
250        removeReflection();
251
252#if ENABLE(CSS_FILTERS)
253    FilterInfo::remove(*this);
254#endif
255
256    // Child layers will be deleted by their corresponding render objects, so
257    // we don't need to delete them ourselves.
258
259    clearBacking(true);
260}
261
262String RenderLayer::name() const
263{
264    StringBuilder name;
265    name.append(renderer().renderName());
266
267    if (Element* element = renderer().element()) {
268        name.append(' ');
269        name.append(element->tagName());
270
271        if (element->hasID()) {
272            name.appendLiteral(" id=\'");
273            name.append(element->getIdAttribute());
274            name.append('\'');
275        }
276
277        if (element->hasClass()) {
278            name.appendLiteral(" class=\'");
279            for (size_t i = 0; i < element->classNames().size(); ++i) {
280                if (i > 0)
281                    name.append(' ');
282                name.append(element->classNames()[i]);
283            }
284            name.append('\'');
285        }
286    }
287
288    if (isReflection())
289        name.appendLiteral(" (reflection)");
290
291    return name.toString();
292}
293
294RenderLayerCompositor& RenderLayer::compositor() const
295{
296    return renderer().view().compositor();
297}
298
299void RenderLayer::contentChanged(ContentChangeType changeType)
300{
301    if ((changeType == CanvasChanged || changeType == VideoChanged || changeType == FullScreenChanged || changeType == ImageChanged) && compositor().updateLayerCompositingState(*this))
302        compositor().setCompositingLayersNeedRebuild();
303
304    if (m_backing)
305        m_backing->contentChanged(changeType);
306}
307
308bool RenderLayer::canRender3DTransforms() const
309{
310    return compositor().canRender3DTransforms();
311}
312
313#if ENABLE(CSS_FILTERS)
314
315bool RenderLayer::paintsWithFilters() const
316{
317    // FIXME: Eventually there will be cases where we paint with filters even without accelerated compositing,
318    // and this whole function won't be inside the #if below.
319
320    if (!renderer().hasFilter())
321        return false;
322
323    if (!isComposited())
324        return true;
325
326    if (!m_backing || !m_backing->canCompositeFilters())
327        return true;
328
329    return false;
330}
331
332bool RenderLayer::requiresFullLayerImageForFilters() const
333{
334    if (!paintsWithFilters())
335        return false;
336    FilterEffectRenderer* renderer = filterRenderer();
337    return renderer && renderer->hasFilterThatMovesPixels();
338}
339
340FilterEffectRenderer* RenderLayer::filterRenderer() const
341{
342    FilterInfo* filterInfo = FilterInfo::getIfExists(*this);
343    return filterInfo ? filterInfo->renderer() : 0;
344}
345
346#endif
347
348void RenderLayer::updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, UpdateLayerPositionsFlags flags)
349{
350    RenderGeometryMap geometryMap(UseTransforms);
351    if (this != rootLayer)
352        geometryMap.pushMappingsToAncestor(parent(), 0);
353    updateLayerPositions(&geometryMap, flags);
354}
355
356void RenderLayer::updateLayerPositions(RenderGeometryMap* geometryMap, UpdateLayerPositionsFlags flags)
357{
358    updateLayerPosition(); // For relpositioned layers or non-positioned layers,
359                           // we need to keep in sync, since we may have shifted relative
360                           // to our parent layer.
361    if (geometryMap)
362        geometryMap->pushMappingsToAncestor(this, parent());
363
364    // Clear our cached clip rect information.
365    clearClipRects();
366
367    if (hasOverflowControls()) {
368        LayoutSize offsetFromRoot;
369        if (geometryMap)
370            offsetFromRoot = LayoutSize(toFloatSize(geometryMap->absolutePoint(FloatPoint())));
371        else {
372            // FIXME: It looks suspicious to call convertToLayerCoords here
373            // as canUseConvertToLayerCoords may be true for an ancestor layer.
374            offsetFromRoot = offsetFromAncestor(root());
375        }
376        positionOverflowControls(roundedIntSize(offsetFromRoot));
377    }
378
379    updateDescendantDependentFlags();
380
381    if (flags & UpdatePagination)
382        updatePagination();
383    else
384        m_enclosingPaginationLayer = nullptr;
385
386    if (m_hasVisibleContent) {
387        // FIXME: LayoutState does not work with RenderLayers as there is not a 1-to-1
388        // mapping between them and the RenderObjects. It would be neat to enable
389        // LayoutState outside the layout() phase and use it here.
390        ASSERT(!renderer().view().layoutStateEnabled());
391
392        RenderLayerModelObject* repaintContainer = renderer().containerForRepaint();
393        LayoutRect oldRepaintRect = m_repaintRect;
394        LayoutRect oldOutlineBox = m_outlineBox;
395        computeRepaintRects(repaintContainer, geometryMap);
396
397        // FIXME: Should ASSERT that value calculated for m_outlineBox using the cached offset is the same
398        // as the value not using the cached offset, but we can't due to https://bugs.webkit.org/show_bug.cgi?id=37048
399        if (flags & CheckForRepaint) {
400            if (!renderer().view().printing()) {
401                bool didRepaint = false;
402                if (m_repaintStatus & NeedsFullRepaint) {
403                    renderer().repaintUsingContainer(repaintContainer, oldRepaintRect);
404                    if (m_repaintRect != oldRepaintRect) {
405                        renderer().repaintUsingContainer(repaintContainer, m_repaintRect);
406                        didRepaint = true;
407                    }
408                } else if (shouldRepaintAfterLayout()) {
409                    renderer().repaintAfterLayoutIfNeeded(repaintContainer, oldRepaintRect, oldOutlineBox, &m_repaintRect, &m_outlineBox);
410                    didRepaint = true;
411                }
412
413                if (didRepaint && renderer().isRenderNamedFlowFragmentContainer()) {
414                    // If we just repainted a region, we must also repaint the flow thread since it is the one
415                    // doing the actual painting of the flowed content.
416                    RenderNamedFlowFragment* region = toRenderBlockFlow(&renderer())->renderNamedFlowFragment();
417                    if (region->isValid())
418                        region->flowThread()->layer()->repaintIncludingDescendants();
419                }
420            }
421        }
422    } else
423        clearRepaintRects();
424
425    m_repaintStatus = NeedsNormalRepaint;
426    m_hasTransformedAncestor = flags & SeenTransformedLayer;
427    m_has3DTransformedAncestor = flags & Seen3DTransformedLayer;
428
429    // Go ahead and update the reflection's position and size.
430    if (m_reflection)
431        m_reflection->layout();
432
433    // Clear the IsCompositingUpdateRoot flag once we've found the first compositing layer in this update.
434    bool isUpdateRoot = (flags & IsCompositingUpdateRoot);
435    if (isComposited())
436        flags &= ~IsCompositingUpdateRoot;
437
438    if (renderer().isInFlowRenderFlowThread()) {
439        updatePagination();
440        flags |= UpdatePagination;
441    }
442
443    if (transform()) {
444        flags |= SeenTransformedLayer;
445        if (!transform()->isAffine())
446            flags |= Seen3DTransformedLayer;
447    }
448
449    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
450        child->updateLayerPositions(geometryMap, flags);
451
452    if ((flags & UpdateCompositingLayers) && isComposited()) {
453        RenderLayerBacking::UpdateAfterLayoutFlags updateFlags = RenderLayerBacking::CompositingChildrenOnly;
454        if (flags & NeedsFullRepaintInBacking)
455            updateFlags |= RenderLayerBacking::NeedsFullRepaint;
456        if (isUpdateRoot)
457            updateFlags |= RenderLayerBacking::IsUpdateRoot;
458        backing()->updateAfterLayout(updateFlags);
459    }
460
461    // With all our children positioned, now update our marquee if we need to.
462    if (m_marquee) {
463        // FIXME: would like to use TemporaryChange<> but it doesn't work with bitfields.
464        bool oldUpdatingMarqueePosition = m_updatingMarqueePosition;
465        m_updatingMarqueePosition = true;
466        m_marquee->updateMarqueePosition();
467        m_updatingMarqueePosition = oldUpdatingMarqueePosition;
468    }
469
470    if (geometryMap)
471        geometryMap->popMappingsToAncestor(parent());
472}
473
474LayoutRect RenderLayer::repaintRectIncludingNonCompositingDescendants() const
475{
476    LayoutRect repaintRect = m_repaintRect;
477    for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
478        // Don't include repaint rects for composited child layers; they will paint themselves and have a different origin.
479        if (child->isComposited())
480            continue;
481
482        repaintRect.unite(child->repaintRectIncludingNonCompositingDescendants());
483    }
484    return repaintRect;
485}
486
487void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant()
488{
489    for (RenderLayer* layer = this; layer; layer = layer->parent()) {
490        if (!layer->m_hasSelfPaintingLayerDescendantDirty && layer->hasSelfPaintingLayerDescendant())
491            break;
492
493        layer->m_hasSelfPaintingLayerDescendantDirty = false;
494        layer->m_hasSelfPaintingLayerDescendant = true;
495    }
496}
497
498void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus()
499{
500    for (RenderLayer* layer = this; layer; layer = layer->parent()) {
501        layer->m_hasSelfPaintingLayerDescendantDirty = true;
502        // If we have reached a self-painting layer, we know our parent should have a self-painting descendant
503        // in this case, there is no need to dirty our ancestors further.
504        if (layer->isSelfPaintingLayer()) {
505            ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->hasSelfPaintingLayerDescendant());
506            break;
507        }
508    }
509}
510
511bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const
512{
513    return renderer().frame().settings().acceleratedCompositingForOverflowScrollEnabled();
514}
515
516// If we are a stacking container, then this function will determine if our
517// descendants for a contiguous block in stacking order. This is required in
518// order for an element to be safely promoted to a stacking container. It is safe
519// to become a stacking container if this change would not alter the stacking
520// order of layers on the page. That can only happen if a non-descendant appear
521// between us and our descendants in stacking order. Here's an example:
522//
523//                                 this
524//                                /  |  \.
525//                               A   B   C
526//                              /\   |   /\.
527//                             0 -8  D  2  7
528//                                   |
529//                                   5
530//
531// I've labeled our normal flow descendants A, B, C, and D, our stacking
532// container descendants with their z indices, and us with 'this' (we're a
533// stacking container and our zIndex doesn't matter here). These nodes appear in
534// three lists: posZOrder, negZOrder, and normal flow (keep in mind that normal
535// flow layers don't overlap). So if we arrange these lists in order we get our
536// stacking order:
537//
538//                     [-8], [A-D], [0, 2, 5, 7]--> pos z-order.
539//                       |     |
540//        Neg z-order. <-+     +--> Normal flow descendants.
541//
542// We can then assign new, 'stacking' order indices to these elements as follows:
543//
544//                     [-8], [A-D], [0, 2, 5, 7]
545// 'Stacking' indices:  -1     0     1  2  3  4
546//
547// Note that the normal flow descendants can share an index because they don't
548// stack/overlap. Now our problem becomes very simple: a layer can safely become
549// a stacking container if the stacking-order indices of it and its descendants
550// appear in a contiguous block in the list of stacking indices. This problem
551// can be solved very efficiently by calculating the min/max stacking indices in
552// the subtree, and the number stacking container descendants. Once we have this
553// information, we know that the subtree's indices form a contiguous block if:
554//
555//           maxStackIndex - minStackIndex == numSCDescendants
556//
557// So for node A in the example above we would have:
558//   maxStackIndex = 1
559//   minStackIndex = -1
560//   numSCDecendants = 2
561//
562// and so,
563//       maxStackIndex - minStackIndex == numSCDescendants
564//  ===>                      1 - (-1) == 2
565//  ===>                             2 == 2
566//
567//  Since this is true, A can safely become a stacking container.
568//  Now, for node C we have:
569//
570//   maxStackIndex = 4
571//   minStackIndex = 0 <-- because C has stacking index 0.
572//   numSCDecendants = 2
573//
574// and so,
575//       maxStackIndex - minStackIndex == numSCDescendants
576//  ===>                         4 - 0 == 2
577//  ===>                             4 == 2
578//
579// Since this is false, C cannot be safely promoted to a stacking container. This
580// happened because of the elements with z-index 5 and 0. Now if 5 had been a
581// child of C rather than D, and A had no child with Z index 0, we would have had:
582//
583//   maxStackIndex = 3
584//   minStackIndex = 0 <-- because C has stacking index 0.
585//   numSCDecendants = 3
586//
587// and so,
588//       maxStackIndex - minStackIndex == numSCDescendants
589//  ===>                         3 - 0 == 3
590//  ===>                             3 == 3
591//
592//  And we would conclude that C could be promoted.
593void RenderLayer::updateDescendantsAreContiguousInStackingOrder()
594{
595    if (!isStackingContext() || !acceleratedCompositingForOverflowScrollEnabled())
596        return;
597
598    ASSERT(!m_normalFlowListDirty);
599    ASSERT(!m_zOrderListsDirty);
600
601    std::unique_ptr<Vector<RenderLayer*>> posZOrderList;
602    std::unique_ptr<Vector<RenderLayer*>> negZOrderList;
603    rebuildZOrderLists(StopAtStackingContexts, posZOrderList, negZOrderList);
604
605    // Create a reverse lookup.
606    HashMap<const RenderLayer*, int> lookup;
607
608    if (negZOrderList) {
609        int stackingOrderIndex = -1;
610        size_t listSize = negZOrderList->size();
611        for (size_t i = 0; i < listSize; ++i) {
612            RenderLayer* currentLayer = negZOrderList->at(listSize - i - 1);
613            if (!currentLayer->isStackingContext())
614                continue;
615            lookup.set(currentLayer, stackingOrderIndex--);
616        }
617    }
618
619    if (posZOrderList) {
620        size_t listSize = posZOrderList->size();
621        int stackingOrderIndex = 1;
622        for (size_t i = 0; i < listSize; ++i) {
623            RenderLayer* currentLayer = posZOrderList->at(i);
624            if (!currentLayer->isStackingContext())
625                continue;
626            lookup.set(currentLayer, stackingOrderIndex++);
627        }
628    }
629
630    int minIndex = 0;
631    int maxIndex = 0;
632    int count = 0;
633    bool firstIteration = true;
634    updateDescendantsAreContiguousInStackingOrderRecursive(lookup, minIndex, maxIndex, count, firstIteration);
635}
636
637void RenderLayer::updateDescendantsAreContiguousInStackingOrderRecursive(const HashMap<const RenderLayer*, int>& lookup, int& minIndex, int& maxIndex, int& count, bool firstIteration)
638{
639    if (isStackingContext() && !firstIteration) {
640        if (lookup.contains(this)) {
641            minIndex = std::min(minIndex, lookup.get(this));
642            maxIndex = std::max(maxIndex, lookup.get(this));
643            count++;
644        }
645        return;
646    }
647
648    for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
649        int childMinIndex = 0;
650        int childMaxIndex = 0;
651        int childCount = 0;
652        child->updateDescendantsAreContiguousInStackingOrderRecursive(lookup, childMinIndex, childMaxIndex, childCount, false);
653        if (childCount) {
654            count += childCount;
655            minIndex = std::min(minIndex, childMinIndex);
656            maxIndex = std::max(maxIndex, childMaxIndex);
657        }
658    }
659
660    if (!isStackingContext()) {
661        bool newValue = maxIndex - minIndex == count;
662        bool didUpdate = newValue != m_descendantsAreContiguousInStackingOrder;
663        m_descendantsAreContiguousInStackingOrder = newValue;
664        if (didUpdate)
665            updateNeedsCompositedScrolling();
666    }
667}
668
669void RenderLayer::computeRepaintRects(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* geometryMap)
670{
671    ASSERT(!m_visibleContentStatusDirty);
672
673    m_repaintRect = renderer().clippedOverflowRectForRepaint(repaintContainer);
674    m_outlineBox = renderer().outlineBoundsForRepaint(repaintContainer, geometryMap);
675}
676
677
678void RenderLayer::computeRepaintRectsIncludingDescendants()
679{
680    // FIXME: computeRepaintRects() has to walk up the parent chain for every layer to compute the rects.
681    // We should make this more efficient.
682    // FIXME: it's wrong to call this when layout is not up-to-date, which we do.
683    computeRepaintRects(renderer().containerForRepaint());
684
685    for (RenderLayer* layer = firstChild(); layer; layer = layer->nextSibling())
686        layer->computeRepaintRectsIncludingDescendants();
687}
688
689void RenderLayer::clearRepaintRects()
690{
691    ASSERT(!m_hasVisibleContent);
692    ASSERT(!m_visibleContentStatusDirty);
693
694    m_repaintRect = LayoutRect();
695    m_outlineBox = LayoutRect();
696}
697
698void RenderLayer::updateLayerPositionsAfterDocumentScroll()
699{
700    ASSERT(this == renderer().view().layer());
701
702    RenderGeometryMap geometryMap(UseTransforms);
703    updateLayerPositionsAfterScroll(&geometryMap);
704}
705
706void RenderLayer::updateLayerPositionsAfterOverflowScroll()
707{
708    RenderGeometryMap geometryMap(UseTransforms);
709    if (this != renderer().view().layer())
710        geometryMap.pushMappingsToAncestor(parent(), 0);
711
712    // FIXME: why is it OK to not check the ancestors of this layer in order to
713    // initialize the HasSeenViewportConstrainedAncestor and HasSeenAncestorWithOverflowClip flags?
714    updateLayerPositionsAfterScroll(&geometryMap, IsOverflowScroll);
715}
716
717void RenderLayer::updateLayerPositionsAfterScroll(RenderGeometryMap* geometryMap, UpdateLayerPositionsAfterScrollFlags flags)
718{
719    // FIXME: This shouldn't be needed, but there are some corner cases where
720    // these flags are still dirty. Update so that the check below is valid.
721    updateDescendantDependentFlags();
722
723    // If we have no visible content and no visible descendants, there is no point recomputing
724    // our rectangles as they will be empty. If our visibility changes, we are expected to
725    // recompute all our positions anyway.
726    if (!m_hasVisibleDescendant && !m_hasVisibleContent)
727        return;
728
729    bool positionChanged = updateLayerPosition();
730    if (positionChanged)
731        flags |= HasChangedAncestor;
732
733    if (geometryMap)
734        geometryMap->pushMappingsToAncestor(this, parent());
735
736    if (flags & HasChangedAncestor || flags & HasSeenViewportConstrainedAncestor || flags & IsOverflowScroll)
737        clearClipRects();
738
739    if (renderer().style().hasViewportConstrainedPosition())
740        flags |= HasSeenViewportConstrainedAncestor;
741
742    if (renderer().hasOverflowClip())
743        flags |= HasSeenAncestorWithOverflowClip;
744
745    if (flags & HasSeenViewportConstrainedAncestor
746        || (flags & IsOverflowScroll && flags & HasSeenAncestorWithOverflowClip)) {
747        // FIXME: We could track the repaint container as we walk down the tree.
748        computeRepaintRects(renderer().containerForRepaint(), geometryMap);
749    } else {
750        // Check that our cached rects are correct.
751        ASSERT(m_repaintRect == renderer().clippedOverflowRectForRepaint(renderer().containerForRepaint()));
752        ASSERT(m_outlineBox == renderer().outlineBoundsForRepaint(renderer().containerForRepaint(), geometryMap));
753    }
754
755    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
756        child->updateLayerPositionsAfterScroll(geometryMap, flags);
757
758    // We don't update our reflection as scrolling is a translation which does not change the size()
759    // of an object, thus RenderReplica will still repaint itself properly as the layer position was
760    // updated above.
761
762    if (m_marquee) {
763        bool oldUpdatingMarqueePosition = m_updatingMarqueePosition;
764        m_updatingMarqueePosition = true;
765        m_marquee->updateMarqueePosition();
766        m_updatingMarqueePosition = oldUpdatingMarqueePosition;
767    }
768
769    if (geometryMap)
770        geometryMap->popMappingsToAncestor(parent());
771}
772
773void RenderLayer::positionNewlyCreatedOverflowControls()
774{
775    if (!backing()->hasUnpositionedOverflowControlsLayers())
776        return;
777
778    RenderGeometryMap geometryMap(UseTransforms);
779    if (this != renderer().view().layer() && parent())
780        geometryMap.pushMappingsToAncestor(parent(), 0);
781
782    LayoutPoint offsetFromRoot = LayoutPoint(geometryMap.absolutePoint(FloatPoint()));
783    positionOverflowControls(toIntSize(roundedIntPoint(offsetFromRoot)));
784}
785
786#if ENABLE(CSS_COMPOSITING)
787
788void RenderLayer::updateBlendMode()
789{
790    bool hadBlendMode = m_blendMode != BlendModeNormal;
791    if (parent() && hadBlendMode != hasBlendMode()) {
792        if (hasBlendMode())
793            parent()->updateAncestorChainHasBlendingDescendants();
794        else
795            parent()->dirtyAncestorChainHasBlendingDescendants();
796    }
797
798    BlendMode newBlendMode = renderer().style().blendMode();
799    if (newBlendMode != m_blendMode)
800        m_blendMode = newBlendMode;
801}
802
803void RenderLayer::updateAncestorChainHasBlendingDescendants()
804{
805    for (auto layer = this; layer; layer = layer->parent()) {
806        if (!layer->hasNotIsolatedBlendingDescendantsStatusDirty() && layer->hasNotIsolatedBlendingDescendants())
807            break;
808        layer->m_hasNotIsolatedBlendingDescendants = true;
809        layer->m_hasNotIsolatedBlendingDescendantsStatusDirty = false;
810
811        layer->updateSelfPaintingLayer();
812
813        if (layer->isStackingContext())
814            break;
815    }
816}
817
818void RenderLayer::dirtyAncestorChainHasBlendingDescendants()
819{
820    for (auto layer = this; layer; layer = layer->parent()) {
821        if (layer->hasNotIsolatedBlendingDescendantsStatusDirty())
822            break;
823
824        layer->m_hasNotIsolatedBlendingDescendantsStatusDirty = true;
825
826        if (layer->isStackingContext())
827            break;
828    }
829}
830#endif
831
832void RenderLayer::updateTransform()
833{
834    // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
835    // so check style too.
836    bool hasTransform = renderer().hasTransform() && renderer().style().hasTransform();
837    bool had3DTransform = has3DTransform();
838
839    bool hadTransform = !!m_transform;
840    if (hasTransform != hadTransform) {
841        if (hasTransform)
842            m_transform = std::make_unique<TransformationMatrix>();
843        else
844            m_transform = nullptr;
845
846        // Layers with transforms act as clip rects roots, so clear the cached clip rects here.
847        clearClipRectsIncludingDescendants();
848    }
849
850    if (hasTransform) {
851        RenderBox* box = renderBox();
852        ASSERT(box);
853        m_transform->makeIdentity();
854        box->style().applyTransform(*m_transform, pixelSnappedForPainting(box->borderBoxRect(), box->document().deviceScaleFactor()), RenderStyle::IncludeTransformOrigin);
855        makeMatrixRenderable(*m_transform, canRender3DTransforms());
856    }
857
858    if (had3DTransform != has3DTransform())
859        dirty3DTransformedDescendantStatus();
860}
861
862TransformationMatrix RenderLayer::currentTransform(RenderStyle::ApplyTransformOrigin applyOrigin) const
863{
864    if (!m_transform)
865        return TransformationMatrix();
866
867    RenderBox* box = renderBox();
868    ASSERT(box);
869    FloatRect pixelSnappedBorderRect = pixelSnappedForPainting(box->borderBoxRect(), box->document().deviceScaleFactor());
870    if (renderer().style().isRunningAcceleratedAnimation()) {
871        TransformationMatrix currTransform;
872        RefPtr<RenderStyle> style = renderer().animation().getAnimatedStyleForRenderer(&renderer());
873        style->applyTransform(currTransform, pixelSnappedBorderRect, applyOrigin);
874        makeMatrixRenderable(currTransform, canRender3DTransforms());
875        return currTransform;
876    }
877
878    // m_transform includes transform-origin, so we need to recompute the transform here.
879    if (applyOrigin == RenderStyle::ExcludeTransformOrigin) {
880        TransformationMatrix currTransform;
881        box->style().applyTransform(currTransform, pixelSnappedBorderRect, RenderStyle::ExcludeTransformOrigin);
882        makeMatrixRenderable(currTransform, canRender3DTransforms());
883        return currTransform;
884    }
885
886    return *m_transform;
887}
888
889TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavior) const
890{
891    if (!m_transform)
892        return TransformationMatrix();
893
894    if (paintBehavior & PaintBehaviorFlattenCompositingLayers) {
895        TransformationMatrix matrix = *m_transform;
896        makeMatrixRenderable(matrix, false /* flatten 3d */);
897        return matrix;
898    }
899
900    return *m_transform;
901}
902
903RenderLayer* RenderLayer::enclosingOverflowClipLayer(IncludeSelfOrNot includeSelf) const
904{
905    const RenderLayer* layer = (includeSelf == IncludeSelf) ? this : parent();
906    while (layer) {
907        if (layer->renderer().hasOverflowClip())
908            return const_cast<RenderLayer*>(layer);
909
910        layer = layer->parent();
911    }
912    return 0;
913}
914
915// FIXME: This is terrible. Bring back a cached bit for this someday. This crawl is going to slow down all
916// painting of content inside paginated layers.
917bool RenderLayer::hasCompositedLayerInEnclosingPaginationChain() const
918{
919    // No enclosing layer means no compositing in the chain.
920    if (!m_enclosingPaginationLayer)
921        return false;
922
923    // If the enclosing layer is composited, we don't have to check anything in between us and that
924    // layer.
925    if (m_enclosingPaginationLayer->isComposited())
926        return true;
927
928    // If we are the enclosing pagination layer, then we can't be composited or we'd have passed the
929    // previous check.
930    if (m_enclosingPaginationLayer == this)
931        return false;
932
933    // The enclosing paginated layer is our ancestor and is not composited, so we have to check
934    // intermediate layers between us and the enclosing pagination layer. Start with our own layer.
935    if (isComposited())
936        return true;
937
938    // For normal flow layers, we can recur up the layer tree.
939    if (isNormalFlowOnly())
940        return parent()->hasCompositedLayerInEnclosingPaginationChain();
941
942    // Otherwise we have to go up the containing block chain. Find the first enclosing
943    // containing block layer ancestor, and check that.
944    RenderView* renderView = &renderer().view();
945    for (RenderBlock* containingBlock = renderer().containingBlock(); containingBlock && containingBlock != renderView; containingBlock = containingBlock->containingBlock()) {
946        if (containingBlock->hasLayer())
947            return containingBlock->layer()->hasCompositedLayerInEnclosingPaginationChain();
948    }
949    return false;
950}
951
952void RenderLayer::updatePagination()
953{
954    m_enclosingPaginationLayer = nullptr;
955
956    if (!parent())
957        return;
958
959    // Each layer that is inside a multicolumn flow thread has to be checked individually and
960    // genuinely know if it is going to have to split itself up when painting only its contents (and not any other descendant
961    // layers). We track an enclosingPaginationLayer instead of using a simple bit, since we want to be able to get back
962    // to that layer easily.
963    if (renderer().isInFlowRenderFlowThread()) {
964        m_enclosingPaginationLayer = this;
965        return;
966    }
967
968    if (isNormalFlowOnly()) {
969        // Content inside a transform is not considered to be paginated, since we simply
970        // paint the transform multiple times in each column, so we don't have to use
971        // fragments for the transformed content.
972        if (parent()->hasTransform())
973            m_enclosingPaginationLayer = nullptr;
974        else
975            m_enclosingPaginationLayer = parent()->enclosingPaginationLayer(IncludeCompositedPaginatedLayers);
976        return;
977    }
978
979    // For the new columns code, we want to walk up our containing block chain looking for an enclosing layer. Once
980    // we find one, then we just check its pagination status.
981    RenderView* renderView = &renderer().view();
982    RenderBlock* containingBlock;
983    for (containingBlock = renderer().containingBlock(); containingBlock && containingBlock != renderView; containingBlock = containingBlock->containingBlock()) {
984        if (containingBlock->hasLayer()) {
985            // Content inside a transform is not considered to be paginated, since we simply
986            // paint the transform multiple times in each column, so we don't have to use
987            // fragments for the transformed content.
988            if (containingBlock->layer()->hasTransform())
989                m_enclosingPaginationLayer = nullptr;
990            else
991                m_enclosingPaginationLayer = containingBlock->layer()->enclosingPaginationLayer(IncludeCompositedPaginatedLayers);
992            return;
993        }
994    }
995}
996
997bool RenderLayer::canBeStackingContainer() const
998{
999    if (isStackingContext() || !stackingContainer())
1000        return true;
1001
1002    return m_descendantsAreContiguousInStackingOrder;
1003}
1004
1005void RenderLayer::setHasVisibleContent()
1006{
1007    if (m_hasVisibleContent && !m_visibleContentStatusDirty) {
1008        ASSERT(!parent() || parent()->hasVisibleDescendant());
1009        return;
1010    }
1011
1012    m_visibleContentStatusDirty = false;
1013    m_hasVisibleContent = true;
1014    computeRepaintRects(renderer().containerForRepaint());
1015    if (!isNormalFlowOnly()) {
1016        // We don't collect invisible layers in z-order lists if we are not in compositing mode.
1017        // As we became visible, we need to dirty our stacking containers ancestors to be properly
1018        // collected. FIXME: When compositing, we could skip this dirtying phase.
1019        for (RenderLayer* sc = stackingContainer(); sc; sc = sc->stackingContainer()) {
1020            sc->dirtyZOrderLists();
1021            if (sc->hasVisibleContent())
1022                break;
1023        }
1024    }
1025
1026    if (parent())
1027        parent()->setAncestorChainHasVisibleDescendant();
1028}
1029
1030void RenderLayer::dirtyVisibleContentStatus()
1031{
1032    m_visibleContentStatusDirty = true;
1033    if (parent())
1034        parent()->dirtyAncestorChainVisibleDescendantStatus();
1035}
1036
1037void RenderLayer::dirtyAncestorChainVisibleDescendantStatus()
1038{
1039    for (RenderLayer* layer = this; layer; layer = layer->parent()) {
1040        if (layer->m_visibleDescendantStatusDirty)
1041            break;
1042
1043        layer->m_visibleDescendantStatusDirty = true;
1044    }
1045}
1046
1047void RenderLayer::setAncestorChainHasVisibleDescendant()
1048{
1049    for (RenderLayer* layer = this; layer; layer = layer->parent()) {
1050        if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendant())
1051            break;
1052
1053        layer->m_hasVisibleDescendant = true;
1054        layer->m_visibleDescendantStatusDirty = false;
1055    }
1056}
1057
1058void RenderLayer::updateDescendantDependentFlags(HashSet<const RenderObject*>* outOfFlowDescendantContainingBlocks)
1059{
1060    if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty || hasNotIsolatedBlendingDescendantsStatusDirty()) {
1061        bool hasVisibleDescendant = false;
1062        bool hasSelfPaintingLayerDescendant = false;
1063        bool hasOutOfFlowPositionedDescendant = false;
1064#if ENABLE(CSS_COMPOSITING)
1065        bool hasNotIsolatedBlendingDescendants = false;
1066#endif
1067
1068        HashSet<const RenderObject*> childOutOfFlowDescendantContainingBlocks;
1069        for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
1070            childOutOfFlowDescendantContainingBlocks.clear();
1071            child->updateDescendantDependentFlags(&childOutOfFlowDescendantContainingBlocks);
1072
1073            bool childIsOutOfFlowPositioned = child->renderer().isOutOfFlowPositioned();
1074            if (childIsOutOfFlowPositioned)
1075                childOutOfFlowDescendantContainingBlocks.add(child->renderer().containingBlock());
1076
1077            if (outOfFlowDescendantContainingBlocks) {
1078                HashSet<const RenderObject*>::const_iterator it = childOutOfFlowDescendantContainingBlocks.begin();
1079                for (; it != childOutOfFlowDescendantContainingBlocks.end(); ++it)
1080                    outOfFlowDescendantContainingBlocks->add(*it);
1081            }
1082
1083            hasVisibleDescendant |= child->m_hasVisibleContent || child->m_hasVisibleDescendant;
1084            hasSelfPaintingLayerDescendant |= child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant();
1085            hasOutOfFlowPositionedDescendant |= !childOutOfFlowDescendantContainingBlocks.isEmpty();
1086#if ENABLE(CSS_COMPOSITING)
1087            hasNotIsolatedBlendingDescendants |= child->hasBlendMode() || (child->hasNotIsolatedBlendingDescendants() && !child->isolatesBlending());
1088#endif
1089
1090            bool allFlagsSet = hasVisibleDescendant && hasSelfPaintingLayerDescendant && hasOutOfFlowPositionedDescendant;
1091#if ENABLE(CSS_COMPOSITING)
1092            allFlagsSet &= hasNotIsolatedBlendingDescendants;
1093#endif
1094            if (allFlagsSet)
1095                break;
1096        }
1097
1098        if (outOfFlowDescendantContainingBlocks)
1099            outOfFlowDescendantContainingBlocks->remove(&renderer());
1100
1101        m_hasVisibleDescendant = hasVisibleDescendant;
1102        m_visibleDescendantStatusDirty = false;
1103        m_hasSelfPaintingLayerDescendant = hasSelfPaintingLayerDescendant;
1104        m_hasSelfPaintingLayerDescendantDirty = false;
1105
1106        m_hasOutOfFlowPositionedDescendant = hasOutOfFlowPositionedDescendant;
1107        if (m_hasOutOfFlowPositionedDescendantDirty)
1108            updateNeedsCompositedScrolling();
1109
1110        m_hasOutOfFlowPositionedDescendantDirty = false;
1111#if ENABLE(CSS_COMPOSITING)
1112        m_hasNotIsolatedBlendingDescendants = hasNotIsolatedBlendingDescendants;
1113        if (m_hasNotIsolatedBlendingDescendantsStatusDirty) {
1114            m_hasNotIsolatedBlendingDescendantsStatusDirty = false;
1115            updateSelfPaintingLayer();
1116        }
1117#endif
1118    }
1119
1120    if (m_visibleContentStatusDirty) {
1121        if (renderer().style().visibility() == VISIBLE)
1122            m_hasVisibleContent = true;
1123        else {
1124            // layer may be hidden but still have some visible content, check for this
1125            m_hasVisibleContent = false;
1126            RenderObject* r = renderer().firstChild();
1127            while (r) {
1128                if (r->style().visibility() == VISIBLE && !r->hasLayer()) {
1129                    m_hasVisibleContent = true;
1130                    break;
1131                }
1132                RenderObject* child = nullptr;
1133                if (!r->hasLayer() && (child = r->firstChildSlow()))
1134                    r = child;
1135                else if (r->nextSibling())
1136                    r = r->nextSibling();
1137                else {
1138                    do {
1139                        r = r->parent();
1140                        if (r == &renderer())
1141                            r = 0;
1142                    } while (r && !r->nextSibling());
1143                    if (r)
1144                        r = r->nextSibling();
1145                }
1146            }
1147        }
1148        m_visibleContentStatusDirty = false;
1149    }
1150}
1151
1152// Return true if the new clipping behaviour requires layer update.
1153bool RenderLayer::checkIfDescendantClippingContextNeedsUpdate(bool isClipping)
1154{
1155    for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
1156        RenderLayerBacking* backing = child->backing();
1157        // Layer subtree needs update when new clipping is added or existing clipping is removed.
1158        if (backing && (isClipping || backing->hasAncestorClippingLayer()))
1159            return true;
1160
1161        if (child->checkIfDescendantClippingContextNeedsUpdate(isClipping))
1162            return true;
1163    }
1164    return false;
1165}
1166
1167void RenderLayer::dirty3DTransformedDescendantStatus()
1168{
1169    RenderLayer* curr = stackingContainer();
1170    if (curr)
1171        curr->m_3DTransformedDescendantStatusDirty = true;
1172
1173    // This propagates up through preserve-3d hierarchies to the enclosing flattening layer.
1174    // Note that preserves3D() creates stacking context, so we can just run up the stacking containers.
1175    while (curr && curr->preserves3D()) {
1176        curr->m_3DTransformedDescendantStatusDirty = true;
1177        curr = curr->stackingContainer();
1178    }
1179}
1180
1181// Return true if this layer or any preserve-3d descendants have 3d.
1182bool RenderLayer::update3DTransformedDescendantStatus()
1183{
1184    if (m_3DTransformedDescendantStatusDirty) {
1185        m_has3DTransformedDescendant = false;
1186
1187        updateZOrderLists();
1188
1189        // Transformed or preserve-3d descendants can only be in the z-order lists, not
1190        // in the normal flow list, so we only need to check those.
1191        if (Vector<RenderLayer*>* positiveZOrderList = posZOrderList()) {
1192            for (unsigned i = 0; i < positiveZOrderList->size(); ++i)
1193                m_has3DTransformedDescendant |= positiveZOrderList->at(i)->update3DTransformedDescendantStatus();
1194        }
1195
1196        // Now check our negative z-index children.
1197        if (Vector<RenderLayer*>* negativeZOrderList = negZOrderList()) {
1198            for (unsigned i = 0; i < negativeZOrderList->size(); ++i)
1199                m_has3DTransformedDescendant |= negativeZOrderList->at(i)->update3DTransformedDescendantStatus();
1200        }
1201
1202        m_3DTransformedDescendantStatusDirty = false;
1203    }
1204
1205    // If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs
1206    // the m_has3DTransformedDescendant set.
1207    if (preserves3D())
1208        return has3DTransform() || m_has3DTransformedDescendant;
1209
1210    return has3DTransform();
1211}
1212
1213bool RenderLayer::updateLayerPosition()
1214{
1215    LayoutPoint localPoint;
1216    LayoutSize inlineBoundingBoxOffset; // We don't put this into the RenderLayer x/y for inlines, so we need to subtract it out when done.
1217    if (renderer().isInline() && renderer().isRenderInline()) {
1218        RenderInline& inlineFlow = toRenderInline(renderer());
1219        IntRect lineBox = inlineFlow.linesBoundingBox();
1220        setSize(lineBox.size());
1221        inlineBoundingBoxOffset = toLayoutSize(lineBox.location());
1222        localPoint += inlineBoundingBoxOffset;
1223    } else if (RenderBox* box = renderBox()) {
1224        // FIXME: Is snapping the size really needed here for the RenderBox case?
1225        setSize(pixelSnappedIntSize(box->size(), box->location()));
1226        localPoint += box->topLeftLocationOffset();
1227    }
1228
1229    if (!renderer().isOutOfFlowPositioned() && renderer().parent()) {
1230        // We must adjust our position by walking up the render tree looking for the
1231        // nearest enclosing object with a layer.
1232        RenderElement* curr = renderer().parent();
1233        while (curr && !curr->hasLayer()) {
1234            if (curr->isBox() && !curr->isTableRow()) {
1235                // Rows and cells share the same coordinate space (that of the section).
1236                // Omit them when computing our xpos/ypos.
1237                localPoint += toRenderBox(curr)->topLeftLocationOffset();
1238            }
1239            curr = curr->parent();
1240        }
1241        if (curr->isBox() && curr->isTableRow()) {
1242            // Put ourselves into the row coordinate space.
1243            localPoint -= toRenderBox(curr)->topLeftLocationOffset();
1244        }
1245    }
1246
1247    // Subtract our parent's scroll offset.
1248    if (renderer().isOutOfFlowPositioned() && enclosingPositionedAncestor()) {
1249        RenderLayer* positionedParent = enclosingPositionedAncestor();
1250
1251        // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
1252        if (positionedParent->renderer().hasOverflowClip()) {
1253            LayoutSize offset = positionedParent->scrolledContentOffset();
1254            localPoint -= offset;
1255        }
1256
1257        if (renderer().isOutOfFlowPositioned() && positionedParent->renderer().isInFlowPositioned() && positionedParent->renderer().isRenderInline()) {
1258            LayoutSize offset = toRenderInline(positionedParent->renderer()).offsetForInFlowPositionedInline(&toRenderBox(renderer()));
1259            localPoint += offset;
1260        }
1261    } else if (parent()) {
1262        if (parent()->renderer().hasOverflowClip()) {
1263            IntSize scrollOffset = parent()->scrolledContentOffset();
1264            localPoint -= scrollOffset;
1265        }
1266    }
1267
1268    bool positionOrOffsetChanged = false;
1269    if (renderer().isInFlowPositioned()) {
1270        LayoutSize newOffset = toRenderBoxModelObject(renderer()).offsetForInFlowPosition();
1271        positionOrOffsetChanged = newOffset != m_offsetForInFlowPosition;
1272        m_offsetForInFlowPosition = newOffset;
1273        localPoint.move(m_offsetForInFlowPosition);
1274    } else {
1275        m_offsetForInFlowPosition = LayoutSize();
1276    }
1277
1278    // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
1279    localPoint -= inlineBoundingBoxOffset;
1280
1281    positionOrOffsetChanged |= location() != localPoint;
1282    setLocation(localPoint);
1283    return positionOrOffsetChanged;
1284}
1285
1286TransformationMatrix RenderLayer::perspectiveTransform() const
1287{
1288    if (!renderer().hasTransform())
1289        return TransformationMatrix();
1290
1291    const RenderStyle& style = renderer().style();
1292    if (!style.hasPerspective())
1293        return TransformationMatrix();
1294
1295    // Maybe fetch the perspective from the backing?
1296    const IntRect borderBox = toRenderBox(renderer()).pixelSnappedBorderBoxRect();
1297    const float boxWidth = borderBox.width();
1298    const float boxHeight = borderBox.height();
1299
1300    float perspectiveOriginX = floatValueForLength(style.perspectiveOriginX(), boxWidth);
1301    float perspectiveOriginY = floatValueForLength(style.perspectiveOriginY(), boxHeight);
1302
1303    // A perspective origin of 0,0 makes the vanishing point in the center of the element.
1304    // We want it to be in the top-left, so subtract half the height and width.
1305    perspectiveOriginX -= boxWidth / 2.0f;
1306    perspectiveOriginY -= boxHeight / 2.0f;
1307
1308    TransformationMatrix t;
1309    t.translate(perspectiveOriginX, perspectiveOriginY);
1310    t.applyPerspective(style.perspective());
1311    t.translate(-perspectiveOriginX, -perspectiveOriginY);
1312
1313    return t;
1314}
1315
1316FloatPoint RenderLayer::perspectiveOrigin() const
1317{
1318    if (!renderer().hasTransform())
1319        return FloatPoint();
1320
1321    const LayoutRect borderBox = toRenderBox(renderer()).borderBoxRect();
1322    const RenderStyle& style = renderer().style();
1323
1324    return FloatPoint(floatValueForLength(style.perspectiveOriginX(), borderBox.width()),
1325                      floatValueForLength(style.perspectiveOriginY(), borderBox.height()));
1326}
1327
1328RenderLayer* RenderLayer::stackingContainer() const
1329{
1330    RenderLayer* layer = parent();
1331    while (layer && !layer->isStackingContainer())
1332        layer = layer->parent();
1333
1334    ASSERT(!layer || layer->isStackingContainer());
1335    return layer;
1336}
1337
1338static inline bool isPositionedContainer(RenderLayer* layer)
1339{
1340    return layer->isRootLayer() || layer->renderer().isPositioned() || layer->hasTransform();
1341}
1342
1343static inline bool isFixedPositionedContainer(RenderLayer* layer)
1344{
1345    return layer->isRootLayer() || layer->hasTransform();
1346}
1347
1348RenderLayer* RenderLayer::enclosingPositionedAncestor() const
1349{
1350    RenderLayer* curr = parent();
1351    while (curr && !isPositionedContainer(curr))
1352        curr = curr->parent();
1353
1354    return curr;
1355}
1356
1357static RenderLayer* parentLayerCrossFrame(const RenderLayer* layer)
1358{
1359    ASSERT(layer);
1360    if (layer->parent())
1361        return layer->parent();
1362
1363    HTMLFrameOwnerElement* ownerElement = layer->renderer().document().ownerElement();
1364    if (!ownerElement)
1365        return 0;
1366
1367    RenderElement* ownerRenderer = ownerElement->renderer();
1368    if (!ownerRenderer)
1369        return 0;
1370
1371    return ownerRenderer->enclosingLayer();
1372}
1373
1374RenderLayer* RenderLayer::enclosingScrollableLayer() const
1375{
1376    for (RenderLayer* nextLayer = parentLayerCrossFrame(this); nextLayer; nextLayer = parentLayerCrossFrame(nextLayer)) {
1377        if (nextLayer->renderer().isBox() && toRenderBox(nextLayer->renderer()).canBeScrolledAndHasScrollableArea())
1378            return nextLayer;
1379    }
1380
1381    return 0;
1382}
1383
1384IntRect RenderLayer::scrollableAreaBoundingBox() const
1385{
1386    return renderer().absoluteBoundingBoxRect();
1387}
1388
1389bool RenderLayer::forceUpdateScrollbarsOnMainThreadForPerformanceTesting() const
1390{
1391    Page* page = renderer().frame().page();
1392    return page && page->settings().forceUpdateScrollbarsOnMainThreadForPerformanceTesting();
1393}
1394
1395RenderLayer* RenderLayer::enclosingTransformedAncestor() const
1396{
1397    RenderLayer* curr = parent();
1398    while (curr && !curr->isRootLayer() && !curr->transform())
1399        curr = curr->parent();
1400
1401    return curr;
1402}
1403
1404static inline const RenderLayer* compositingContainer(const RenderLayer* layer)
1405{
1406    return layer->isNormalFlowOnly() ? layer->parent() : layer->stackingContainer();
1407}
1408
1409inline bool RenderLayer::shouldRepaintAfterLayout() const
1410{
1411    if (m_repaintStatus == NeedsNormalRepaint)
1412        return true;
1413
1414    // Composited layers that were moved during a positioned movement only
1415    // layout, don't need to be repainted. They just need to be recomposited.
1416    ASSERT(m_repaintStatus == NeedsFullRepaintForPositionedMovementLayout);
1417    return !isComposited() || backing()->paintsIntoCompositedAncestor();
1418}
1419
1420static bool compositedWithOwnBackingStore(const RenderLayer* layer)
1421{
1422    return layer->isComposited() && !layer->backing()->paintsIntoCompositedAncestor();
1423}
1424
1425RenderLayer* RenderLayer::enclosingCompositingLayer(IncludeSelfOrNot includeSelf) const
1426{
1427    if (includeSelf == IncludeSelf && isComposited())
1428        return const_cast<RenderLayer*>(this);
1429
1430    for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) {
1431        if (curr->isComposited())
1432            return const_cast<RenderLayer*>(curr);
1433    }
1434
1435    return 0;
1436}
1437
1438RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(IncludeSelfOrNot includeSelf) const
1439{
1440    if (includeSelf == IncludeSelf && isComposited() && !backing()->paintsIntoCompositedAncestor())
1441        return const_cast<RenderLayer*>(this);
1442
1443    for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) {
1444        if (compositedWithOwnBackingStore(curr))
1445            return const_cast<RenderLayer*>(curr);
1446    }
1447
1448    return 0;
1449}
1450
1451#if ENABLE(CSS_FILTERS)
1452
1453RenderLayer* RenderLayer::enclosingFilterLayer(IncludeSelfOrNot includeSelf) const
1454{
1455    const RenderLayer* curr = (includeSelf == IncludeSelf) ? this : parent();
1456    for (; curr; curr = curr->parent()) {
1457        if (curr->requiresFullLayerImageForFilters())
1458            return const_cast<RenderLayer*>(curr);
1459    }
1460
1461    return 0;
1462}
1463
1464RenderLayer* RenderLayer::enclosingFilterRepaintLayer() const
1465{
1466    for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
1467        if ((curr != this && curr->requiresFullLayerImageForFilters()) || compositedWithOwnBackingStore(curr) || curr->isRootLayer())
1468            return const_cast<RenderLayer*>(curr);
1469    }
1470    return 0;
1471}
1472
1473void RenderLayer::setFilterBackendNeedsRepaintingInRect(const LayoutRect& rect)
1474{
1475    if (rect.isEmpty())
1476        return;
1477
1478    LayoutRect rectForRepaint = rect;
1479    renderer().style().filterOutsets().expandRect(rectForRepaint);
1480
1481    FilterInfo& filterInfo = FilterInfo::get(*this);
1482    filterInfo.expandDirtySourceRect(rectForRepaint);
1483
1484    RenderLayer* parentLayer = enclosingFilterRepaintLayer();
1485    ASSERT(parentLayer);
1486    FloatQuad repaintQuad(rectForRepaint);
1487    LayoutRect parentLayerRect = renderer().localToContainerQuad(repaintQuad, &parentLayer->renderer()).enclosingBoundingBox();
1488
1489    if (parentLayer->isComposited()) {
1490        if (!parentLayer->backing()->paintsIntoWindow()) {
1491            parentLayer->setBackingNeedsRepaintInRect(parentLayerRect);
1492            return;
1493        }
1494        // If the painting goes to window, redirect the painting to the parent RenderView.
1495        parentLayer = renderer().view().layer();
1496        parentLayerRect = renderer().localToContainerQuad(repaintQuad, &parentLayer->renderer()).enclosingBoundingBox();
1497    }
1498
1499    if (parentLayer->paintsWithFilters()) {
1500        parentLayer->setFilterBackendNeedsRepaintingInRect(parentLayerRect);
1501        return;
1502    }
1503
1504    if (parentLayer->isRootLayer()) {
1505        toRenderView(parentLayer->renderer()).repaintViewRectangle(parentLayerRect);
1506        return;
1507    }
1508
1509    ASSERT_NOT_REACHED();
1510}
1511
1512bool RenderLayer::hasAncestorWithFilterOutsets() const
1513{
1514    for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
1515        if (curr->renderer().style().hasFilterOutsets())
1516            return true;
1517    }
1518    return false;
1519}
1520
1521#endif
1522
1523RenderLayer* RenderLayer::clippingRootForPainting() const
1524{
1525    if (isComposited())
1526        return const_cast<RenderLayer*>(this);
1527
1528    const RenderLayer* current = this;
1529    while (current) {
1530        if (current->isRootLayer())
1531            return const_cast<RenderLayer*>(current);
1532
1533        current = compositingContainer(current);
1534        ASSERT(current);
1535        if (current->transform() || compositedWithOwnBackingStore(current))
1536            return const_cast<RenderLayer*>(current);
1537    }
1538
1539    ASSERT_NOT_REACHED();
1540    return 0;
1541}
1542
1543LayoutPoint RenderLayer::absoluteToContents(const LayoutPoint& absolutePoint) const
1544{
1545    // We don't use convertToLayerCoords because it doesn't know about transforms
1546    return roundedLayoutPoint(renderer().absoluteToLocal(absolutePoint, UseTransforms));
1547}
1548
1549bool RenderLayer::cannotBlitToWindow() const
1550{
1551    if (isTransparent() || hasReflection() || hasTransform())
1552        return true;
1553    if (!parent())
1554        return false;
1555    return parent()->cannotBlitToWindow();
1556}
1557
1558RenderLayer* RenderLayer::transparentPaintingAncestor()
1559{
1560    if (isComposited())
1561        return 0;
1562
1563    for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
1564        if (curr->isComposited())
1565            return 0;
1566        if (curr->isTransparent())
1567            return curr;
1568    }
1569    return 0;
1570}
1571
1572enum TransparencyClipBoxBehavior {
1573    PaintingTransparencyClipBox,
1574    HitTestingTransparencyClipBox
1575};
1576
1577enum TransparencyClipBoxMode {
1578    DescendantsOfTransparencyClipBox,
1579    RootOfTransparencyClipBox
1580};
1581
1582static LayoutRect transparencyClipBox(const RenderLayer&, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, PaintBehavior = 0);
1583
1584static void expandClipRectForRegionAndReflection(LayoutRect& clipRect, const RenderLayer& layer, const RenderLayer* rootLayer,
1585    TransparencyClipBoxBehavior transparencyBehavior, PaintBehavior paintBehavior)
1586{
1587    // If this is a region, then the painting is actually done by its flow thread's layer.
1588    if (layer.renderer().isRenderNamedFlowFragmentContainer()) {
1589        RenderBlockFlow* regionContainer = toRenderBlockFlow(&layer.renderer());
1590        RenderNamedFlowFragment* region = regionContainer->renderNamedFlowFragment();
1591        RenderLayer* flowThreadLayer = region->flowThread()->layer();
1592        if (flowThreadLayer && (!layer.reflection() || layer.reflectionLayer() != flowThreadLayer)) {
1593            LayoutRect flowThreadClipRect = transparencyClipBox(*flowThreadLayer, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior);
1594            LayoutSize moveOffset = (regionContainer->contentBoxRect().location() + layer.offsetFromAncestor(flowThreadLayer)) - region->flowThreadPortionRect().location();
1595            flowThreadClipRect.move(moveOffset);
1596
1597            clipRect.unite(flowThreadClipRect);
1598        }
1599    }
1600}
1601
1602static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer& layer, const RenderLayer* rootLayer,
1603    TransparencyClipBoxBehavior transparencyBehavior, PaintBehavior paintBehavior)
1604{
1605    // If we have a mask, then the clip is limited to the border box area (and there is
1606    // no need to examine child layers).
1607    if (!layer.renderer().hasMask()) {
1608        // Note: we don't have to walk z-order lists since transparent elements always establish
1609        // a stacking container. This means we can just walk the layer tree directly.
1610        for (RenderLayer* curr = layer.firstChild(); curr; curr = curr->nextSibling()) {
1611            if (!layer.reflection() || layer.reflectionLayer() != curr)
1612                clipRect.unite(transparencyClipBox(*curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior));
1613        }
1614    }
1615
1616    expandClipRectForRegionAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior);
1617
1618    // If we have a reflection, then we need to account for that when we push the clip.  Reflect our entire
1619    // current transparencyClipBox to catch all child layers.
1620    // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this
1621    // size into the parent layer.
1622    if (layer.renderer().hasReflection()) {
1623        LayoutSize delta = layer.offsetFromAncestor(rootLayer);
1624        clipRect.move(-delta);
1625        clipRect.unite(layer.renderBox()->reflectedRect(clipRect));
1626        clipRect.move(delta);
1627    }
1628}
1629
1630static LayoutRect transparencyClipBox(const RenderLayer& layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior,
1631    TransparencyClipBoxMode transparencyMode, PaintBehavior paintBehavior)
1632{
1633    // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
1634    // paintDirtyRect, and that should cut down on the amount we have to paint.  Still it
1635    // would be better to respect clips.
1636
1637    if (rootLayer != &layer && ((transparencyBehavior == PaintingTransparencyClipBox && layer.paintsWithTransform(paintBehavior))
1638        || (transparencyBehavior == HitTestingTransparencyClipBox && layer.hasTransform()))) {
1639        // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
1640        // the transformed layer and all of its children.
1641        RenderLayer::PaginationInclusionMode mode = transparencyBehavior == HitTestingTransparencyClipBox ? RenderLayer::IncludeCompositedPaginatedLayers : RenderLayer::ExcludeCompositedPaginatedLayers;
1642        const RenderLayer* paginationLayer = transparencyMode == DescendantsOfTransparencyClipBox ? layer.enclosingPaginationLayer(mode) : 0;
1643        const RenderLayer* rootLayerForTransform = paginationLayer ? paginationLayer : rootLayer;
1644        LayoutSize delta = layer.offsetFromAncestor(rootLayerForTransform);
1645
1646        TransformationMatrix transform;
1647        transform.translate(delta.width(), delta.height());
1648        transform = transform * *layer.transform();
1649
1650        // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
1651        // paints unfragmented.
1652        LayoutRect clipRect = layer.boundingBox(&layer);
1653        expandClipRectForDescendantsAndReflection(clipRect, layer, &layer, transparencyBehavior, paintBehavior);
1654#if ENABLE(CSS_FILTERS)
1655        layer.renderer().style().filterOutsets().expandRect(clipRect);
1656#endif
1657        LayoutRect result = transform.mapRect(clipRect);
1658        if (!paginationLayer)
1659            return result;
1660
1661        // We have to break up the transformed extent across our columns.
1662        // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
1663        // get our true bounding box.
1664        RenderFlowThread& enclosingFlowThread = toRenderFlowThread(paginationLayer->renderer());
1665        result = enclosingFlowThread.fragmentsBoundingBox(result);
1666        result.move(paginationLayer->offsetFromAncestor(rootLayer));
1667        return result;
1668    }
1669
1670    LayoutRect clipRect = layer.boundingBox(rootLayer, layer.offsetFromAncestor(rootLayer), transparencyBehavior == HitTestingTransparencyClipBox ? RenderLayer::UseFragmentBoxesIncludingCompositing : RenderLayer::UseFragmentBoxesExcludingCompositing);
1671    expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior);
1672#if ENABLE(CSS_FILTERS)
1673    layer.renderer().style().filterOutsets().expandRect(clipRect);
1674#endif
1675    return clipRect;
1676}
1677
1678static LayoutRect paintingExtent(const RenderLayer& currentLayer, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
1679{
1680    return intersection(transparencyClipBox(currentLayer, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect);
1681}
1682
1683void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, const LayoutRect& dirtyRect)
1684{
1685    if (context->paintingDisabled() || (paintsWithTransparency(paintingInfo.paintBehavior) && m_usedTransparency))
1686        return;
1687
1688    RenderLayer* ancestor = transparentPaintingAncestor();
1689    if (ancestor)
1690        ancestor->beginTransparencyLayers(context, paintingInfo, dirtyRect);
1691
1692    if (paintsWithTransparency(paintingInfo.paintBehavior)) {
1693        m_usedTransparency = true;
1694        context->save();
1695        LayoutRect adjustedClipRect = paintingExtent(*this, paintingInfo.rootLayer, dirtyRect, paintingInfo.paintBehavior);
1696        adjustedClipRect.move(paintingInfo.subpixelAccumulation);
1697        FloatRect pixelSnappedClipRect = pixelSnappedForPainting(adjustedClipRect, renderer().document().deviceScaleFactor());
1698        context->clip(pixelSnappedClipRect);
1699
1700#if ENABLE(CSS_COMPOSITING)
1701        if (hasBlendMode())
1702            context->setCompositeOperation(context->compositeOperation(), blendMode());
1703#endif
1704
1705        context->beginTransparencyLayer(renderer().opacity());
1706
1707#if ENABLE(CSS_COMPOSITING)
1708        if (hasBlendMode())
1709            context->setCompositeOperation(context->compositeOperation(), BlendModeNormal);
1710#endif
1711
1712#ifdef REVEAL_TRANSPARENCY_LAYERS
1713        context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f), ColorSpaceDeviceRGB);
1714        context->fillRect(pixelSnappedClipRect);
1715#endif
1716    }
1717}
1718
1719#if PLATFORM(IOS)
1720void RenderLayer::willBeDestroyed()
1721{
1722    if (RenderLayerBacking* layerBacking = backing())
1723        layerBacking->layerWillBeDestroyed();
1724}
1725#endif
1726
1727void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
1728{
1729    RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
1730    if (prevSibling) {
1731        child->setPreviousSibling(prevSibling);
1732        prevSibling->setNextSibling(child);
1733        ASSERT(prevSibling != child);
1734    } else
1735        setFirstChild(child);
1736
1737    if (beforeChild) {
1738        beforeChild->setPreviousSibling(child);
1739        child->setNextSibling(beforeChild);
1740        ASSERT(beforeChild != child);
1741    } else
1742        setLastChild(child);
1743
1744    child->setParent(this);
1745
1746    if (child->isNormalFlowOnly())
1747        dirtyNormalFlowList();
1748
1749    if (!child->isNormalFlowOnly() || child->firstChild()) {
1750        // Dirty the z-order list in which we are contained. The stackingContainer() can be null in the
1751        // case where we're building up generated content layers. This is ok, since the lists will start
1752        // off dirty in that case anyway.
1753        child->dirtyStackingContainerZOrderLists();
1754    }
1755
1756    child->updateDescendantDependentFlags();
1757    if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
1758        setAncestorChainHasVisibleDescendant();
1759
1760    if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant())
1761        setAncestorChainHasSelfPaintingLayerDescendant();
1762
1763    if (child->renderer().isOutOfFlowPositioned() || child->hasOutOfFlowPositionedDescendant())
1764        setAncestorChainHasOutOfFlowPositionedDescendant(child->renderer().containingBlock());
1765
1766#if ENABLE(CSS_COMPOSITING)
1767    if (child->hasBlendMode() || (child->hasNotIsolatedBlendingDescendants() && !child->isolatesBlending()))
1768        updateAncestorChainHasBlendingDescendants();
1769#endif
1770
1771    compositor().layerWasAdded(*this, *child);
1772}
1773
1774RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
1775{
1776    if (!renderer().documentBeingDestroyed())
1777        compositor().layerWillBeRemoved(*this, *oldChild);
1778
1779    // remove the child
1780    if (oldChild->previousSibling())
1781        oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
1782    if (oldChild->nextSibling())
1783        oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
1784
1785    if (m_first == oldChild)
1786        m_first = oldChild->nextSibling();
1787    if (m_last == oldChild)
1788        m_last = oldChild->previousSibling();
1789
1790    if (oldChild->isNormalFlowOnly())
1791        dirtyNormalFlowList();
1792    if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) {
1793        // Dirty the z-order list in which we are contained.  When called via the
1794        // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
1795        // from the main layer tree, so we need to null-check the |stackingContainer| value.
1796        oldChild->dirtyStackingContainerZOrderLists();
1797    }
1798
1799    if (oldChild->renderer().isOutOfFlowPositioned() || oldChild->hasOutOfFlowPositionedDescendant())
1800        dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
1801
1802    oldChild->setPreviousSibling(0);
1803    oldChild->setNextSibling(0);
1804    oldChild->setParent(0);
1805
1806    oldChild->updateDescendantDependentFlags();
1807    if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
1808        dirtyAncestorChainVisibleDescendantStatus();
1809
1810    if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescendant())
1811        dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
1812
1813#if ENABLE(CSS_COMPOSITING)
1814    if (oldChild->hasBlendMode() || (oldChild->hasNotIsolatedBlendingDescendants() && !oldChild->isolatesBlending()))
1815        dirtyAncestorChainHasBlendingDescendants();
1816#endif
1817
1818    return oldChild;
1819}
1820
1821void RenderLayer::removeOnlyThisLayer()
1822{
1823    if (!m_parent)
1824        return;
1825
1826    // Mark that we are about to lose our layer. This makes render tree
1827    // walks ignore this layer while we're removing it.
1828    renderer().setHasLayer(false);
1829
1830    compositor().layerWillBeRemoved(*m_parent, *this);
1831
1832    // Dirty the clip rects.
1833    clearClipRectsIncludingDescendants();
1834
1835    RenderLayer* nextSib = nextSibling();
1836
1837    // Remove the child reflection layer before moving other child layers.
1838    // The reflection layer should not be moved to the parent.
1839    if (reflection())
1840        removeChild(reflectionLayer());
1841
1842    // Now walk our kids and reattach them to our parent.
1843    RenderLayer* current = m_first;
1844    while (current) {
1845        RenderLayer* next = current->nextSibling();
1846        removeChild(current);
1847        m_parent->addChild(current, nextSib);
1848        current->setRepaintStatus(NeedsFullRepaint);
1849        // updateLayerPositions depends on hasLayer() already being false for proper layout.
1850        ASSERT(!renderer().hasLayer());
1851        current->updateLayerPositions(0); // FIXME: use geometry map.
1852        current = next;
1853    }
1854
1855    // Remove us from the parent.
1856    m_parent->removeChild(this);
1857    renderer().destroyLayer();
1858}
1859
1860void RenderLayer::insertOnlyThisLayer()
1861{
1862    if (!m_parent && renderer().parent()) {
1863        // We need to connect ourselves when our renderer() has a parent.
1864        // Find our enclosingLayer and add ourselves.
1865        RenderLayer* parentLayer = renderer().parent()->enclosingLayer();
1866        ASSERT(parentLayer);
1867        RenderLayer* beforeChild = parentLayer->reflectionLayer() != this ? renderer().parent()->findNextLayer(parentLayer, &renderer()) : 0;
1868        parentLayer->addChild(this, beforeChild);
1869    }
1870
1871    // Remove all descendant layers from the hierarchy and add them to the new position.
1872    for (auto& child : childrenOfType<RenderElement>(renderer()))
1873        child.moveLayers(m_parent, this);
1874
1875    // Clear out all the clip rects.
1876    clearClipRectsIncludingDescendants();
1877}
1878
1879void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& roundedLocation, ColumnOffsetAdjustment adjustForColumns) const
1880{
1881    LayoutPoint location = convertToLayerCoords(ancestorLayer, roundedLocation, adjustForColumns);
1882    roundedLocation = roundedIntPoint(location);
1883}
1884
1885// Returns the layer reached on the walk up towards the ancestor.
1886static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutPoint& location, RenderLayer::ColumnOffsetAdjustment adjustForColumns)
1887{
1888    ASSERT(ancestorLayer != layer);
1889
1890    const RenderLayerModelObject& renderer = layer->renderer();
1891    EPosition position = renderer.style().position();
1892
1893    // FIXME: Special casing RenderFlowThread so much for fixed positioning here is not great.
1894    RenderFlowThread* fixedFlowThreadContainer = position == FixedPosition ? renderer.flowThreadContainingBlock() : 0;
1895    if (fixedFlowThreadContainer && !fixedFlowThreadContainer->isOutOfFlowPositioned())
1896        fixedFlowThreadContainer = 0;
1897
1898    // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in a RenderFlowThread
1899    // may need to be revisited in a future patch.
1900    // If the fixed renderer is inside a RenderFlowThread, we should not compute location using localToAbsolute,
1901    // since localToAbsolute maps the coordinates from named flow to regions coordinates and regions can be
1902    // positioned in a completely different place in the viewport (RenderView).
1903    if (position == FixedPosition && !fixedFlowThreadContainer && (!ancestorLayer || ancestorLayer == renderer.view().layer())) {
1904        // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
1905        // localToAbsolute() on the RenderView.
1906        FloatPoint absPos = renderer.localToAbsolute(FloatPoint(), IsFixed);
1907        location += LayoutSize(absPos.x(), absPos.y());
1908        return ancestorLayer;
1909    }
1910
1911    // For the fixed positioned elements inside a render flow thread, we should also skip the code path below
1912    // Otherwise, for the case of ancestorLayer == rootLayer and fixed positioned element child of a transformed
1913    // element in render flow thread, we will hit the fixed positioned container before hitting the ancestor layer.
1914    if (position == FixedPosition && !fixedFlowThreadContainer) {
1915        // For a fixed layers, we need to walk up to the root to see if there's a fixed position container
1916        // (e.g. a transformed layer). It's an error to call offsetFromAncestor() across a layer with a transform,
1917        // so we should always find the ancestor at or before we find the fixed position container.
1918        RenderLayer* fixedPositionContainerLayer = 0;
1919        bool foundAncestor = false;
1920        for (RenderLayer* currLayer = layer->parent(); currLayer; currLayer = currLayer->parent()) {
1921            if (currLayer == ancestorLayer)
1922                foundAncestor = true;
1923
1924            if (isFixedPositionedContainer(currLayer)) {
1925                fixedPositionContainerLayer = currLayer;
1926                ASSERT_UNUSED(foundAncestor, foundAncestor);
1927                break;
1928            }
1929        }
1930
1931        ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least.
1932
1933        if (fixedPositionContainerLayer != ancestorLayer) {
1934            LayoutSize fixedContainerCoords = layer->offsetFromAncestor(fixedPositionContainerLayer);
1935            LayoutSize ancestorCoords = ancestorLayer->offsetFromAncestor(fixedPositionContainerLayer);
1936            location += (fixedContainerCoords - ancestorCoords);
1937            return ancestorLayer;
1938        }
1939    }
1940
1941    if (position == FixedPosition && fixedFlowThreadContainer) {
1942        ASSERT(ancestorLayer);
1943        if (ancestorLayer->isOutOfFlowRenderFlowThread()) {
1944            location += toLayoutSize(layer->location());
1945            return ancestorLayer;
1946        }
1947
1948        if (ancestorLayer == renderer.view().layer()) {
1949            // Add location in flow thread coordinates.
1950            location += toLayoutSize(layer->location());
1951
1952            // Add flow thread offset in view coordinates since the view may be scrolled.
1953            FloatPoint absPos = renderer.view().localToAbsolute(FloatPoint(), IsFixed);
1954            location += LayoutSize(absPos.x(), absPos.y());
1955            return ancestorLayer;
1956        }
1957    }
1958
1959    RenderLayer* parentLayer;
1960    if (position == AbsolutePosition || position == FixedPosition) {
1961        // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way.
1962        parentLayer = layer->parent();
1963        bool foundAncestorFirst = false;
1964        while (parentLayer) {
1965            // RenderFlowThread is a positioned container, child of RenderView, positioned at (0,0).
1966            // This implies that, for out-of-flow positioned elements inside a RenderFlowThread,
1967            // we are bailing out before reaching root layer.
1968            if (isPositionedContainer(parentLayer))
1969                break;
1970
1971            if (parentLayer == ancestorLayer) {
1972                foundAncestorFirst = true;
1973                break;
1974            }
1975
1976            parentLayer = parentLayer->parent();
1977        }
1978
1979        // We should not reach RenderView layer past the RenderFlowThread layer for any
1980        // children of the RenderFlowThread.
1981        if (renderer.flowThreadContainingBlock() && !layer->isOutOfFlowRenderFlowThread())
1982            ASSERT(parentLayer != renderer.view().layer());
1983
1984        if (foundAncestorFirst) {
1985            // Found ancestorLayer before the abs. positioned container, so compute offset of both relative
1986            // to enclosingPositionedAncestor and subtract.
1987            RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAncestor();
1988            LayoutSize thisCoords = layer->offsetFromAncestor(positionedAncestor);
1989            LayoutSize ancestorCoords = ancestorLayer->offsetFromAncestor(positionedAncestor);
1990            location += (thisCoords - ancestorCoords);
1991            return ancestorLayer;
1992        }
1993    } else
1994        parentLayer = layer->parent();
1995
1996    if (!parentLayer)
1997        return 0;
1998
1999    location += toLayoutSize(layer->location());
2000
2001    if (adjustForColumns == RenderLayer::AdjustForColumns) {
2002        if (RenderLayer* parentLayer = layer->parent()) {
2003            if (parentLayer->renderer().isRenderMultiColumnFlowThread()) {
2004                RenderRegion* region = toRenderMultiColumnFlowThread(parentLayer->renderer()).physicalTranslationFromFlowToRegion(location);
2005                if (region)
2006                    location.moveBy(region->topLeftLocation() + -parentLayer->renderBox()->topLeftLocation());
2007            }
2008        }
2009    }
2010
2011    return parentLayer;
2012}
2013
2014LayoutPoint RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, const LayoutPoint& location, ColumnOffsetAdjustment adjustForColumns) const
2015{
2016    if (ancestorLayer == this)
2017        return location;
2018
2019    const RenderLayer* currLayer = this;
2020    LayoutPoint locationInLayerCoords = location;
2021    while (currLayer && currLayer != ancestorLayer)
2022        currLayer = accumulateOffsetTowardsAncestor(currLayer, ancestorLayer, locationInLayerCoords, adjustForColumns);
2023    return locationInLayerCoords;
2024}
2025
2026LayoutSize RenderLayer::offsetFromAncestor(const RenderLayer* ancestorLayer) const
2027{
2028    return toLayoutSize(convertToLayerCoords(ancestorLayer, LayoutPoint()));
2029}
2030
2031#if PLATFORM(IOS)
2032bool RenderLayer::hasAcceleratedTouchScrolling() const
2033{
2034#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
2035    if (!scrollsOverflow())
2036        return false;
2037
2038    Settings* settings = renderer().document().settings();
2039    // FIXME: settings should not be null at this point. If you find a reliable way to hit this assertion, please file a bug.
2040    // See <rdar://problem/10266101>.
2041    ASSERT(settings);
2042
2043    return renderer().style().useTouchOverflowScrolling() || (settings && settings->alwaysUseAcceleratedOverflowScroll());
2044#else
2045    return false;
2046#endif
2047}
2048
2049bool RenderLayer::hasTouchScrollableOverflow() const
2050{
2051    return hasAcceleratedTouchScrolling() && (hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
2052}
2053
2054#if ENABLE(TOUCH_EVENTS)
2055bool RenderLayer::handleTouchEvent(const PlatformTouchEvent& touchEvent)
2056{
2057    // If we have accelerated scrolling, let the scrolling be handled outside of WebKit.
2058    if (hasTouchScrollableOverflow())
2059        return false;
2060
2061    return ScrollableArea::handleTouchEvent(touchEvent);
2062}
2063#endif
2064
2065void RenderLayer::registerAsTouchEventListenerForScrolling()
2066{
2067    if (!renderer().element() || m_registeredAsTouchEventListenerForScrolling)
2068        return;
2069
2070    renderer().document().addTouchEventListener(renderer().element());
2071    m_registeredAsTouchEventListenerForScrolling = true;
2072}
2073
2074void RenderLayer::unregisterAsTouchEventListenerForScrolling()
2075{
2076    if (!renderer().element() || !m_registeredAsTouchEventListenerForScrolling)
2077        return;
2078
2079    renderer().document().removeTouchEventListener(renderer().element());
2080    m_registeredAsTouchEventListenerForScrolling = false;
2081}
2082#endif // PLATFORM(IOS)
2083
2084bool RenderLayer::usesCompositedScrolling() const
2085{
2086    return isComposited() && backing()->scrollingLayer();
2087}
2088
2089bool RenderLayer::needsCompositedScrolling() const
2090{
2091    return m_needsCompositedScrolling;
2092}
2093
2094void RenderLayer::updateNeedsCompositedScrolling()
2095{
2096    bool oldNeedsCompositedScrolling = m_needsCompositedScrolling;
2097
2098    if (!renderer().view().frameView().containsScrollableArea(this))
2099        m_needsCompositedScrolling = false;
2100    else {
2101        bool forceUseCompositedScrolling = acceleratedCompositingForOverflowScrollEnabled()
2102            && canBeStackingContainer()
2103            && !hasOutOfFlowPositionedDescendant();
2104
2105#if !PLATFORM(IOS) && ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
2106        m_needsCompositedScrolling = forceUseCompositedScrolling || renderer().style().useTouchOverflowScrolling();
2107#else
2108        // On iOS we don't want to opt into accelerated composited scrolling, which creates scroll bar
2109        // layers in WebCore, because we use UIKit to composite our scroll bars.
2110        m_needsCompositedScrolling = forceUseCompositedScrolling;
2111#endif
2112    }
2113
2114    if (oldNeedsCompositedScrolling != m_needsCompositedScrolling) {
2115        updateSelfPaintingLayer();
2116        if (isStackingContainer())
2117            dirtyZOrderLists();
2118        else
2119            clearZOrderLists();
2120
2121        dirtyStackingContainerZOrderLists();
2122
2123        compositor().setShouldReevaluateCompositingAfterLayout();
2124        compositor().setCompositingLayersNeedRebuild();
2125    }
2126}
2127
2128static inline int adjustedScrollDelta(int beginningDelta) {
2129    // This implemention matches Firefox's.
2130    // http://mxr.mozilla.org/firefox/source/toolkit/content/widgets/browser.xml#856.
2131    const int speedReducer = 12;
2132
2133    int adjustedDelta = beginningDelta / speedReducer;
2134    if (adjustedDelta > 1)
2135        adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(adjustedDelta))) - 1;
2136    else if (adjustedDelta < -1)
2137        adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(-adjustedDelta))) + 1;
2138
2139    return adjustedDelta;
2140}
2141
2142static inline IntSize adjustedScrollDelta(const IntSize& delta)
2143{
2144    return IntSize(adjustedScrollDelta(delta.width()), adjustedScrollDelta(delta.height()));
2145}
2146
2147void RenderLayer::panScrollFromPoint(const IntPoint& sourcePoint)
2148{
2149    IntPoint lastKnownMousePosition = renderer().frame().eventHandler().lastKnownMousePosition();
2150
2151    // 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
2152    static IntPoint previousMousePosition;
2153    if (lastKnownMousePosition.x() < 0 || lastKnownMousePosition.y() < 0)
2154        lastKnownMousePosition = previousMousePosition;
2155    else
2156        previousMousePosition = lastKnownMousePosition;
2157
2158    IntSize delta = lastKnownMousePosition - sourcePoint;
2159
2160    if (abs(delta.width()) <= ScrollView::noPanScrollRadius) // at the center we let the space for the icon
2161        delta.setWidth(0);
2162    if (abs(delta.height()) <= ScrollView::noPanScrollRadius)
2163        delta.setHeight(0);
2164
2165    scrollByRecursively(adjustedScrollDelta(delta), ScrollOffsetClamped);
2166}
2167
2168void RenderLayer::scrollByRecursively(const IntSize& delta, ScrollOffsetClamping clamp, ScrollableArea** scrolledArea)
2169{
2170    if (delta.isZero())
2171        return;
2172
2173    bool restrictedByLineClamp = false;
2174    if (renderer().parent())
2175        restrictedByLineClamp = !renderer().parent()->style().lineClamp().isNone();
2176
2177    if (renderer().hasOverflowClip() && !restrictedByLineClamp) {
2178        IntSize newScrollOffset = scrollOffset() + delta;
2179        scrollToOffset(newScrollOffset, clamp);
2180        if (scrolledArea)
2181            *scrolledArea = this;
2182
2183        // If this layer can't do the scroll we ask the next layer up that can scroll to try
2184        IntSize remainingScrollOffset = newScrollOffset - scrollOffset();
2185        if (!remainingScrollOffset.isZero() && renderer().parent()) {
2186            if (RenderLayer* scrollableLayer = enclosingScrollableLayer())
2187                scrollableLayer->scrollByRecursively(remainingScrollOffset, clamp, scrolledArea);
2188
2189            renderer().frame().eventHandler().updateAutoscrollRenderer();
2190        }
2191    } else {
2192        // If we are here, we were called on a renderer that can be programmatically scrolled, but doesn't
2193        // have an overflow clip. Which means that it is a document node that can be scrolled.
2194        renderer().view().frameView().scrollBy(delta);
2195        if (scrolledArea)
2196            *scrolledArea = &renderer().view().frameView();
2197
2198        // FIXME: If we didn't scroll the whole way, do we want to try looking at the frames ownerElement?
2199        // https://bugs.webkit.org/show_bug.cgi?id=28237
2200    }
2201}
2202
2203IntSize RenderLayer::clampScrollOffset(const IntSize& scrollOffset) const
2204{
2205    RenderBox* box = renderBox();
2206    ASSERT(box);
2207
2208    int maxX = scrollWidth() - box->pixelSnappedClientWidth();
2209    int maxY = scrollHeight() - box->pixelSnappedClientHeight();
2210
2211    int x = std::max(std::min(scrollOffset.width(), maxX), 0);
2212    int y = std::max(std::min(scrollOffset.height(), maxY), 0);
2213    return IntSize(x, y);
2214}
2215
2216void RenderLayer::scrollToOffset(const IntSize& scrollOffset, ScrollOffsetClamping clamp)
2217{
2218    IntSize newScrollOffset = clamp == ScrollOffsetClamped ? clampScrollOffset(scrollOffset) : scrollOffset;
2219    if (newScrollOffset != this->scrollOffset())
2220        scrollToOffsetWithoutAnimation(IntPoint(newScrollOffset));
2221}
2222
2223void RenderLayer::scrollTo(int x, int y)
2224{
2225    RenderBox* box = renderBox();
2226    if (!box)
2227        return;
2228
2229    if (box->style().overflowX() != OMARQUEE) {
2230        // Ensure that the dimensions will be computed if they need to be (for overflow:hidden blocks).
2231        if (m_scrollDimensionsDirty)
2232            computeScrollDimensions();
2233#if PLATFORM(IOS)
2234        if (adjustForIOSCaretWhenScrolling()) {
2235            int maxX = scrollWidth() - box->clientWidth();
2236            if (x > maxX - caretWidth) {
2237                x += caretWidth;
2238                if (x <= caretWidth)
2239                    x = 0;
2240            } else if (x < m_scrollOffset.width() - caretWidth)
2241                x -= caretWidth;
2242        }
2243#endif
2244    }
2245
2246    // FIXME: Eventually, we will want to perform a blit.  For now never
2247    // blit, since the check for blitting is going to be very
2248    // complicated (since it will involve testing whether our layer
2249    // is either occluded by another layer or clipped by an enclosing
2250    // layer or contains fixed backgrounds, etc.).
2251    IntSize newScrollOffset = IntSize(x - scrollOrigin().x(), y - scrollOrigin().y());
2252    if (m_scrollOffset == newScrollOffset) {
2253#if PLATFORM(IOS)
2254        if (m_requiresScrollBoundsOriginUpdate)
2255            updateCompositingLayersAfterScroll();
2256#endif
2257        return;
2258    }
2259
2260    IntPoint oldPosition = IntPoint(m_scrollOffset);
2261    m_scrollOffset = newScrollOffset;
2262
2263    InspectorInstrumentation::willScrollLayer(&renderer().frame());
2264
2265    RenderView& view = renderer().view();
2266
2267    // Update the positions of our child layers (if needed as only fixed layers should be impacted by a scroll).
2268    // We don't update compositing layers, because we need to do a deep update from the compositing ancestor.
2269    bool inLayout = view.frameView().isInLayout();
2270    if (!inLayout) {
2271        // If we're in the middle of layout, we'll just update layers once layout has finished.
2272        updateLayerPositionsAfterOverflowScroll();
2273        // Update regions, scrolling may change the clip of a particular region.
2274#if ENABLE(DASHBOARD_SUPPORT)
2275        view.frameView().updateAnnotatedRegions();
2276#endif
2277        view.frameView().updateWidgetPositions();
2278
2279        if (!m_updatingMarqueePosition) {
2280            // Avoid updating compositing layers if, higher on the stack, we're already updating layer
2281            // positions. Updating layer positions requires a full walk of up-to-date RenderLayers, and
2282            // in this case we're still updating their positions; we'll update compositing layers later
2283            // when that completes.
2284            updateCompositingLayersAfterScroll();
2285        }
2286
2287#if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS)
2288        renderer().document().dirtyTouchEventRects();
2289#endif
2290    }
2291
2292    Frame& frame = renderer().frame();
2293    RenderLayerModelObject* repaintContainer = renderer().containerForRepaint();
2294    // The caret rect needs to be invalidated after scrolling
2295    frame.selection().setCaretRectNeedsUpdate();
2296
2297    FloatQuad quadForFakeMouseMoveEvent = FloatQuad(m_repaintRect);
2298    if (repaintContainer)
2299        quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
2300    frame.eventHandler().dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
2301
2302    bool requiresRepaint = true;
2303    if (compositor().inCompositingMode() && usesCompositedScrolling())
2304        requiresRepaint = false;
2305
2306    // Just schedule a full repaint of our object.
2307    if (requiresRepaint)
2308        renderer().repaintUsingContainer(repaintContainer, m_repaintRect);
2309
2310    // Schedule the scroll and scroll-related DOM events.
2311    if (Element* element = renderer().element()) {
2312        element->document().eventQueue().enqueueOrDispatchScrollEvent(*element);
2313        element->document().sendWillRevealEdgeEventsIfNeeded(oldPosition, IntPoint(newScrollOffset), visibleContentRect(), contentsSize(), element);
2314    }
2315
2316    InspectorInstrumentation::didScrollLayer(&frame);
2317    if (scrollsOverflow())
2318        frame.loader().client().didChangeScrollOffset();
2319
2320    view.frameView().resumeVisibleImageAnimationsIncludingSubframes();
2321}
2322
2323static inline bool frameElementAndViewPermitScroll(HTMLFrameElementBase* frameElementBase, FrameView* frameView)
2324{
2325    // If scrollbars aren't explicitly forbidden, permit scrolling.
2326    if (frameElementBase && frameElementBase->scrollingMode() != ScrollbarAlwaysOff)
2327        return true;
2328
2329    // If scrollbars are forbidden, user initiated scrolls should obviously be ignored.
2330    if (frameView->wasScrolledByUser())
2331        return false;
2332
2333    // Forbid autoscrolls when scrollbars are off, but permits other programmatic scrolls,
2334    // like navigation to an anchor.
2335    return !frameView->frame().eventHandler().autoscrollInProgress();
2336}
2337
2338void RenderLayer::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
2339{
2340    RenderLayer* parentLayer = 0;
2341    LayoutRect newRect = rect;
2342
2343    // We may end up propagating a scroll event. It is important that we suspend events until
2344    // the end of the function since they could delete the layer or the layer's renderer().
2345    FrameView& frameView = renderer().view().frameView();
2346
2347    bool restrictedByLineClamp = false;
2348    if (renderer().parent()) {
2349        parentLayer = renderer().parent()->enclosingLayer();
2350        restrictedByLineClamp = !renderer().parent()->style().lineClamp().isNone();
2351    }
2352
2353    if (renderer().hasOverflowClip() && !restrictedByLineClamp) {
2354        // Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
2355        // This will prevent us from revealing text hidden by the slider in Safari RSS.
2356        RenderBox* box = renderBox();
2357        ASSERT(box);
2358        LayoutRect localExposeRect(box->absoluteToLocalQuad(FloatQuad(FloatRect(rect)), UseTransforms).boundingBox());
2359        LayoutRect layerBounds(0, 0, box->clientWidth(), box->clientHeight());
2360        LayoutRect r = getRectToExpose(layerBounds, layerBounds, localExposeRect, alignX, alignY);
2361
2362        IntSize clampedScrollOffset = clampScrollOffset(scrollOffset() + toIntSize(roundedIntRect(r).location()));
2363        if (clampedScrollOffset != scrollOffset()) {
2364            IntSize oldScrollOffset = scrollOffset();
2365            scrollToOffset(clampedScrollOffset);
2366            IntSize scrollOffsetDifference = scrollOffset() - oldScrollOffset;
2367            localExposeRect.move(-scrollOffsetDifference);
2368            newRect = LayoutRect(box->localToAbsoluteQuad(FloatQuad(FloatRect(localExposeRect)), UseTransforms).boundingBox());
2369        }
2370    } else if (!parentLayer && renderer().isBox() && renderBox()->canBeProgramaticallyScrolled()) {
2371        Element* ownerElement = renderer().document().ownerElement();
2372
2373        if (ownerElement && ownerElement->renderer()) {
2374            HTMLFrameElementBase* frameElementBase = 0;
2375
2376            if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))
2377                frameElementBase = toHTMLFrameElementBase(ownerElement);
2378
2379            if (frameElementAndViewPermitScroll(frameElementBase, &frameView)) {
2380                LayoutRect viewRect = frameView.visibleContentRect(LegacyIOSDocumentVisibleRect);
2381                LayoutRect exposeRect = getRectToExpose(viewRect, viewRect, rect, alignX, alignY);
2382
2383                int xOffset = roundToInt(exposeRect.x());
2384                int yOffset = roundToInt(exposeRect.y());
2385                // Adjust offsets if they're outside of the allowable range.
2386                xOffset = std::max(0, std::min(frameView.contentsWidth(), xOffset));
2387                yOffset = std::max(0, std::min(frameView.contentsHeight(), yOffset));
2388
2389                frameView.setScrollPosition(IntPoint(xOffset, yOffset));
2390                if (frameView.safeToPropagateScrollToParent()) {
2391                    parentLayer = ownerElement->renderer()->enclosingLayer();
2392                    // FIXME: This doesn't correctly convert the rect to
2393                    // absolute coordinates in the parent.
2394                    newRect.setX(rect.x() - frameView.scrollX() + frameView.x());
2395                    newRect.setY(rect.y() - frameView.scrollY() + frameView.y());
2396                } else
2397                    parentLayer = 0;
2398            }
2399        } else {
2400#if !PLATFORM(IOS)
2401            LayoutRect viewRect = frameView.visibleContentRect();
2402            LayoutRect visibleRectRelativeToDocument = viewRect;
2403            IntSize documentScrollOffsetRelativeToScrollableAreaOrigin = frameView.documentScrollOffsetRelativeToScrollableAreaOrigin();
2404            visibleRectRelativeToDocument.setLocation(IntPoint(documentScrollOffsetRelativeToScrollableAreaOrigin.width(), documentScrollOffsetRelativeToScrollableAreaOrigin.height()));
2405#else
2406            LayoutRect viewRect = frameView.unobscuredContentRect();
2407            LayoutRect visibleRectRelativeToDocument = viewRect;
2408#endif
2409
2410            LayoutRect r = getRectToExpose(viewRect, visibleRectRelativeToDocument, rect, alignX, alignY);
2411
2412            frameView.setScrollPosition(roundedIntPoint(r.location()));
2413
2414            // This is the outermost view of a web page, so after scrolling this view we
2415            // scroll its container by calling Page::scrollRectIntoView.
2416            // This only has an effect on the Mac platform in applications
2417            // that put web views into scrolling containers, such as Mac OS X Mail.
2418            // The canAutoscroll function in EventHandler also knows about this.
2419            if (Page* page = frameView.frame().page())
2420                page->chrome().scrollRectIntoView(pixelSnappedIntRect(rect));
2421        }
2422    }
2423
2424    if (renderer().frame().eventHandler().autoscrollInProgress())
2425        parentLayer = enclosingScrollableLayer();
2426
2427    if (parentLayer)
2428        parentLayer->scrollRectToVisible(newRect, alignX, alignY);
2429}
2430
2431void RenderLayer::updateCompositingLayersAfterScroll()
2432{
2433    if (compositor().inCompositingMode()) {
2434        // Our stacking container is guaranteed to contain all of our descendants that may need
2435        // repositioning, so update compositing layers from there.
2436        if (RenderLayer* compositingAncestor = stackingContainer()->enclosingCompositingLayer()) {
2437            if (usesCompositedScrolling() && !hasOutOfFlowPositionedDescendant())
2438                compositor().updateCompositingLayers(CompositingUpdateOnCompositedScroll, compositingAncestor);
2439            else
2440                compositor().updateCompositingLayers(CompositingUpdateOnScroll, compositingAncestor);
2441        }
2442    }
2443}
2444
2445LayoutRect RenderLayer::getRectToExpose(const LayoutRect &visibleRect, const LayoutRect &visibleRectRelativeToDocument, const LayoutRect &exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
2446{
2447    // Determine the appropriate X behavior.
2448    ScrollBehavior scrollX;
2449    LayoutRect exposeRectX(exposeRect.x(), visibleRect.y(), exposeRect.width(), visibleRect.height());
2450    LayoutUnit intersectWidth = intersection(visibleRect, exposeRectX).width();
2451    if (intersectWidth == exposeRect.width() || intersectWidth >= MIN_INTERSECT_FOR_REVEAL)
2452        // If the rectangle is fully visible, use the specified visible behavior.
2453        // If the rectangle is partially visible, but over a certain threshold,
2454        // then treat it as fully visible to avoid unnecessary horizontal scrolling
2455        scrollX = ScrollAlignment::getVisibleBehavior(alignX);
2456    else if (intersectWidth == visibleRect.width()) {
2457        // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
2458        scrollX = ScrollAlignment::getVisibleBehavior(alignX);
2459        if (scrollX == alignCenter)
2460            scrollX = noScroll;
2461    } else if (intersectWidth > 0)
2462        // If the rectangle is partially visible, but not above the minimum threshold, use the specified partial behavior
2463        scrollX = ScrollAlignment::getPartialBehavior(alignX);
2464    else
2465        scrollX = ScrollAlignment::getHiddenBehavior(alignX);
2466    // If we're trying to align to the closest edge, and the exposeRect is further right
2467    // than the visibleRect, and not bigger than the visible area, then align with the right.
2468    if (scrollX == alignToClosestEdge && exposeRect.maxX() > visibleRect.maxX() && exposeRect.width() < visibleRect.width())
2469        scrollX = alignRight;
2470
2471    // Given the X behavior, compute the X coordinate.
2472    LayoutUnit x;
2473    if (scrollX == noScroll)
2474        x = visibleRect.x();
2475    else if (scrollX == alignRight)
2476        x = exposeRect.maxX() - visibleRect.width();
2477    else if (scrollX == alignCenter)
2478        x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2;
2479    else
2480        x = exposeRect.x();
2481
2482    // Determine the appropriate Y behavior.
2483    ScrollBehavior scrollY;
2484    LayoutRect exposeRectY(visibleRect.x(), exposeRect.y(), visibleRect.width(), exposeRect.height());
2485    LayoutUnit intersectHeight = intersection(visibleRectRelativeToDocument, exposeRectY).height();
2486    if (intersectHeight == exposeRect.height())
2487        // If the rectangle is fully visible, use the specified visible behavior.
2488        scrollY = ScrollAlignment::getVisibleBehavior(alignY);
2489    else if (intersectHeight == visibleRect.height()) {
2490        // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
2491        scrollY = ScrollAlignment::getVisibleBehavior(alignY);
2492        if (scrollY == alignCenter)
2493            scrollY = noScroll;
2494    } else if (intersectHeight > 0)
2495        // If the rectangle is partially visible, use the specified partial behavior
2496        scrollY = ScrollAlignment::getPartialBehavior(alignY);
2497    else
2498        scrollY = ScrollAlignment::getHiddenBehavior(alignY);
2499    // If we're trying to align to the closest edge, and the exposeRect is further down
2500    // than the visibleRect, and not bigger than the visible area, then align with the bottom.
2501    if (scrollY == alignToClosestEdge && exposeRect.maxY() > visibleRect.maxY() && exposeRect.height() < visibleRect.height())
2502        scrollY = alignBottom;
2503
2504    // Given the Y behavior, compute the Y coordinate.
2505    LayoutUnit y;
2506    if (scrollY == noScroll)
2507        y = visibleRect.y();
2508    else if (scrollY == alignBottom)
2509        y = exposeRect.maxY() - visibleRect.height();
2510    else if (scrollY == alignCenter)
2511        y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2;
2512    else
2513        y = exposeRect.y();
2514
2515    return LayoutRect(LayoutPoint(x, y), visibleRect.size());
2516}
2517
2518void RenderLayer::autoscroll(const IntPoint& position)
2519{
2520    IntPoint currentDocumentPosition = renderer().view().frameView().windowToContents(position);
2521    scrollRectToVisible(LayoutRect(currentDocumentPosition, LayoutSize(1, 1)), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
2522}
2523
2524bool RenderLayer::canResize() const
2525{
2526    // We need a special case for <iframe> because they never have
2527    // hasOverflowClip(). However, they do "implicitly" clip their contents, so
2528    // we want to allow resizing them also.
2529    return (renderer().hasOverflowClip() || renderer().isRenderIFrame()) && renderer().style().resize() != RESIZE_NONE;
2530}
2531
2532void RenderLayer::resize(const PlatformMouseEvent& evt, const LayoutSize& oldOffset)
2533{
2534    // FIXME: This should be possible on generated content but is not right now.
2535    if (!inResizeMode() || !canResize() || !renderer().element())
2536        return;
2537
2538    // FIXME: The only case where renderer->element()->renderer() != renderer is with continuations. Do they matter here?
2539    // If they do it would still be better to deal with them explicitly.
2540    Element* element = renderer().element();
2541    RenderBox* renderer = toRenderBox(element->renderer());
2542
2543    Document& document = element->document();
2544    if (!document.frame()->eventHandler().mousePressed())
2545        return;
2546
2547    float zoomFactor = renderer->style().effectiveZoom();
2548
2549    LayoutSize newOffset = offsetFromResizeCorner(document.view()->windowToContents(evt.position()));
2550    newOffset.setWidth(newOffset.width() / zoomFactor);
2551    newOffset.setHeight(newOffset.height() / zoomFactor);
2552
2553    LayoutSize currentSize = LayoutSize(renderer->width() / zoomFactor, renderer->height() / zoomFactor);
2554    LayoutSize minimumSize = element->minimumSizeForResizing().shrunkTo(currentSize);
2555    element->setMinimumSizeForResizing(minimumSize);
2556
2557    LayoutSize adjustedOldOffset = LayoutSize(oldOffset.width() / zoomFactor, oldOffset.height() / zoomFactor);
2558    if (renderer->style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
2559        newOffset.setWidth(-newOffset.width());
2560        adjustedOldOffset.setWidth(-adjustedOldOffset.width());
2561    }
2562
2563    LayoutSize difference = (currentSize + newOffset - adjustedOldOffset).expandedTo(minimumSize) - currentSize;
2564
2565    StyledElement* styledElement = toStyledElement(element);
2566    bool isBoxSizingBorder = renderer->style().boxSizing() == BORDER_BOX;
2567
2568    EResize resize = renderer->style().resize();
2569    if (resize != RESIZE_VERTICAL && difference.width()) {
2570        if (element->isFormControlElement()) {
2571            // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
2572            styledElement->setInlineStyleProperty(CSSPropertyMarginLeft, renderer->marginLeft() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2573            styledElement->setInlineStyleProperty(CSSPropertyMarginRight, renderer->marginRight() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2574        }
2575        LayoutUnit baseWidth = renderer->width() - (isBoxSizingBorder ? LayoutUnit() : renderer->horizontalBorderAndPaddingExtent());
2576        baseWidth = baseWidth / zoomFactor;
2577        styledElement->setInlineStyleProperty(CSSPropertyWidth, roundToInt(baseWidth + difference.width()), CSSPrimitiveValue::CSS_PX);
2578    }
2579
2580    if (resize != RESIZE_HORIZONTAL && difference.height()) {
2581        if (element->isFormControlElement()) {
2582            // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
2583            styledElement->setInlineStyleProperty(CSSPropertyMarginTop, renderer->marginTop() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2584            styledElement->setInlineStyleProperty(CSSPropertyMarginBottom, renderer->marginBottom() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2585        }
2586        LayoutUnit baseHeight = renderer->height() - (isBoxSizingBorder ? LayoutUnit() : renderer->verticalBorderAndPaddingExtent());
2587        baseHeight = baseHeight / zoomFactor;
2588        styledElement->setInlineStyleProperty(CSSPropertyHeight, roundToInt(baseHeight + difference.height()), CSSPrimitiveValue::CSS_PX);
2589    }
2590
2591    document.updateLayout();
2592
2593    // FIXME (Radar 4118564): We should also autoscroll the window as necessary to keep the point under the cursor in view.
2594}
2595
2596int RenderLayer::scrollSize(ScrollbarOrientation orientation) const
2597{
2598    Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_hBar : m_vBar).get();
2599    return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
2600}
2601
2602void RenderLayer::setScrollOffset(const IntPoint& offset)
2603{
2604    scrollTo(offset.x(), offset.y());
2605}
2606
2607int RenderLayer::scrollPosition(Scrollbar* scrollbar) const
2608{
2609    if (scrollbar->orientation() == HorizontalScrollbar)
2610        return scrollXOffset();
2611    if (scrollbar->orientation() == VerticalScrollbar)
2612        return scrollYOffset();
2613    return 0;
2614}
2615
2616IntPoint RenderLayer::scrollPosition() const
2617{
2618    return IntPoint(m_scrollOffset);
2619}
2620
2621IntPoint RenderLayer::minimumScrollPosition() const
2622{
2623    return -scrollOrigin();
2624}
2625
2626IntPoint RenderLayer::maximumScrollPosition() const
2627{
2628    // FIXME: m_scrollSize may not be up-to-date if m_scrollDimensionsDirty is true.
2629    return -scrollOrigin() + roundedIntSize(m_scrollSize) - visibleContentRectIncludingScrollbars(ContentsVisibleRect).size();
2630}
2631
2632IntRect RenderLayer::visibleContentRectInternal(VisibleContentRectIncludesScrollbars scrollbarInclusion, VisibleContentRectBehavior) const
2633{
2634    int verticalScrollbarWidth = 0;
2635    int horizontalScrollbarHeight = 0;
2636    if (showsOverflowControls() && scrollbarInclusion == IncludeScrollbars) {
2637        verticalScrollbarWidth = (verticalScrollbar() && !verticalScrollbar()->isOverlayScrollbar()) ? verticalScrollbar()->width() : 0;
2638        horizontalScrollbarHeight = (horizontalScrollbar() && !horizontalScrollbar()->isOverlayScrollbar()) ? horizontalScrollbar()->height() : 0;
2639    }
2640
2641    return IntRect(IntPoint(scrollXOffset(), scrollYOffset()),
2642                   IntSize(std::max(0, m_layerSize.width() - verticalScrollbarWidth),
2643                           std::max(0, m_layerSize.height() - horizontalScrollbarHeight)));
2644}
2645
2646IntSize RenderLayer::overhangAmount() const
2647{
2648    return IntSize();
2649}
2650
2651bool RenderLayer::isActive() const
2652{
2653    Page* page = renderer().frame().page();
2654    return page && page->focusController().isActive();
2655}
2656
2657static int cornerStart(const RenderLayer* layer, int minX, int maxX, int thickness)
2658{
2659    if (layer->renderer().style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
2660        return minX + layer->renderer().style().borderLeftWidth();
2661    return maxX - thickness - layer->renderer().style().borderRightWidth();
2662}
2663
2664static LayoutRect cornerRect(const RenderLayer* layer, const LayoutRect& bounds)
2665{
2666    int horizontalThickness;
2667    int verticalThickness;
2668    if (!layer->verticalScrollbar() && !layer->horizontalScrollbar()) {
2669        // FIXME: This isn't right.  We need to know the thickness of custom scrollbars
2670        // even when they don't exist in order to set the resizer square size properly.
2671        horizontalThickness = ScrollbarTheme::theme()->scrollbarThickness();
2672        verticalThickness = horizontalThickness;
2673    } else if (layer->verticalScrollbar() && !layer->horizontalScrollbar()) {
2674        horizontalThickness = layer->verticalScrollbar()->width();
2675        verticalThickness = horizontalThickness;
2676    } else if (layer->horizontalScrollbar() && !layer->verticalScrollbar()) {
2677        verticalThickness = layer->horizontalScrollbar()->height();
2678        horizontalThickness = verticalThickness;
2679    } else {
2680        horizontalThickness = layer->verticalScrollbar()->width();
2681        verticalThickness = layer->horizontalScrollbar()->height();
2682    }
2683    return LayoutRect(cornerStart(layer, bounds.x(), bounds.maxX(), horizontalThickness),
2684        bounds.maxY() - verticalThickness - layer->renderer().style().borderBottomWidth(),
2685        horizontalThickness, verticalThickness);
2686}
2687
2688IntRect RenderLayer::scrollCornerRect() const
2689{
2690    // We have a scrollbar corner when a scrollbar is visible and not filling the entire length of the box.
2691    // This happens when:
2692    // (a) A resizer is present and at least one scrollbar is present
2693    // (b) Both scrollbars are present.
2694    bool hasHorizontalBar = horizontalScrollbar();
2695    bool hasVerticalBar = verticalScrollbar();
2696    bool hasResizer = renderer().style().resize() != RESIZE_NONE;
2697    if ((hasHorizontalBar && hasVerticalBar) || (hasResizer && (hasHorizontalBar || hasVerticalBar)))
2698        return pixelSnappedIntRect(cornerRect(this, renderBox()->borderBoxRect()));
2699    return IntRect();
2700}
2701
2702static LayoutRect resizerCornerRect(const RenderLayer* layer, const LayoutRect& bounds)
2703{
2704    ASSERT(layer->renderer().isBox());
2705    if (layer->renderer().style().resize() == RESIZE_NONE)
2706        return LayoutRect();
2707    return cornerRect(layer, bounds);
2708}
2709
2710LayoutRect RenderLayer::scrollCornerAndResizerRect() const
2711{
2712    RenderBox* box = renderBox();
2713    if (!box)
2714        return LayoutRect();
2715    LayoutRect scrollCornerAndResizer = scrollCornerRect();
2716    if (scrollCornerAndResizer.isEmpty())
2717        scrollCornerAndResizer = resizerCornerRect(this, box->borderBoxRect());
2718    return scrollCornerAndResizer;
2719}
2720
2721bool RenderLayer::isScrollCornerVisible() const
2722{
2723    ASSERT(renderer().isBox());
2724    return !scrollCornerRect().isEmpty();
2725}
2726
2727IntRect RenderLayer::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
2728{
2729    IntRect rect = scrollbarRect;
2730    rect.move(scrollbarOffset(scrollbar));
2731
2732    return renderer().view().frameView().convertFromRendererToContainingView(&renderer(), rect);
2733}
2734
2735IntRect RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
2736{
2737    IntRect rect = renderer().view().frameView().convertFromContainingViewToRenderer(&renderer(), parentRect);
2738    rect.move(-scrollbarOffset(scrollbar));
2739    return rect;
2740}
2741
2742IntPoint RenderLayer::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
2743{
2744    IntPoint point = scrollbarPoint;
2745    point.move(scrollbarOffset(scrollbar));
2746    return renderer().view().frameView().convertFromRendererToContainingView(&renderer(), point);
2747}
2748
2749IntPoint RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
2750{
2751    IntPoint point = renderer().view().frameView().convertFromContainingViewToRenderer(&renderer(), parentPoint);
2752    point.move(-scrollbarOffset(scrollbar));
2753    return point;
2754}
2755
2756IntSize RenderLayer::visibleSize() const
2757{
2758    if (!renderer().isBox())
2759        return IntSize();
2760
2761    return IntSize(renderBox()->pixelSnappedClientWidth(), renderBox()->pixelSnappedClientHeight());
2762}
2763
2764IntSize RenderLayer::contentsSize() const
2765{
2766    return IntSize(scrollWidth(), scrollHeight());
2767}
2768
2769IntSize RenderLayer::scrollableContentsSize() const
2770{
2771    IntSize contentsSize = this->contentsSize();
2772
2773    if (!hasScrollableHorizontalOverflow())
2774        contentsSize.setWidth(std::min(contentsSize.width(), visibleSize().width()));
2775
2776    if (!hasScrollableVerticalOverflow())
2777        contentsSize.setHeight(std::min(contentsSize.height(), visibleSize().height()));
2778
2779    return contentsSize;
2780}
2781
2782bool RenderLayer::shouldSuspendScrollAnimations() const
2783{
2784    return renderer().view().frameView().shouldSuspendScrollAnimations();
2785}
2786
2787#if PLATFORM(IOS)
2788void RenderLayer::didStartScroll()
2789{
2790    if (Page* page = renderer().frame().page())
2791        page->chrome().client().didStartOverflowScroll();
2792}
2793
2794void RenderLayer::didEndScroll()
2795{
2796    if (Page* page = renderer().frame().page())
2797        page->chrome().client().didEndOverflowScroll();
2798}
2799
2800void RenderLayer::didUpdateScroll()
2801{
2802    // Send this notification when we scroll, since this is how we keep selection updated.
2803    if (Page* page = renderer().frame().page())
2804        page->chrome().client().didLayout(ChromeClient::Scroll);
2805}
2806#endif
2807
2808IntPoint RenderLayer::lastKnownMousePosition() const
2809{
2810    return renderer().frame().eventHandler().lastKnownMousePosition();
2811}
2812
2813bool RenderLayer::isHandlingWheelEvent() const
2814{
2815    return renderer().frame().eventHandler().isHandlingWheelEvent();
2816}
2817
2818IntRect RenderLayer::rectForHorizontalScrollbar(const IntRect& borderBoxRect) const
2819{
2820    if (!m_hBar)
2821        return IntRect();
2822
2823    const RenderBox* box = renderBox();
2824    const IntRect& scrollCorner = scrollCornerRect();
2825
2826    return IntRect(horizontalScrollbarStart(borderBoxRect.x()),
2827        borderBoxRect.maxY() - box->borderBottom() - m_hBar->height(),
2828        borderBoxRect.width() - (box->borderLeft() + box->borderRight()) - scrollCorner.width(),
2829        m_hBar->height());
2830}
2831
2832IntRect RenderLayer::rectForVerticalScrollbar(const IntRect& borderBoxRect) const
2833{
2834    if (!m_vBar)
2835        return IntRect();
2836
2837    const RenderBox* box = renderBox();
2838    const IntRect& scrollCorner = scrollCornerRect();
2839
2840    return IntRect(verticalScrollbarStart(borderBoxRect.x(), borderBoxRect.maxX()),
2841        borderBoxRect.y() + box->borderTop(),
2842        m_vBar->width(),
2843        borderBoxRect.height() - (box->borderTop() + box->borderBottom()) - scrollCorner.height());
2844}
2845
2846LayoutUnit RenderLayer::verticalScrollbarStart(int minX, int maxX) const
2847{
2848    const RenderBox* box = renderBox();
2849    if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
2850        return minX + box->borderLeft();
2851    return maxX - box->borderRight() - m_vBar->width();
2852}
2853
2854LayoutUnit RenderLayer::horizontalScrollbarStart(int minX) const
2855{
2856    const RenderBox* box = renderBox();
2857    int x = minX + box->borderLeft();
2858    if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
2859        x += m_vBar ? m_vBar->width() : roundToInt(resizerCornerRect(this, box->borderBoxRect()).width());
2860    return x;
2861}
2862
2863IntSize RenderLayer::scrollbarOffset(const Scrollbar* scrollbar) const
2864{
2865    RenderBox* box = renderBox();
2866
2867    if (scrollbar == m_vBar.get())
2868        return IntSize(verticalScrollbarStart(0, box->width()), box->borderTop());
2869
2870    if (scrollbar == m_hBar.get())
2871        return IntSize(horizontalScrollbarStart(0), box->height() - box->borderBottom() - scrollbar->height());
2872
2873    ASSERT_NOT_REACHED();
2874    return IntSize();
2875}
2876
2877void RenderLayer::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
2878{
2879    if (!showsOverflowControls())
2880        return;
2881
2882    if (scrollbar == m_vBar.get()) {
2883        if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
2884            layer->setNeedsDisplayInRect(rect);
2885            return;
2886        }
2887    } else {
2888        if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
2889            layer->setNeedsDisplayInRect(rect);
2890            return;
2891        }
2892    }
2893
2894    IntRect scrollRect = rect;
2895    RenderBox* box = renderBox();
2896    ASSERT(box);
2897    // If we are not yet inserted into the tree, there is no need to repaint.
2898    if (!box->parent())
2899        return;
2900
2901    if (scrollbar == m_vBar.get())
2902        scrollRect.move(verticalScrollbarStart(0, box->width()), box->borderTop());
2903    else
2904        scrollRect.move(horizontalScrollbarStart(0), box->height() - box->borderBottom() - scrollbar->height());
2905    LayoutRect repaintRect = scrollRect;
2906    renderBox()->flipForWritingMode(repaintRect);
2907    renderer().repaintRectangle(repaintRect);
2908}
2909
2910void RenderLayer::invalidateScrollCornerRect(const IntRect& rect)
2911{
2912    if (!showsOverflowControls())
2913        return;
2914
2915    if (GraphicsLayer* layer = layerForScrollCorner()) {
2916        layer->setNeedsDisplayInRect(rect);
2917        return;
2918    }
2919
2920    if (m_scrollCorner)
2921        m_scrollCorner->repaintRectangle(rect);
2922    if (m_resizer)
2923        m_resizer->repaintRectangle(rect);
2924}
2925
2926static inline RenderElement* rendererForScrollbar(RenderLayerModelObject& renderer)
2927{
2928    if (Element* element = renderer.element()) {
2929        if (ShadowRoot* shadowRoot = element->containingShadowRoot()) {
2930            if (shadowRoot->type() == ShadowRoot::UserAgentShadowRoot)
2931                return shadowRoot->hostElement()->renderer();
2932        }
2933    }
2934
2935    return &renderer;
2936}
2937
2938PassRefPtr<Scrollbar> RenderLayer::createScrollbar(ScrollbarOrientation orientation)
2939{
2940    RefPtr<Scrollbar> widget;
2941    RenderElement* actualRenderer = rendererForScrollbar(renderer());
2942    bool hasCustomScrollbarStyle = actualRenderer->isBox() && actualRenderer->style().hasPseudoStyle(SCROLLBAR);
2943    if (hasCustomScrollbarStyle)
2944        widget = RenderScrollbar::createCustomScrollbar(this, orientation, actualRenderer->element());
2945    else {
2946        widget = Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
2947        didAddScrollbar(widget.get(), orientation);
2948    }
2949    renderer().view().frameView().addChild(widget.get());
2950    return widget.release();
2951}
2952
2953void RenderLayer::destroyScrollbar(ScrollbarOrientation orientation)
2954{
2955    RefPtr<Scrollbar>& scrollbar = orientation == HorizontalScrollbar ? m_hBar : m_vBar;
2956    if (!scrollbar)
2957        return;
2958
2959    if (!scrollbar->isCustomScrollbar())
2960        willRemoveScrollbar(scrollbar.get(), orientation);
2961
2962    scrollbar->removeFromParent();
2963    scrollbar->disconnectFromScrollableArea();
2964    scrollbar = 0;
2965}
2966
2967bool RenderLayer::scrollsOverflow() const
2968{
2969    if (!renderer().isBox())
2970        return false;
2971
2972    return toRenderBox(renderer()).scrollsOverflow();
2973}
2974
2975void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
2976{
2977    if (hasScrollbar == hasHorizontalScrollbar())
2978        return;
2979
2980    if (hasScrollbar)
2981        m_hBar = createScrollbar(HorizontalScrollbar);
2982    else
2983        destroyScrollbar(HorizontalScrollbar);
2984
2985    // Destroying or creating one bar can cause our scrollbar corner to come and go.  We need to update the opposite scrollbar's style.
2986    if (m_hBar)
2987        m_hBar->styleChanged();
2988    if (m_vBar)
2989        m_vBar->styleChanged();
2990
2991    // Force an update since we know the scrollbars have changed things.
2992#if ENABLE(DASHBOARD_SUPPORT)
2993    if (renderer().document().hasAnnotatedRegions())
2994        renderer().document().setAnnotatedRegionsDirty(true);
2995#endif
2996}
2997
2998void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
2999{
3000    if (hasScrollbar == hasVerticalScrollbar())
3001        return;
3002
3003    if (hasScrollbar)
3004        m_vBar = createScrollbar(VerticalScrollbar);
3005    else
3006        destroyScrollbar(VerticalScrollbar);
3007
3008     // Destroying or creating one bar can cause our scrollbar corner to come and go.  We need to update the opposite scrollbar's style.
3009    if (m_hBar)
3010        m_hBar->styleChanged();
3011    if (m_vBar)
3012        m_vBar->styleChanged();
3013
3014    // Force an update since we know the scrollbars have changed things.
3015#if ENABLE(DASHBOARD_SUPPORT)
3016    if (renderer().document().hasAnnotatedRegions())
3017        renderer().document().setAnnotatedRegionsDirty(true);
3018#endif
3019}
3020
3021ScrollableArea* RenderLayer::enclosingScrollableArea() const
3022{
3023    if (RenderLayer* scrollableLayer = enclosingScrollableLayer())
3024        return scrollableLayer;
3025
3026    // FIXME: We should return the frame view here (or possibly an ancestor frame view,
3027    // if the frame view isn't scrollable.
3028    return 0;
3029}
3030
3031int RenderLayer::verticalScrollbarWidth(OverlayScrollbarSizeRelevancy relevancy) const
3032{
3033    if (!m_vBar
3034        || !showsOverflowControls()
3035        || (m_vBar->isOverlayScrollbar() && (relevancy == IgnoreOverlayScrollbarSize || !m_vBar->shouldParticipateInHitTesting())))
3036        return 0;
3037
3038    return m_vBar->width();
3039}
3040
3041int RenderLayer::horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy relevancy) const
3042{
3043    if (!m_hBar
3044        || !showsOverflowControls()
3045        || (m_hBar->isOverlayScrollbar() && (relevancy == IgnoreOverlayScrollbarSize || !m_hBar->shouldParticipateInHitTesting())))
3046        return 0;
3047
3048    return m_hBar->height();
3049}
3050
3051IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& absolutePoint) const
3052{
3053    // Currently the resize corner is either the bottom right corner or the bottom left corner.
3054    // FIXME: This assumes the location is 0, 0. Is this guaranteed to always be the case?
3055    IntSize elementSize = size();
3056    if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
3057        elementSize.setWidth(0);
3058    IntPoint resizerPoint = IntPoint(elementSize);
3059    IntPoint localPoint = roundedIntPoint(absoluteToContents(absolutePoint));
3060    return localPoint - resizerPoint;
3061}
3062
3063bool RenderLayer::hasOverflowControls() const
3064{
3065    return m_hBar || m_vBar || m_scrollCorner || renderer().style().resize() != RESIZE_NONE;
3066}
3067
3068void RenderLayer::positionOverflowControls(const IntSize& offsetFromRoot)
3069{
3070    if (!m_hBar && !m_vBar && !canResize())
3071        return;
3072
3073    RenderBox* box = renderBox();
3074    if (!box)
3075        return;
3076
3077    const IntRect borderBox = box->pixelSnappedBorderBoxRect();
3078    const IntRect& scrollCorner = scrollCornerRect();
3079    IntRect absBounds(borderBox.location() + offsetFromRoot, borderBox.size());
3080    if (m_vBar) {
3081        IntRect vBarRect = rectForVerticalScrollbar(borderBox);
3082        vBarRect.move(offsetFromRoot);
3083        m_vBar->setFrameRect(vBarRect);
3084    }
3085
3086    if (m_hBar) {
3087        IntRect hBarRect = rectForHorizontalScrollbar(borderBox);
3088        hBarRect.move(offsetFromRoot);
3089        m_hBar->setFrameRect(hBarRect);
3090    }
3091
3092    if (m_scrollCorner)
3093        m_scrollCorner->setFrameRect(scrollCorner);
3094    if (m_resizer)
3095        m_resizer->setFrameRect(resizerCornerRect(this, borderBox));
3096
3097    if (isComposited())
3098        backing()->positionOverflowControlsLayers();
3099}
3100
3101int RenderLayer::scrollWidth() const
3102{
3103    ASSERT(renderBox());
3104    if (m_scrollDimensionsDirty)
3105        const_cast<RenderLayer*>(this)->computeScrollDimensions();
3106    return snapSizeToPixel(m_scrollSize.width(), renderBox()->clientLeft() + renderBox()->x());
3107}
3108
3109int RenderLayer::scrollHeight() const
3110{
3111    ASSERT(renderBox());
3112    if (m_scrollDimensionsDirty)
3113        const_cast<RenderLayer*>(this)->computeScrollDimensions();
3114    return snapSizeToPixel(m_scrollSize.height(), renderBox()->clientTop() + renderBox()->y());
3115}
3116
3117LayoutUnit RenderLayer::overflowTop() const
3118{
3119    RenderBox* box = renderBox();
3120    LayoutRect overflowRect(box->layoutOverflowRect());
3121    box->flipForWritingMode(overflowRect);
3122    return overflowRect.y();
3123}
3124
3125LayoutUnit RenderLayer::overflowBottom() const
3126{
3127    RenderBox* box = renderBox();
3128    LayoutRect overflowRect(box->layoutOverflowRect());
3129    box->flipForWritingMode(overflowRect);
3130    return overflowRect.maxY();
3131}
3132
3133LayoutUnit RenderLayer::overflowLeft() const
3134{
3135    RenderBox* box = renderBox();
3136    LayoutRect overflowRect(box->layoutOverflowRect());
3137    box->flipForWritingMode(overflowRect);
3138    return overflowRect.x();
3139}
3140
3141LayoutUnit RenderLayer::overflowRight() const
3142{
3143    RenderBox* box = renderBox();
3144    LayoutRect overflowRect(box->layoutOverflowRect());
3145    box->flipForWritingMode(overflowRect);
3146    return overflowRect.maxX();
3147}
3148
3149void RenderLayer::computeScrollDimensions()
3150{
3151    RenderBox* box = renderBox();
3152    ASSERT(box);
3153
3154    m_scrollDimensionsDirty = false;
3155
3156    m_scrollSize.setWidth(overflowRight() - overflowLeft());
3157    m_scrollSize.setHeight(overflowBottom() - overflowTop());
3158
3159    int scrollableLeftOverflow = overflowLeft() - box->borderLeft();
3160    int scrollableTopOverflow = overflowTop() - box->borderTop();
3161    setScrollOrigin(IntPoint(-scrollableLeftOverflow, -scrollableTopOverflow));
3162}
3163
3164bool RenderLayer::hasScrollableHorizontalOverflow() const
3165{
3166    return hasHorizontalOverflow() && renderBox()->scrollsOverflowX();
3167}
3168
3169bool RenderLayer::hasScrollableVerticalOverflow() const
3170{
3171    return hasVerticalOverflow() && renderBox()->scrollsOverflowY();
3172}
3173
3174bool RenderLayer::hasHorizontalOverflow() const
3175{
3176    ASSERT(!m_scrollDimensionsDirty);
3177
3178    return scrollWidth() > renderBox()->pixelSnappedClientWidth();
3179}
3180
3181bool RenderLayer::hasVerticalOverflow() const
3182{
3183    ASSERT(!m_scrollDimensionsDirty);
3184
3185    return scrollHeight() > renderBox()->pixelSnappedClientHeight();
3186}
3187
3188void RenderLayer::updateScrollbarsAfterLayout()
3189{
3190    RenderBox* box = renderBox();
3191    ASSERT(box);
3192
3193    // List box parts handle the scrollbars by themselves so we have nothing to do.
3194    if (box->style().appearance() == ListboxPart)
3195        return;
3196
3197    bool hasHorizontalOverflow = this->hasHorizontalOverflow();
3198    bool hasVerticalOverflow = this->hasVerticalOverflow();
3199
3200    // overflow:scroll should just enable/disable.
3201    if (renderer().style().overflowX() == OSCROLL)
3202        m_hBar->setEnabled(hasHorizontalOverflow);
3203    if (renderer().style().overflowY() == OSCROLL)
3204        m_vBar->setEnabled(hasVerticalOverflow);
3205
3206    // overflow:auto may need to lay out again if scrollbars got added/removed.
3207    bool autoHorizontalScrollBarChanged = box->hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow);
3208    bool autoVerticalScrollBarChanged = box->hasAutoVerticalScrollbar() && (hasVerticalScrollbar() != hasVerticalOverflow);
3209
3210    if (autoHorizontalScrollBarChanged || autoVerticalScrollBarChanged) {
3211        if (box->hasAutoHorizontalScrollbar())
3212            setHasHorizontalScrollbar(hasHorizontalOverflow);
3213        if (box->hasAutoVerticalScrollbar())
3214            setHasVerticalScrollbar(hasVerticalOverflow);
3215
3216        updateSelfPaintingLayer();
3217
3218        // Force an update since we know the scrollbars have changed things.
3219#if ENABLE(DASHBOARD_SUPPORT)
3220        if (renderer().document().hasAnnotatedRegions())
3221            renderer().document().setAnnotatedRegionsDirty(true);
3222#endif
3223
3224        renderer().repaint();
3225
3226        if (renderer().style().overflowX() == OAUTO || renderer().style().overflowY() == OAUTO) {
3227            if (!m_inOverflowRelayout) {
3228                // Our proprietary overflow: overlay value doesn't trigger a layout.
3229                m_inOverflowRelayout = true;
3230                renderer().setNeedsLayout(MarkOnlyThis);
3231                if (renderer().isRenderBlock()) {
3232                    RenderBlock& block = toRenderBlock(renderer());
3233                    block.scrollbarsChanged(autoHorizontalScrollBarChanged, autoVerticalScrollBarChanged);
3234                    block.layoutBlock(true);
3235                } else
3236                    renderer().layout();
3237                m_inOverflowRelayout = false;
3238            }
3239        }
3240    }
3241
3242    // Set up the range (and page step/line step).
3243    if (m_hBar) {
3244        int clientWidth = box->pixelSnappedClientWidth();
3245        int pageStep = std::max(std::max<int>(clientWidth * Scrollbar::minFractionToStepWhenPaging(), clientWidth - Scrollbar::maxOverlapBetweenPages()), 1);
3246        m_hBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
3247        m_hBar->setProportion(clientWidth, m_scrollSize.width().round());
3248    }
3249    if (m_vBar) {
3250        int clientHeight = box->pixelSnappedClientHeight();
3251        int pageStep = std::max(std::max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1);
3252        m_vBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
3253        m_vBar->setProportion(clientHeight, m_scrollSize.height().round());
3254    }
3255
3256    updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
3257}
3258
3259void RenderLayer::updateScrollInfoAfterLayout()
3260{
3261    RenderBox* box = renderBox();
3262    if (!box)
3263        return;
3264
3265    m_scrollDimensionsDirty = true;
3266    IntSize originalScrollOffset = scrollOffset();
3267
3268    computeScrollDimensions();
3269
3270    if (box->style().overflowX() != OMARQUEE) {
3271        // Layout may cause us to be at an invalid scroll position. In this case we need
3272        // to pull our scroll offsets back to the max (or push them up to the min).
3273        IntSize clampedScrollOffset = clampScrollOffset(scrollOffset());
3274#if PLATFORM(IOS)
3275        // FIXME: This looks wrong. The caret adjust mode should only be enabled on editing related entry points.
3276        // This code was added to fix an issue where the text insertion point would always be drawn on the right edge
3277        // of a text field whose content overflowed its bounds. See <rdar://problem/15579797> for more details.
3278        setAdjustForIOSCaretWhenScrolling(true);
3279#endif
3280        if (clampedScrollOffset != scrollOffset())
3281            scrollToOffset(clampedScrollOffset);
3282
3283#if PLATFORM(IOS)
3284        setAdjustForIOSCaretWhenScrolling(false);
3285#endif
3286    }
3287
3288    updateScrollbarsAfterLayout();
3289
3290    if (originalScrollOffset != scrollOffset())
3291        scrollToOffsetWithoutAnimation(IntPoint(scrollOffset()));
3292
3293    // Composited scrolling may need to be enabled or disabled if the amount of overflow changed.
3294    if (compositor().updateLayerCompositingState(*this))
3295        compositor().setCompositingLayersNeedRebuild();
3296}
3297
3298bool RenderLayer::overflowControlsIntersectRect(const IntRect& localRect) const
3299{
3300    const IntRect borderBox = renderBox()->pixelSnappedBorderBoxRect();
3301
3302    if (rectForHorizontalScrollbar(borderBox).intersects(localRect))
3303        return true;
3304
3305    if (rectForVerticalScrollbar(borderBox).intersects(localRect))
3306        return true;
3307
3308    if (scrollCornerRect().intersects(localRect))
3309        return true;
3310
3311    if (resizerCornerRect(this, borderBox).intersects(localRect))
3312        return true;
3313
3314    return false;
3315}
3316
3317bool RenderLayer::showsOverflowControls() const
3318{
3319#if PLATFORM(IOS)
3320    // Don't render (custom) scrollbars if we have accelerated scrolling.
3321    if (hasAcceleratedTouchScrolling())
3322        return false;
3323#endif
3324
3325    return true;
3326}
3327
3328void RenderLayer::paintOverflowControls(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayControls)
3329{
3330    // Don't do anything if we have no overflow.
3331    if (!renderer().hasOverflowClip())
3332        return;
3333
3334    if (!showsOverflowControls())
3335        return;
3336
3337    // Overlay scrollbars paint in a second pass through the layer tree so that they will paint
3338    // on top of everything else. If this is the normal painting pass, paintingOverlayControls
3339    // will be false, and we should just tell the root layer that there are overlay scrollbars
3340    // that need to be painted. That will cause the second pass through the layer tree to run,
3341    // and we'll paint the scrollbars then. In the meantime, cache tx and ty so that the
3342    // second pass doesn't need to re-enter the RenderTree to get it right.
3343    if (hasOverlayScrollbars() && !paintingOverlayControls) {
3344        m_cachedOverlayScrollbarOffset = paintOffset;
3345
3346        // It's not necessary to do the second pass if the scrollbars paint into layers.
3347        if ((m_hBar && layerForHorizontalScrollbar()) || (m_vBar && layerForVerticalScrollbar()))
3348            return;
3349        IntRect localDamgeRect = damageRect;
3350        localDamgeRect.moveBy(-paintOffset);
3351        if (!overflowControlsIntersectRect(localDamgeRect))
3352            return;
3353
3354        RenderLayer* paintingRoot = enclosingCompositingLayer();
3355        if (!paintingRoot)
3356            paintingRoot = renderer().view().layer();
3357
3358        paintingRoot->setContainsDirtyOverlayScrollbars(true);
3359        return;
3360    }
3361
3362    // This check is required to avoid painting custom CSS scrollbars twice.
3363    if (paintingOverlayControls && !hasOverlayScrollbars())
3364        return;
3365
3366    IntPoint adjustedPaintOffset = paintOffset;
3367    if (paintingOverlayControls)
3368        adjustedPaintOffset = m_cachedOverlayScrollbarOffset;
3369
3370    // Move the scrollbar widgets if necessary.  We normally move and resize widgets during layout, but sometimes
3371    // widgets can move without layout occurring (most notably when you scroll a document that
3372    // contains fixed positioned elements).
3373    positionOverflowControls(toIntSize(adjustedPaintOffset));
3374
3375    // Now that we're sure the scrollbars are in the right place, paint them.
3376    if (m_hBar && !layerForHorizontalScrollbar())
3377        m_hBar->paint(context, damageRect);
3378    if (m_vBar && !layerForVerticalScrollbar())
3379        m_vBar->paint(context, damageRect);
3380
3381    if (layerForScrollCorner())
3382        return;
3383
3384    // We fill our scroll corner with white if we have a scrollbar that doesn't run all the way up to the
3385    // edge of the box.
3386    paintScrollCorner(context, adjustedPaintOffset, damageRect);
3387
3388    // Paint our resizer last, since it sits on top of the scroll corner.
3389    paintResizer(context, adjustedPaintOffset, damageRect);
3390}
3391
3392void RenderLayer::paintScrollCorner(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect)
3393{
3394    RenderBox* box = renderBox();
3395    ASSERT(box);
3396
3397    IntRect absRect = scrollCornerRect();
3398    absRect.moveBy(paintOffset);
3399    if (!absRect.intersects(damageRect))
3400        return;
3401
3402    if (context->updatingControlTints()) {
3403        updateScrollCornerStyle();
3404        return;
3405    }
3406
3407    if (m_scrollCorner) {
3408        m_scrollCorner->paintIntoRect(context, paintOffset, absRect);
3409        return;
3410    }
3411
3412    // We don't want to paint white if we have overlay scrollbars, since we need
3413    // to see what is behind it.
3414    if (!hasOverlayScrollbars())
3415        context->fillRect(absRect, Color::white, box->style().colorSpace());
3416}
3417
3418void RenderLayer::drawPlatformResizerImage(GraphicsContext* context, const LayoutRect& resizerCornerRect)
3419{
3420    RefPtr<Image> resizeCornerImage;
3421    FloatSize cornerResizerSize;
3422    if (renderer().document().deviceScaleFactor() >= 2) {
3423        DEPRECATED_DEFINE_STATIC_LOCAL(Image*, resizeCornerImageHiRes, (Image::loadPlatformResource("textAreaResizeCorner@2x").leakRef()));
3424        resizeCornerImage = resizeCornerImageHiRes;
3425        cornerResizerSize = resizeCornerImage->size();
3426        cornerResizerSize.scale(0.5f);
3427    } else {
3428        DEPRECATED_DEFINE_STATIC_LOCAL(Image*, resizeCornerImageLoRes, (Image::loadPlatformResource("textAreaResizeCorner").leakRef()));
3429        resizeCornerImage = resizeCornerImageLoRes;
3430        cornerResizerSize = resizeCornerImage->size();
3431    }
3432
3433    if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
3434        context->save();
3435        context->translate(resizerCornerRect.x() + cornerResizerSize.width(), resizerCornerRect.y() + resizerCornerRect.height() - cornerResizerSize.height());
3436        context->scale(FloatSize(-1.0, 1.0));
3437        context->drawImage(resizeCornerImage.get(), renderer().style().colorSpace(), FloatRect(FloatPoint(), cornerResizerSize));
3438        context->restore();
3439        return;
3440    }
3441    FloatRect imageRect = pixelSnappedForPainting(LayoutRect(resizerCornerRect.maxXMaxYCorner() - cornerResizerSize, cornerResizerSize), renderer().document().deviceScaleFactor());
3442    context->drawImage(resizeCornerImage.get(), renderer().style().colorSpace(), imageRect);
3443}
3444
3445void RenderLayer::paintResizer(GraphicsContext* context, const LayoutPoint& paintOffset, const LayoutRect& damageRect)
3446{
3447    if (renderer().style().resize() == RESIZE_NONE)
3448        return;
3449
3450    RenderBox* box = renderBox();
3451    ASSERT(box);
3452
3453    LayoutRect absRect = resizerCornerRect(this, box->borderBoxRect());
3454    absRect.moveBy(paintOffset);
3455    if (!absRect.intersects(damageRect))
3456        return;
3457
3458    if (context->updatingControlTints()) {
3459        updateResizerStyle();
3460        return;
3461    }
3462
3463    if (m_resizer) {
3464        m_resizer->paintIntoRect(context, paintOffset, absRect);
3465        return;
3466    }
3467
3468    drawPlatformResizerImage(context, absRect);
3469
3470    // Draw a frame around the resizer (1px grey line) if there are any scrollbars present.
3471    // Clipping will exclude the right and bottom edges of this frame.
3472    if (!hasOverlayScrollbars() && (m_vBar || m_hBar)) {
3473        GraphicsContextStateSaver stateSaver(*context);
3474        context->clip(absRect);
3475        LayoutRect largerCorner = absRect;
3476        largerCorner.setSize(LayoutSize(largerCorner.width() + LayoutUnit::fromPixel(1), largerCorner.height() + LayoutUnit::fromPixel(1)));
3477        context->setStrokeColor(Color(makeRGB(217, 217, 217)), ColorSpaceDeviceRGB);
3478        context->setStrokeThickness(1.0f);
3479        context->setFillColor(Color::transparent, ColorSpaceDeviceRGB);
3480        context->drawRect(pixelSnappedIntRect(largerCorner));
3481    }
3482}
3483
3484bool RenderLayer::isPointInResizeControl(const IntPoint& absolutePoint) const
3485{
3486    if (!canResize())
3487        return false;
3488
3489    RenderBox* box = renderBox();
3490    ASSERT(box);
3491
3492    IntPoint localPoint = roundedIntPoint(absoluteToContents(absolutePoint));
3493
3494    IntRect localBounds(0, 0, box->pixelSnappedWidth(), box->pixelSnappedHeight());
3495    return resizerCornerRect(this, localBounds).contains(localPoint);
3496}
3497
3498bool RenderLayer::hitTestOverflowControls(HitTestResult& result, const IntPoint& localPoint)
3499{
3500    if (!m_hBar && !m_vBar && !canResize())
3501        return false;
3502
3503    RenderBox* box = renderBox();
3504    ASSERT(box);
3505
3506    IntRect resizeControlRect;
3507    if (renderer().style().resize() != RESIZE_NONE) {
3508        resizeControlRect = pixelSnappedIntRect(resizerCornerRect(this, box->borderBoxRect()));
3509        if (resizeControlRect.contains(localPoint))
3510            return true;
3511    }
3512
3513    int resizeControlSize = std::max(resizeControlRect.height(), 0);
3514
3515    // FIXME: We should hit test the m_scrollCorner and pass it back through the result.
3516
3517    if (m_vBar && m_vBar->shouldParticipateInHitTesting()) {
3518        LayoutRect vBarRect(verticalScrollbarStart(0, box->width()),
3519                            box->borderTop(),
3520                            m_vBar->width(),
3521                            box->height() - (box->borderTop() + box->borderBottom()) - (m_hBar ? m_hBar->height() : resizeControlSize));
3522        if (vBarRect.contains(localPoint)) {
3523            result.setScrollbar(m_vBar.get());
3524            return true;
3525        }
3526    }
3527
3528    resizeControlSize = std::max(resizeControlRect.width(), 0);
3529    if (m_hBar && m_hBar->shouldParticipateInHitTesting()) {
3530        LayoutRect hBarRect(horizontalScrollbarStart(0),
3531                            box->height() - box->borderBottom() - m_hBar->height(),
3532                            box->width() - (box->borderLeft() + box->borderRight()) - (m_vBar ? m_vBar->width() : resizeControlSize),
3533                            m_hBar->height());
3534        if (hBarRect.contains(localPoint)) {
3535            result.setScrollbar(m_hBar.get());
3536            return true;
3537        }
3538    }
3539
3540    return false;
3541}
3542
3543bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
3544{
3545    return ScrollableArea::scroll(direction, granularity, multiplier);
3546}
3547
3548void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* subtreePaintRoot, PaintLayerFlags paintFlags)
3549{
3550    OverlapTestRequestMap overlapTestRequests;
3551
3552    LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), subtreePaintRoot, &overlapTestRequests);
3553    paintLayer(context, paintingInfo, paintFlags);
3554
3555    OverlapTestRequestMap::iterator end = overlapTestRequests.end();
3556    for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it)
3557        it->key->setOverlapTestResult(false);
3558}
3559
3560void RenderLayer::paintOverlayScrollbars(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* subtreePaintRoot)
3561{
3562    if (!m_containsDirtyOverlayScrollbars)
3563        return;
3564
3565    LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), subtreePaintRoot);
3566    paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars);
3567
3568    m_containsDirtyOverlayScrollbars = false;
3569}
3570
3571static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLayer)
3572{
3573    if (startLayer == endLayer)
3574        return true;
3575
3576    RenderView* view = &startLayer->renderer().view();
3577    for (RenderBlock* currentBlock = startLayer->renderer().containingBlock(); currentBlock && currentBlock != view; currentBlock = currentBlock->containingBlock()) {
3578        if (currentBlock->layer() == endLayer)
3579            return true;
3580    }
3581
3582    return false;
3583}
3584
3585void RenderLayer::clipToRect(const LayerPaintingInfo& paintingInfo, GraphicsContext* context, const ClipRect& clipRect, BorderRadiusClippingRule rule)
3586{
3587    float deviceScaleFactor = renderer().document().deviceScaleFactor();
3588    if (clipRect.rect() != paintingInfo.paintDirtyRect || clipRect.hasRadius()) {
3589        context->save();
3590        LayoutRect adjustedClipRect = clipRect.rect();
3591        adjustedClipRect.move(paintingInfo.subpixelAccumulation);
3592        context->clip(pixelSnappedForPainting(adjustedClipRect, deviceScaleFactor));
3593    }
3594
3595    if (!clipRect.hasRadius())
3596        return;
3597
3598    // If the clip rect has been tainted by a border radius, then we have to walk up our layer chain applying the clips from
3599    // any layers with overflow. The condition for being able to apply these clips is that the overflow object be in our
3600    // containing block chain so we check that also.
3601    for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? this : parent(); layer; layer = layer->parent()) {
3602        if (layer->renderer().hasOverflowClip() && layer->renderer().style().hasBorderRadius() && inContainingBlockChain(this, layer)) {
3603            LayoutRect adjustedClipRect = LayoutRect(toLayoutPoint(layer->offsetFromAncestor(paintingInfo.rootLayer)), layer->size());
3604            adjustedClipRect.move(paintingInfo.subpixelAccumulation);
3605            context->clipRoundedRect(layer->renderer().style().getRoundedInnerBorderFor(adjustedClipRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor));
3606        }
3607
3608        if (layer == paintingInfo.rootLayer)
3609            break;
3610    }
3611}
3612
3613void RenderLayer::restoreClip(GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect)
3614{
3615    if (clipRect.rect() == paintDirtyRect && !clipRect.hasRadius())
3616        return;
3617    context->restore();
3618}
3619
3620static void performOverlapTests(OverlapTestRequestMap& overlapTestRequests, const RenderLayer* rootLayer, const RenderLayer* layer)
3621{
3622    Vector<OverlapTestRequestClient*> overlappedRequestClients;
3623    OverlapTestRequestMap::iterator end = overlapTestRequests.end();
3624    LayoutRect boundingBox = layer->boundingBox(rootLayer, layer->offsetFromAncestor(rootLayer));
3625    for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it) {
3626        if (!boundingBox.intersects(it->value))
3627            continue;
3628
3629        it->key->setOverlapTestResult(true);
3630        overlappedRequestClients.append(it->key);
3631    }
3632    for (size_t i = 0; i < overlappedRequestClients.size(); ++i)
3633        overlapTestRequests.remove(overlappedRequestClients[i]);
3634}
3635
3636static inline bool shouldDoSoftwarePaint(const RenderLayer* layer, bool paintingReflection)
3637{
3638    return paintingReflection && !layer->has3DTransform();
3639}
3640
3641static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
3642{
3643    // Avoid painting descendants of the root layer when stylesheets haven't loaded. This eliminates FOUC.
3644    // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
3645    // will do a full repaint().
3646    if (layer->renderer().document().didLayoutWithPendingStylesheets() && !layer->isRootLayer() && !layer->renderer().isRoot())
3647        return true;
3648
3649    // Avoid painting all layers if the document is in a state where visual updates aren't allowed.
3650    // A full repaint will occur in Document::implicitClose() if painting is suppressed here.
3651    if (!layer->renderer().document().visualUpdatesAllowed())
3652        return true;
3653
3654    return false;
3655}
3656
3657static inline bool paintForFixedRootBackground(const RenderLayer* layer, RenderLayer::PaintLayerFlags paintFlags)
3658{
3659    return layer->renderer().isRoot() && (paintFlags & RenderLayer::PaintLayerPaintingRootBackgroundOnly);
3660}
3661
3662void RenderLayer::paintLayer(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
3663{
3664    if (isComposited()) {
3665        // The updatingControlTints() painting pass goes through compositing layers,
3666        // but we need to ensure that we don't cache clip rects computed with the wrong root in this case.
3667        if (context->updatingControlTints() || (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers))
3668            paintFlags |= PaintLayerTemporaryClipRects;
3669        else if (!backing()->paintsIntoWindow()
3670            && !backing()->paintsIntoCompositedAncestor()
3671            && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection)
3672            && !paintForFixedRootBackground(this, paintFlags)) {
3673            // If this RenderLayer should paint into its backing, that will be done via RenderLayerBacking::paintIntoLayer().
3674            return;
3675        }
3676    } else if (viewportConstrainedNotCompositedReason() == NotCompositedForBoundsOutOfView) {
3677        // Don't paint out-of-view viewport constrained layers (when doing prepainting) because they will never be visible
3678        // unless their position or viewport size is changed.
3679        ASSERT(renderer().style().position() == FixedPosition);
3680        return;
3681    }
3682
3683    // Non self-painting leaf layers don't need to be painted as their renderer() should properly paint itself.
3684    if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
3685        return;
3686
3687    if (shouldSuppressPaintingLayer(this))
3688        return;
3689
3690    // If this layer is totally invisible then there is nothing to paint.
3691    if (!renderer().opacity())
3692        return;
3693
3694    // Don't paint the layer if the renderer doesn't belong to this region.
3695    // This is true as long as we clamp the range of a box to its containing block range.
3696
3697    // Disable named flow region information for in flow threads such as multi-col.
3698    std::unique_ptr<CurrentRenderFlowThreadDisabler> flowThreadDisabler;
3699    if (enclosingPaginationLayer(ExcludeCompositedPaginatedLayers))
3700        flowThreadDisabler = std::make_unique<CurrentRenderFlowThreadDisabler>(&renderer().view());
3701
3702    RenderNamedFlowFragment* namedFlowFragment = currentRenderNamedFlowFragment();
3703    if (namedFlowFragment) {
3704        ASSERT(namedFlowFragment->isValid());
3705        if (!namedFlowFragment->flowThread()->objectShouldFragmentInFlowRegion(&renderer(), namedFlowFragment))
3706            return;
3707    }
3708
3709    if (paintsWithTransparency(paintingInfo.paintBehavior))
3710        paintFlags |= PaintLayerHaveTransparency;
3711
3712    // PaintLayerAppliedTransform is used in RenderReplica, to avoid applying the transform twice.
3713    if (paintsWithTransform(paintingInfo.paintBehavior) && !(paintFlags & PaintLayerAppliedTransform)) {
3714        TransformationMatrix layerTransform = renderableTransform(paintingInfo.paintBehavior);
3715        // If the transform can't be inverted, then don't paint anything.
3716        if (!layerTransform.isInvertible())
3717            return;
3718
3719        // If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency
3720        // layer from the parent now, assuming there is a parent
3721        if (paintFlags & PaintLayerHaveTransparency) {
3722            if (parent())
3723                parent()->beginTransparencyLayers(context, paintingInfo, paintingInfo.paintDirtyRect);
3724            else
3725                beginTransparencyLayers(context, paintingInfo, paintingInfo.paintDirtyRect);
3726        }
3727
3728        if (enclosingPaginationLayer(ExcludeCompositedPaginatedLayers)) {
3729            paintTransformedLayerIntoFragments(context, paintingInfo, paintFlags);
3730            return;
3731        }
3732
3733        // Make sure the parent's clip rects have been calculated.
3734        ClipRect clipRect = paintingInfo.paintDirtyRect;
3735        if (parent()) {
3736            ClipRectsContext clipRectsContext(paintingInfo.rootLayer, (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects,
3737                IgnoreOverlayScrollbarSize, (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip);
3738            clipRect = backgroundClipRect(clipRectsContext);
3739            clipRect.intersect(paintingInfo.paintDirtyRect);
3740
3741            // Push the parent coordinate space's clip.
3742            parent()->clipToRect(paintingInfo, context, clipRect);
3743        }
3744
3745        paintLayerByApplyingTransform(context, paintingInfo, paintFlags);
3746
3747        // Restore the clip.
3748        if (parent())
3749            parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect);
3750
3751        return;
3752    }
3753
3754    paintLayerContentsAndReflection(context, paintingInfo, paintFlags);
3755}
3756
3757void RenderLayer::paintLayerContentsAndReflection(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
3758{
3759    ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
3760
3761    PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform);
3762
3763    // Paint the reflection first if we have one.
3764    if (m_reflection && !m_paintingInsideReflection) {
3765        // Mark that we are now inside replica painting.
3766        m_paintingInsideReflection = true;
3767        reflectionLayer()->paintLayer(context, paintingInfo, localPaintFlags | PaintLayerPaintingReflection);
3768        m_paintingInsideReflection = false;
3769    }
3770
3771    localPaintFlags |= PaintLayerPaintingCompositingAllPhases;
3772    paintLayerContents(context, paintingInfo, localPaintFlags);
3773}
3774
3775bool RenderLayer::setupFontSubpixelQuantization(GraphicsContext* context, bool& didQuantizeFonts)
3776{
3777    if (context->paintingDisabled())
3778        return false;
3779
3780    bool scrollingOnMainThread = true;
3781#if ENABLE(ASYNC_SCROLLING)
3782    if (Page* page = renderer().frame().page()) {
3783        if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
3784            scrollingOnMainThread = scrollingCoordinator->shouldUpdateScrollLayerPositionSynchronously();
3785    }
3786#endif
3787
3788    // FIXME: We shouldn't have to disable subpixel quantization for overflow clips or subframes once we scroll those
3789    // things on the scrolling thread.
3790    bool contentsScrollByPainting = (renderer().hasOverflowClip() && !usesCompositedScrolling()) || (renderer().frame().ownerElement());
3791    bool isZooming = false;
3792    if (Page* page = renderer().frame().page())
3793        isZooming = !page->chrome().client().hasStablePageScaleFactor();
3794    if (scrollingOnMainThread || contentsScrollByPainting || isZooming) {
3795        didQuantizeFonts = context->shouldSubpixelQuantizeFonts();
3796        context->setShouldSubpixelQuantizeFonts(false);
3797        return true;
3798    }
3799    return false;
3800}
3801
3802template <class ReferenceBoxClipPathOperation>
3803static inline LayoutRect computeReferenceBox(const RenderObject& renderer, const ReferenceBoxClipPathOperation& clippingPath, const LayoutSize& offsetFromRoot, const LayoutRect& rootRelativeBounds)
3804{
3805    // FIXME: Support different reference boxes for inline content.
3806    // https://bugs.webkit.org/show_bug.cgi?id=129047
3807    if (!renderer.isBox())
3808        return rootRelativeBounds;
3809
3810    LayoutRect referenceBox;
3811    const RenderBox& box = toRenderBox(renderer);
3812    switch (clippingPath.referenceBox()) {
3813    case ContentBox:
3814        referenceBox = box.contentBoxRect();
3815        referenceBox.move(offsetFromRoot);
3816        break;
3817    case PaddingBox:
3818        referenceBox = box.paddingBoxRect();
3819        referenceBox.move(offsetFromRoot);
3820        break;
3821    // FIXME: Support margin-box. Use bounding client rect for now.
3822    // https://bugs.webkit.org/show_bug.cgi?id=127984
3823    case MarginBox:
3824    // fill, stroke, view-box compute to border-box for HTML elements.
3825    case Fill:
3826    case Stroke:
3827    case ViewBox:
3828    case BorderBox:
3829    case BoxMissing:
3830        referenceBox = box.borderBoxRect();
3831        referenceBox.move(offsetFromRoot);
3832        break;
3833    }
3834
3835    return referenceBox;
3836}
3837
3838bool RenderLayer::setupClipPath(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed)
3839{
3840    if (!renderer().hasClipPath() || context->paintingDisabled())
3841        return false;
3842
3843    if (!rootRelativeBoundsComputed) {
3844        rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, offsetFromRoot, 0);
3845        rootRelativeBoundsComputed = true;
3846    }
3847
3848    RenderStyle& style = renderer().style();
3849    ASSERT(style.clipPath());
3850    if (style.clipPath()->type() == ClipPathOperation::Shape) {
3851        ShapeClipPathOperation& clippingPath = toShapeClipPathOperation(*(style.clipPath()));
3852
3853        LayoutRect referenceBox = computeReferenceBox(renderer(), clippingPath, offsetFromRoot, rootRelativeBounds);
3854        context->save();
3855        context->clipPath(clippingPath.pathForReferenceRect(referenceBox), clippingPath.windRule());
3856        return true;
3857    }
3858
3859    if (style.clipPath()->type() == ClipPathOperation::Box && renderer().isBox()) {
3860        BoxClipPathOperation& clippingPath = toBoxClipPathOperation(*(style.clipPath()));
3861
3862        RoundedRect shapeRect = computeRoundedRectForBoxShape(clippingPath.referenceBox(), toRenderBox(renderer()));
3863        shapeRect.move(offsetFromRoot);
3864
3865        context->save();
3866        context->clipPath(clippingPath.pathForReferenceRect(shapeRect), RULE_NONZERO);
3867        return true;
3868    }
3869
3870    if (style.clipPath()->type() == ClipPathOperation::Reference) {
3871        ReferenceClipPathOperation* referenceClipPathOperation = static_cast<ReferenceClipPathOperation*>(style.clipPath());
3872        Element* element = renderer().document().getElementById(referenceClipPathOperation->fragment());
3873        if (element && element->hasTagName(SVGNames::clipPathTag) && element->renderer()) {
3874            // FIXME: This should use a safer cast such as toRenderSVGResourceContainer().
3875            // FIXME: Should this do a context->save() and return true so we restore the context?
3876            static_cast<RenderSVGResourceClipper*>(element->renderer())->applyClippingToContext(renderer(), rootRelativeBounds, paintingInfo.paintDirtyRect, context);
3877        }
3878    }
3879
3880    return false;
3881}
3882
3883#if ENABLE(CSS_FILTERS)
3884
3885std::unique_ptr<FilterEffectRendererHelper> RenderLayer::setupFilters(GraphicsContext* context, LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed)
3886{
3887    if (context->paintingDisabled())
3888        return nullptr;
3889
3890    if (paintFlags & PaintLayerPaintingOverlayScrollbars)
3891        return nullptr;
3892
3893    FilterInfo* filterInfo = FilterInfo::getIfExists(*this);
3894    bool hasPaintedFilter = filterInfo && filterInfo->renderer() && paintsWithFilters();
3895    if (!hasPaintedFilter)
3896        return nullptr;
3897
3898    auto filterPainter = std::make_unique<FilterEffectRendererHelper>(hasPaintedFilter);
3899    if (!filterPainter->haveFilterEffect())
3900        return nullptr;
3901
3902    LayoutRect filterRepaintRect = filterInfo->dirtySourceRect();
3903    filterRepaintRect.move(offsetFromRoot);
3904
3905    if (!rootRelativeBoundsComputed) {
3906        rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, offsetFromRoot, 0);
3907        rootRelativeBoundsComputed = true;
3908    }
3909
3910    if (filterPainter->prepareFilterEffect(this, enclosingIntRect(rootRelativeBounds), enclosingIntRect(paintingInfo.paintDirtyRect), enclosingIntRect(filterRepaintRect))) {
3911        // Now we know for sure, that the source image will be updated, so we can revert our tracking repaint rect back to zero.
3912        filterInfo->resetDirtySourceRect();
3913
3914        if (!filterPainter->beginFilterEffect())
3915            return nullptr;
3916
3917        // Check that we didn't fail to allocate the graphics context for the offscreen buffer.
3918        ASSERT(filterPainter->hasStartedFilterEffect());
3919
3920        paintingInfo.paintDirtyRect = filterPainter->repaintRect();
3921        // If the filter needs the full source image, we need to avoid using the clip rectangles.
3922        // Otherwise, if for example this layer has overflow:hidden, a drop shadow will not compute correctly.
3923        // Note that we will still apply the clipping on the final rendering of the filter.
3924        paintingInfo.clipToDirtyRect = !filterInfo->renderer()->hasFilterThatMovesPixels();
3925        return filterPainter;
3926    }
3927    return nullptr;
3928}
3929
3930GraphicsContext* RenderLayer::applyFilters(FilterEffectRendererHelper* filterPainter, GraphicsContext* originalContext, LayerPaintingInfo& paintingInfo, LayerFragments& layerFragments)
3931{
3932    ASSERT(filterPainter->hasStartedFilterEffect());
3933    // Apply the correct clipping (ie. overflow: hidden).
3934    // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
3935    ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect;
3936    clipToRect(paintingInfo, originalContext, backgroundRect);
3937    filterPainter->applyFilterEffect(originalContext);
3938    restoreClip(originalContext, paintingInfo.paintDirtyRect, backgroundRect);
3939    return originalContext;
3940}
3941
3942#endif
3943
3944// Helper for the sorting of layers by z-index.
3945static inline bool compareZIndex(RenderLayer* first, RenderLayer* second)
3946{
3947    return first->zIndex() < second->zIndex();
3948}
3949
3950// Paint the layers associated with the fixed positioned elements in named flows.
3951// These layers should not be painted in a similar way as the other elements collected in
3952// named flows - regions -> named flows - since we do not want them to be clipped to the
3953// regions viewport.
3954void RenderLayer::paintFixedLayersInNamedFlows(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
3955{
3956    if (!isRootLayer())
3957        return;
3958
3959    // Get the named flows for the view
3960    if (!renderer().view().hasRenderNamedFlowThreads())
3961        return;
3962
3963    // Ensure the flow threads hierarchy is up-to-date before using it.
3964    renderer().view().flowThreadController().updateNamedFlowsLayerListsIfNeeded();
3965
3966    // Collect the fixed layers in a list to be painted
3967    Vector<RenderLayer*> fixedLayers;
3968    renderer().view().flowThreadController().collectFixedPositionedLayers(fixedLayers);
3969
3970    // Paint the layers
3971    for (size_t i = 0; i < fixedLayers.size(); ++i) {
3972        RenderLayer* fixedLayer = fixedLayers.at(i);
3973        fixedLayer->paintLayer(context, paintingInfo, paintFlags);
3974    }
3975}
3976
3977void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
3978{
3979    ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
3980
3981    PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform);
3982    bool haveTransparency = localPaintFlags & PaintLayerHaveTransparency;
3983    bool isSelfPaintingLayer = this->isSelfPaintingLayer();
3984    bool isPaintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars;
3985    bool isPaintingScrollingContent = paintFlags & PaintLayerPaintingCompositingScrollingPhase;
3986    bool isPaintingCompositedForeground = paintFlags & PaintLayerPaintingCompositingForegroundPhase;
3987    bool isPaintingCompositedBackground = paintFlags & PaintLayerPaintingCompositingBackgroundPhase;
3988    bool isPaintingOverflowContents = paintFlags & PaintLayerPaintingOverflowContents;
3989    // Outline always needs to be painted even if we have no visible content. Also,
3990    // the outline is painted in the background phase during composited scrolling.
3991    // If it were painted in the foreground phase, it would move with the scrolled
3992    // content. When not composited scrolling, the outline is painted in the
3993    // foreground phase. Since scrolled contents are moved by repainting in this
3994    // case, the outline won't get 'dragged along'.
3995    bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars
3996        && ((isPaintingScrollingContent && isPaintingCompositedBackground)
3997        || (!isPaintingScrollingContent && isPaintingCompositedForeground));
3998    bool shouldPaintContent = m_hasVisibleContent && isSelfPaintingLayer && !isPaintingOverlayScrollbars;
3999
4000    if (localPaintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer().isRenderView() && !renderer().isRoot())
4001        return;
4002
4003    // Ensure our lists are up-to-date.
4004    updateLayerListsIfNeeded();
4005
4006    // Do not paint the fixed positioned layers if the paint root is the named flow,
4007    // if the paint originates at region level.
4008    if (paintingInfo.rootLayer->isOutOfFlowRenderFlowThread()
4009        && renderer().fixedPositionedWithNamedFlowContainingBlock())
4010        return;
4011
4012    LayoutSize offsetFromRoot = offsetFromAncestor(paintingInfo.rootLayer);
4013    LayoutRect rootRelativeBounds;
4014    bool rootRelativeBoundsComputed = false;
4015
4016    // FIXME: We shouldn't have to disable subpixel quantization for overflow clips or subframes once we scroll those
4017    // things on the scrolling thread.
4018    bool didQuantizeFonts = true;
4019    bool needToAdjustSubpixelQuantization = setupFontSubpixelQuantization(context, didQuantizeFonts);
4020
4021    // Apply clip-path to context.
4022    bool hasClipPath = setupClipPath(context, paintingInfo, offsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed);
4023
4024    LayerPaintingInfo localPaintingInfo(paintingInfo);
4025
4026    GraphicsContext* transparencyLayerContext = context;
4027#if ENABLE(CSS_FILTERS)
4028    std::unique_ptr<FilterEffectRendererHelper> filterPainter = setupFilters(context, localPaintingInfo, paintFlags, offsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed);
4029    if (filterPainter) {
4030        context = filterPainter->filterContext();
4031        if (context != transparencyLayerContext && haveTransparency) {
4032            // If we have a filter and transparency, we have to eagerly start a transparency layer here, rather than risk a child layer lazily starts one with the wrong context.
4033            beginTransparencyLayers(transparencyLayerContext, localPaintingInfo, paintingInfo.paintDirtyRect);
4034        }
4035    }
4036#endif
4037
4038    // If this layer's renderer is a child of the subtreePaintRoot, we render unconditionally, which
4039    // is done by passing a nil subtreePaintRoot down to our renderer (as if no subtreePaintRoot was ever set).
4040    // Otherwise, our renderer tree may or may not contain the subtreePaintRoot root, so we pass that root along
4041    // so it will be tested against as we descend through the renderers.
4042    RenderObject* subtreePaintRootForRenderer = 0;
4043    if (localPaintingInfo.subtreePaintRoot && !renderer().isDescendantOf(localPaintingInfo.subtreePaintRoot))
4044        subtreePaintRootForRenderer = localPaintingInfo.subtreePaintRoot;
4045
4046    if (localPaintingInfo.overlapTestRequests && isSelfPaintingLayer)
4047        performOverlapTests(*localPaintingInfo.overlapTestRequests, localPaintingInfo.rootLayer, this);
4048
4049    bool forceBlackText = localPaintingInfo.paintBehavior & PaintBehaviorForceBlackText;
4050    bool selectionOnly  = localPaintingInfo.paintBehavior & PaintBehaviorSelectionOnly;
4051
4052    PaintBehavior paintBehavior = PaintBehaviorNormal;
4053    if (localPaintFlags & PaintLayerPaintingSkipRootBackground)
4054        paintBehavior |= PaintBehaviorSkipRootBackground;
4055    else if (localPaintFlags & PaintLayerPaintingRootBackgroundOnly)
4056        paintBehavior |= PaintBehaviorRootBackgroundOnly;
4057
4058    LayerFragments layerFragments;
4059    LayoutRect paintDirtyRect = localPaintingInfo.paintDirtyRect;
4060    if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
4061        // Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment, as well as whether or not the content of each
4062        // fragment should paint. If the parent's filter dictates full repaint to ensure proper filter effect,
4063        // use the overflow clip as dirty rect, instead of no clipping. It maintains proper clipping for overflow::scroll.
4064        if (!paintingInfo.clipToDirtyRect && renderer().hasOverflowClip()) {
4065            // We can turn clipping back by requesting full repaint for the overflow area.
4066            localPaintingInfo.clipToDirtyRect = true;
4067            paintDirtyRect = selfClipRect();
4068        }
4069        collectFragments(layerFragments, localPaintingInfo.rootLayer, paintDirtyRect, ExcludeCompositedPaginatedLayers,
4070            (localPaintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
4071            (isPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, offsetFromRoot);
4072        updatePaintingInfoForFragments(layerFragments, localPaintingInfo, localPaintFlags, shouldPaintContent, offsetFromRoot);
4073    }
4074
4075    if (isPaintingCompositedBackground) {
4076        // Paint only the backgrounds for all of the fragments of the layer.
4077        if (shouldPaintContent && !selectionOnly)
4078            paintBackgroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
4079                localPaintingInfo, paintBehavior, subtreePaintRootForRenderer);
4080    }
4081
4082    // Now walk the sorted list of children with negative z-indices.
4083    if ((isPaintingScrollingContent && isPaintingOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackground))
4084        paintList(negZOrderList(), context, localPaintingInfo, localPaintFlags);
4085
4086    if (isPaintingCompositedForeground) {
4087        if (shouldPaintContent)
4088            paintForegroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
4089                localPaintingInfo, paintBehavior, subtreePaintRootForRenderer, selectionOnly, forceBlackText);
4090    }
4091
4092    if (shouldPaintOutline)
4093        paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, subtreePaintRootForRenderer);
4094
4095    if (isPaintingCompositedForeground) {
4096        // Paint any child layers that have overflow.
4097        paintList(m_normalFlowList.get(), context, localPaintingInfo, localPaintFlags);
4098
4099        // Now walk the sorted list of children with positive z-indices.
4100        paintList(posZOrderList(), context, localPaintingInfo, localPaintFlags);
4101
4102        // Paint the fixed elements from flow threads.
4103        paintFixedLayersInNamedFlows(context, localPaintingInfo, localPaintFlags);
4104
4105        // If this is a region, paint its contents via the flow thread's layer.
4106        if (shouldPaintContent)
4107            paintFlowThreadIfRegionForFragments(layerFragments, context, localPaintingInfo, localPaintFlags);
4108    }
4109
4110    if (isPaintingOverlayScrollbars)
4111        paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo);
4112
4113#if ENABLE(CSS_FILTERS)
4114    if (filterPainter) {
4115        context = applyFilters(filterPainter.get(), transparencyLayerContext, localPaintingInfo, layerFragments);
4116        filterPainter = nullptr;
4117    }
4118#endif
4119
4120    // Make sure that we now use the original transparency context.
4121    ASSERT(transparencyLayerContext == context);
4122
4123    if ((localPaintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && renderer().hasMask() && !selectionOnly) {
4124        // Paint the mask for the fragments.
4125        paintMaskForFragments(layerFragments, context, localPaintingInfo, subtreePaintRootForRenderer);
4126    }
4127
4128    // End our transparency layer
4129    if (haveTransparency && m_usedTransparency && !m_paintingInsideReflection) {
4130        context->endTransparencyLayer();
4131        context->restore();
4132        m_usedTransparency = false;
4133    }
4134
4135    // Re-set this to whatever it was before we painted the layer.
4136    if (needToAdjustSubpixelQuantization)
4137        context->setShouldSubpixelQuantizeFonts(didQuantizeFonts);
4138
4139    if (hasClipPath)
4140        context->restore();
4141}
4142
4143void RenderLayer::paintLayerByApplyingTransform(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutSize& translationOffset)
4144{
4145    // This involves subtracting out the position of the layer in our current coordinate space, but preserving
4146    // the accumulated error for sub-pixel layout.
4147    float deviceScaleFactor = renderer().document().deviceScaleFactor();
4148    LayoutSize offsetFromParent = offsetFromAncestor(paintingInfo.rootLayer);
4149    offsetFromParent += translationOffset;
4150    TransformationMatrix transform(renderableTransform(paintingInfo.paintBehavior));
4151    // Add the subpixel accumulation to the current layer's offset so that we can always snap the translateRight value to where the renderer() is supposed to be painting.
4152    LayoutSize offsetForThisLayer = offsetFromParent + paintingInfo.subpixelAccumulation;
4153    FloatSize devicePixelSnappedOffsetForThisLayer = toFloatSize(roundedForPainting(toLayoutPoint(offsetForThisLayer), deviceScaleFactor));
4154    // We handle accumulated subpixels through nested layers here. Since the context gets translated to device pixels,
4155    // all we need to do is add the delta to the accumulated pixels coming from ancestor layers.
4156    // Translate the graphics context to the snapping position to avoid off-device-pixel positing.
4157    transform.translateRight(devicePixelSnappedOffsetForThisLayer.width(), devicePixelSnappedOffsetForThisLayer.height());
4158    // Apply the transform.
4159    GraphicsContextStateSaver stateSaver(*context);
4160    context->concatCTM(transform.toAffineTransform());
4161
4162    // Now do a paint with the root layer shifted to be us.
4163    LayoutSize adjustedSubpixelAccumulation = offsetForThisLayer - LayoutSize(devicePixelSnappedOffsetForThisLayer);
4164    LayerPaintingInfo transformedPaintingInfo(this, LayoutRect(enclosingRectForPainting(transform.inverse().mapRect(paintingInfo.paintDirtyRect), deviceScaleFactor)),
4165        paintingInfo.paintBehavior, adjustedSubpixelAccumulation, paintingInfo.subtreePaintRoot, paintingInfo.overlapTestRequests);
4166    paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags);
4167}
4168
4169void RenderLayer::paintList(Vector<RenderLayer*>* list, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
4170{
4171    if (!list)
4172        return;
4173
4174    if (!hasSelfPaintingLayerDescendant())
4175        return;
4176
4177#if !ASSERT_DISABLED
4178    LayerListMutationDetector mutationChecker(this);
4179#endif
4180
4181    for (size_t i = 0; i < list->size(); ++i) {
4182        RenderLayer* childLayer = list->at(i);
4183        if (childLayer->isFlowThreadCollectingGraphicsLayersUnderRegions())
4184            continue;
4185        childLayer->paintLayer(context, paintingInfo, paintFlags);
4186    }
4187}
4188
4189RenderLayer* RenderLayer::enclosingPaginationLayerInSubtree(const RenderLayer* rootLayer, PaginationInclusionMode mode) const
4190{
4191    // If we don't have an enclosing layer, or if the root layer is the same as the enclosing layer,
4192    // then just return the enclosing pagination layer (it will be 0 in the former case and the rootLayer in the latter case).
4193    RenderLayer* paginationLayer = enclosingPaginationLayer(mode);
4194    if (!paginationLayer || rootLayer == paginationLayer)
4195        return paginationLayer;
4196
4197    // Walk up the layer tree and see which layer we hit first. If it's the root, then the enclosing pagination
4198    // layer isn't in our subtree and we return 0. If we hit the enclosing pagination layer first, then
4199    // we can return it.
4200    for (const RenderLayer* layer = this; layer; layer = layer->parent()) {
4201        if (layer == rootLayer)
4202            return 0;
4203        if (layer == paginationLayer)
4204            return paginationLayer;
4205    }
4206
4207    // This should never be reached, since an enclosing layer should always either be the rootLayer or be
4208    // our enclosing pagination layer.
4209    ASSERT_NOT_REACHED();
4210    return 0;
4211}
4212
4213void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* rootLayer, const LayoutRect& dirtyRect, PaginationInclusionMode inclusionMode,
4214    ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const LayoutSize& offsetFromRoot,
4215    const LayoutRect* layerBoundingBox, ShouldApplyRootOffsetToFragments applyRootOffsetToFragments)
4216{
4217    RenderLayer* paginationLayer = enclosingPaginationLayerInSubtree(rootLayer, inclusionMode);
4218    if (!paginationLayer || hasTransform()) {
4219        // For unpaginated layers, there is only one fragment.
4220        LayerFragment fragment;
4221        ClipRectsContext clipRectsContext(rootLayer, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
4222        calculateRects(clipRectsContext, dirtyRect, fragment.layerBounds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offsetFromRoot);
4223        fragments.append(fragment);
4224        return;
4225    }
4226
4227    // Compute our offset within the enclosing pagination layer.
4228    LayoutSize offsetWithinPaginatedLayer = offsetFromAncestor(paginationLayer);
4229
4230    // Calculate clip rects relative to the enclosingPaginationLayer. The purpose of this call is to determine our bounds clipped to intermediate
4231    // layers between us and the pagination context. It's important to minimize the number of fragments we need to create and this helps with that.
4232    ClipRectsContext paginationClipRectsContext(paginationLayer, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
4233    LayoutRect layerBoundsInFlowThread;
4234    ClipRect backgroundRectInFlowThread;
4235    ClipRect foregroundRectInFlowThread;
4236    ClipRect outlineRectInFlowThread;
4237    calculateRects(paginationClipRectsContext, LayoutRect::infiniteRect(), layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread,
4238        outlineRectInFlowThread, offsetWithinPaginatedLayer);
4239
4240    // Take our bounding box within the flow thread and clip it.
4241    LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingBox : boundingBox(paginationLayer, offsetWithinPaginatedLayer);
4242    layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect());
4243
4244    RenderFlowThread& enclosingFlowThread = toRenderFlowThread(paginationLayer->renderer());
4245    RenderLayer* parentPaginationLayer = paginationLayer->parent()->enclosingPaginationLayerInSubtree(rootLayer, inclusionMode);
4246    LayerFragments ancestorFragments;
4247    if (parentPaginationLayer) {
4248        // Compute a bounding box accounting for fragments.
4249        LayoutRect layerFragmentBoundingBoxInParentPaginationLayer = enclosingFlowThread.fragmentsBoundingBox(layerBoundingBoxInFlowThread);
4250
4251        // Convert to be in the ancestor pagination context's coordinate space.
4252        LayoutSize offsetWithinParentPaginatedLayer = paginationLayer->offsetFromAncestor(parentPaginationLayer);
4253        layerFragmentBoundingBoxInParentPaginationLayer.move(offsetWithinParentPaginatedLayer);
4254
4255        // Now collect ancestor fragments.
4256        parentPaginationLayer->collectFragments(ancestorFragments, rootLayer, dirtyRect, inclusionMode, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip,
4257            offsetFromAncestor(rootLayer), &layerFragmentBoundingBoxInParentPaginationLayer, ApplyRootOffsetToFragments);
4258
4259        if (ancestorFragments.isEmpty())
4260            return;
4261
4262        for (auto& ancestorFragment : ancestorFragments) {
4263            // Shift the dirty rect into flow thread coordinates.
4264            LayoutRect dirtyRectInFlowThread(dirtyRect);
4265            dirtyRectInFlowThread.move(-offsetWithinParentPaginatedLayer - ancestorFragment.paginationOffset);
4266
4267            size_t oldSize = fragments.size();
4268
4269            // Tell the flow thread to collect the fragments. We pass enough information to create a minimal number of fragments based off the pages/columns
4270            // that intersect the actual dirtyRect as well as the pages/columns that intersect our layer's bounding box.
4271            enclosingFlowThread.collectLayerFragments(fragments, layerBoundingBoxInFlowThread, dirtyRectInFlowThread);
4272
4273            size_t newSize = fragments.size();
4274
4275            if (oldSize == newSize)
4276                continue;
4277
4278            for (size_t i = oldSize; i < newSize; ++i) {
4279                LayerFragment& fragment = fragments.at(i);
4280
4281                // Set our four rects with all clipping applied that was internal to the flow thread.
4282                fragment.setRects(layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread, outlineRectInFlowThread, &layerBoundingBoxInFlowThread);
4283
4284                // Shift to the root-relative physical position used when painting the flow thread in this fragment.
4285                fragment.moveBy(toLayoutPoint(ancestorFragment.paginationOffset + fragment.paginationOffset + offsetWithinParentPaginatedLayer));
4286
4287                // Intersect the fragment with our ancestor's background clip so that e.g., columns in an overflow:hidden block are
4288                // properly clipped by the overflow.
4289                fragment.intersect(ancestorFragment.paginationClip);
4290
4291                // Now intersect with our pagination clip. This will typically mean we're just intersecting the dirty rect with the column
4292                // clip, so the column clip ends up being all we apply.
4293                fragment.intersect(fragment.paginationClip);
4294
4295                if (applyRootOffsetToFragments == ApplyRootOffsetToFragments)
4296                    fragment.paginationOffset = fragment.paginationOffset + offsetWithinParentPaginatedLayer;
4297            }
4298        }
4299
4300        return;
4301    }
4302
4303    // Shift the dirty rect into flow thread coordinates.
4304    LayoutSize offsetOfPaginationLayerFromRoot = enclosingPaginationLayer(inclusionMode)->offsetFromAncestor(rootLayer);
4305    LayoutRect dirtyRectInFlowThread(dirtyRect);
4306    dirtyRectInFlowThread.move(-offsetOfPaginationLayerFromRoot);
4307
4308    // Tell the flow thread to collect the fragments. We pass enough information to create a minimal number of fragments based off the pages/columns
4309    // that intersect the actual dirtyRect as well as the pages/columns that intersect our layer's bounding box.
4310    enclosingFlowThread.collectLayerFragments(fragments, layerBoundingBoxInFlowThread, dirtyRectInFlowThread);
4311
4312    if (fragments.isEmpty())
4313        return;
4314
4315    // Get the parent clip rects of the pagination layer, since we need to intersect with that when painting column contents.
4316    ClipRect ancestorClipRect = dirtyRect;
4317    if (paginationLayer->parent()) {
4318        ClipRectsContext clipRectsContext(rootLayer, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
4319        ancestorClipRect = paginationLayer->backgroundClipRect(clipRectsContext);
4320        ancestorClipRect.intersect(dirtyRect);
4321    }
4322
4323    for (size_t i = 0; i < fragments.size(); ++i) {
4324        LayerFragment& fragment = fragments.at(i);
4325
4326        // Set our four rects with all clipping applied that was internal to the flow thread.
4327        fragment.setRects(layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread, outlineRectInFlowThread, &layerBoundingBoxInFlowThread);
4328
4329        // Shift to the root-relative physical position used when painting the flow thread in this fragment.
4330        fragment.moveBy(toLayoutPoint(fragment.paginationOffset + offsetOfPaginationLayerFromRoot));
4331
4332        // Intersect the fragment with our ancestor's background clip so that e.g., columns in an overflow:hidden block are
4333        // properly clipped by the overflow.
4334        fragment.intersect(ancestorClipRect.rect());
4335
4336        // If the ancestor clip rect has border-radius, make sure to apply it to the fragments.
4337        if (ancestorClipRect.hasRadius()) {
4338            fragment.foregroundRect.setHasRadius(true);
4339            fragment.backgroundRect.setHasRadius(true);
4340            fragment.outlineRect.setHasRadius(true);
4341        }
4342
4343        // Now intersect with our pagination clip. This will typically mean we're just intersecting the dirty rect with the column
4344        // clip, so the column clip ends up being all we apply.
4345        fragment.intersect(fragment.paginationClip);
4346
4347        if (applyRootOffsetToFragments == ApplyRootOffsetToFragments)
4348            fragment.paginationOffset = fragment.paginationOffset + offsetOfPaginationLayerFromRoot;
4349    }
4350}
4351
4352void RenderLayer::updatePaintingInfoForFragments(LayerFragments& fragments, const LayerPaintingInfo& localPaintingInfo, PaintLayerFlags localPaintFlags,
4353    bool shouldPaintContent, const LayoutSize& offsetFromRoot)
4354{
4355    for (size_t i = 0; i < fragments.size(); ++i) {
4356        LayerFragment& fragment = fragments.at(i);
4357        fragment.shouldPaintContent = shouldPaintContent;
4358        if (this != localPaintingInfo.rootLayer || !(localPaintFlags & PaintLayerPaintingOverflowContents)) {
4359            LayoutSize newOffsetFromRoot = offsetFromRoot + fragment.paginationOffset;
4360            fragment.shouldPaintContent &= intersectsDamageRect(fragment.layerBounds, fragment.backgroundRect.rect(), localPaintingInfo.rootLayer, newOffsetFromRoot, fragment.hasBoundingBox ? &fragment.boundingBox : 0);
4361        }
4362    }
4363}
4364
4365void RenderLayer::paintTransformedLayerIntoFragments(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
4366{
4367    LayerFragments enclosingPaginationFragments;
4368    LayoutSize offsetOfPaginationLayerFromRoot;
4369    RenderLayer* paginatedLayer = enclosingPaginationLayer(ExcludeCompositedPaginatedLayers);
4370    LayoutRect transformedExtent = transparencyClipBox(*this, paginatedLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintingInfo.paintBehavior);
4371    paginatedLayer->collectFragments(enclosingPaginationFragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, ExcludeCompositedPaginatedLayers,
4372        (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
4373        (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, offsetOfPaginationLayerFromRoot, &transformedExtent);
4374
4375    for (size_t i = 0; i < enclosingPaginationFragments.size(); ++i) {
4376        const LayerFragment& fragment = enclosingPaginationFragments.at(i);
4377
4378        // Apply the page/column clip for this fragment, as well as any clips established by layers in between us and
4379        // the enclosing pagination layer.
4380        LayoutRect clipRect = fragment.backgroundRect.rect();
4381
4382        // Now compute the clips within a given fragment
4383        if (parent() != paginatedLayer) {
4384            offsetOfPaginationLayerFromRoot = toLayoutSize(paginatedLayer->convertToLayerCoords(paintingInfo.rootLayer, toLayoutPoint(offsetOfPaginationLayerFromRoot)));
4385
4386            ClipRectsContext clipRectsContext(paginatedLayer, (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects,
4387                IgnoreOverlayScrollbarSize, (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip);
4388            LayoutRect parentClipRect = backgroundClipRect(clipRectsContext).rect();
4389            parentClipRect.move(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
4390            clipRect.intersect(parentClipRect);
4391        }
4392
4393        parent()->clipToRect(paintingInfo, context, clipRect);
4394        paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragment.paginationOffset);
4395        parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect);
4396    }
4397}
4398
4399void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
4400    const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
4401    RenderObject* subtreePaintRootForRenderer)
4402{
4403    for (size_t i = 0; i < layerFragments.size(); ++i) {
4404        const LayerFragment& fragment = layerFragments.at(i);
4405        if (!fragment.shouldPaintContent)
4406            continue;
4407
4408        // Begin transparency layers lazily now that we know we have to paint something.
4409        if (haveTransparency)
4410            beginTransparencyLayers(transparencyLayerContext, localPaintingInfo, transparencyPaintDirtyRect);
4411
4412        if (localPaintingInfo.clipToDirtyRect) {
4413            // Paint our background first, before painting any child layers.
4414            // Establish the clip used to paint our background.
4415            clipToRect(localPaintingInfo, context, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self.
4416        }
4417
4418        // Paint the background.
4419        // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
4420        PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseBlockBackground, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer());
4421        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation));
4422
4423        if (localPaintingInfo.clipToDirtyRect)
4424            restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
4425    }
4426}
4427
4428void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
4429    const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
4430    RenderObject* subtreePaintRootForRenderer, bool selectionOnly, bool forceBlackText)
4431{
4432    // Begin transparency if we have something to paint.
4433    if (haveTransparency) {
4434        for (size_t i = 0; i < layerFragments.size(); ++i) {
4435            const LayerFragment& fragment = layerFragments.at(i);
4436            if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty()) {
4437                beginTransparencyLayers(transparencyLayerContext, localPaintingInfo, transparencyPaintDirtyRect);
4438                break;
4439            }
4440        }
4441    }
4442
4443    PaintBehavior localPaintBehavior = forceBlackText ? (PaintBehavior)PaintBehaviorForceBlackText : paintBehavior;
4444
4445    // Optimize clipping for the single fragment case.
4446    bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && layerFragments[0].shouldPaintContent && !layerFragments[0].foregroundRect.isEmpty();
4447    ClipRect clippedRect;
4448    if (shouldClip) {
4449        clippedRect = layerFragments[0].foregroundRect;
4450        clipToRect(localPaintingInfo, context, clippedRect);
4451    }
4452
4453    // We have to loop through every fragment multiple times, since we have to repaint in each specific phase in order for
4454    // interleaving of the fragments to work properly.
4455    paintForegroundForFragmentsWithPhase(selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds, layerFragments,
4456        context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer);
4457
4458    if (!selectionOnly) {
4459        paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer);
4460        paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer);
4461
4462        // Switch the clipping rectangle to the outline version.
4463        if (shouldClip && clippedRect != layerFragments[0].outlineRect) {
4464            restoreClip(context, localPaintingInfo.paintDirtyRect, clippedRect);
4465
4466            if (!layerFragments[0].outlineRect.isEmpty()) {
4467                clippedRect = layerFragments[0].outlineRect;
4468                clipToRect(localPaintingInfo, context, clippedRect);
4469            } else
4470                shouldClip = false;
4471        }
4472
4473        paintForegroundForFragmentsWithPhase(PaintPhaseChildOutlines, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer);
4474    }
4475
4476    if (shouldClip)
4477        restoreClip(context, localPaintingInfo.paintDirtyRect, clippedRect);
4478}
4479
4480void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const LayerFragments& layerFragments, GraphicsContext* context,
4481    const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, RenderObject* subtreePaintRootForRenderer)
4482{
4483    bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() > 1;
4484
4485    for (size_t i = 0; i < layerFragments.size(); ++i) {
4486        const LayerFragment& fragment = layerFragments.at(i);
4487        if (!fragment.shouldPaintContent || fragment.foregroundRect.isEmpty())
4488            continue;
4489
4490        if (shouldClip)
4491            clipToRect(localPaintingInfo, context, fragment.foregroundRect);
4492
4493        PaintInfo paintInfo(context, fragment.foregroundRect.rect(), phase, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer());
4494        if (phase == PaintPhaseForeground)
4495            paintInfo.overlapTestRequests = localPaintingInfo.overlapTestRequests;
4496        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation));
4497
4498        if (shouldClip)
4499            restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
4500    }
4501}
4502
4503void RenderLayer::paintOutlineForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
4504    PaintBehavior paintBehavior, RenderObject* subtreePaintRootForRenderer)
4505{
4506    for (size_t i = 0; i < layerFragments.size(); ++i) {
4507        const LayerFragment& fragment = layerFragments.at(i);
4508        if (fragment.outlineRect.isEmpty())
4509            continue;
4510
4511        // Paint our own outline
4512        PaintInfo paintInfo(context, fragment.outlineRect.rect(), PaintPhaseSelfOutline, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer());
4513        clipToRect(localPaintingInfo, context, fragment.outlineRect, DoNotIncludeSelfForBorderRadius);
4514        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation));
4515        restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.outlineRect);
4516    }
4517}
4518
4519void RenderLayer::paintMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
4520    RenderObject* subtreePaintRootForRenderer)
4521{
4522    for (size_t i = 0; i < layerFragments.size(); ++i) {
4523        const LayerFragment& fragment = layerFragments.at(i);
4524        if (!fragment.shouldPaintContent)
4525            continue;
4526
4527        if (localPaintingInfo.clipToDirtyRect)
4528            clipToRect(localPaintingInfo, context, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self.
4529
4530        // Paint the mask.
4531        // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
4532        PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseMask, PaintBehaviorNormal, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer());
4533        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation));
4534
4535        if (localPaintingInfo.clipToDirtyRect)
4536            restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
4537    }
4538}
4539
4540void RenderLayer::paintOverflowControlsForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo)
4541{
4542    for (size_t i = 0; i < layerFragments.size(); ++i) {
4543        const LayerFragment& fragment = layerFragments.at(i);
4544        clipToRect(localPaintingInfo, context, fragment.backgroundRect);
4545        paintOverflowControls(context, roundedIntPoint(toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation)),
4546            pixelSnappedIntRect(fragment.backgroundRect.rect()), true);
4547        restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
4548    }
4549}
4550
4551bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
4552{
4553    return hitTest(request, result.hitTestLocation(), result);
4554}
4555
4556bool RenderLayer::hitTest(const HitTestRequest& request, const HitTestLocation& hitTestLocation, HitTestResult& result)
4557{
4558    ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
4559
4560    renderer().document().updateLayout();
4561
4562    LayoutRect hitTestArea = isOutOfFlowRenderFlowThread() ? toRenderFlowThread(&renderer())->visualOverflowRect() : renderer().view().documentRect();
4563    if (!request.ignoreClipping())
4564        hitTestArea.intersect(renderer().view().frameView().visibleContentRect(LegacyIOSDocumentVisibleRect));
4565
4566    RenderLayer* insideLayer = hitTestLayer(this, nullptr, request, result, hitTestArea, hitTestLocation, false);
4567    if (!insideLayer) {
4568        // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down,
4569        // return ourselves. We do this so mouse events continue getting delivered after a drag has
4570        // exited the WebView, and so hit testing over a scrollbar hits the content document.
4571        if (!request.isChildFrameHitTest() && (request.active() || request.release()) && isRootLayer()) {
4572            renderer().updateHitTestResult(result, toRenderView(renderer()).flipForWritingMode(hitTestLocation.point()));
4573            insideLayer = this;
4574        }
4575    }
4576
4577    // Now determine if the result is inside an anchor - if the urlElement isn't already set.
4578    Node* node = result.innerNode();
4579    if (node && !result.URLElement())
4580        result.setURLElement(node->enclosingLinkEventParentOrSelf());
4581
4582    // Now return whether we were inside this layer (this will always be true for the root
4583    // layer).
4584    return insideLayer;
4585}
4586
4587Element* RenderLayer::enclosingElement() const
4588{
4589    for (RenderElement* r = &renderer(); r; r = r->parent()) {
4590        if (Element* e = r->element())
4591            return e;
4592    }
4593    return 0;
4594}
4595
4596RenderLayer* RenderLayer::enclosingFlowThreadAncestor() const
4597{
4598    RenderLayer* curr = parent();
4599    for (; curr && !curr->isRenderFlowThread(); curr = curr->parent()) {
4600        if (curr->isStackingContainer() && curr->isComposited()) {
4601            // We only adjust the position of the first level of layers.
4602            return 0;
4603        }
4604    }
4605    return curr;
4606}
4607
4608bool RenderLayer::isFlowThreadCollectingGraphicsLayersUnderRegions() const
4609{
4610    return renderer().isRenderFlowThread() && toRenderFlowThread(renderer()).collectsGraphicsLayersUnderRegions();
4611}
4612
4613// Compute the z-offset of the point in the transformState.
4614// This is effectively projecting a ray normal to the plane of ancestor, finding where that
4615// ray intersects target, and computing the z delta between those two points.
4616static double computeZOffset(const HitTestingTransformState& transformState)
4617{
4618    // We got an affine transform, so no z-offset
4619    if (transformState.m_accumulatedTransform.isAffine())
4620        return 0;
4621
4622    // Flatten the point into the target plane
4623    FloatPoint targetPoint = transformState.mappedPoint();
4624
4625    // Now map the point back through the transform, which computes Z.
4626    FloatPoint3D backmappedPoint = transformState.m_accumulatedTransform.mapPoint(FloatPoint3D(targetPoint));
4627    return backmappedPoint.z();
4628}
4629
4630PassRefPtr<HitTestingTransformState> RenderLayer::createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer,
4631                                        const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
4632                                        const HitTestingTransformState* containerTransformState,
4633                                        const LayoutSize& translationOffset) const
4634{
4635    RefPtr<HitTestingTransformState> transformState;
4636    LayoutSize offset;
4637    if (containerTransformState) {
4638        // If we're already computing transform state, then it's relative to the container (which we know is non-null).
4639        transformState = HitTestingTransformState::create(*containerTransformState);
4640        offset = offsetFromAncestor(containerLayer);
4641    } else {
4642        // If this is the first time we need to make transform state, then base it off of hitTestLocation,
4643        // which is relative to rootLayer.
4644        transformState = HitTestingTransformState::create(hitTestLocation.transformedPoint(), hitTestLocation.transformedRect(), FloatQuad(hitTestRect));
4645        offset = offsetFromAncestor(rootLayer);
4646    }
4647    offset += translationOffset;
4648
4649    RenderObject* containerRenderer = containerLayer ? &containerLayer->renderer() : 0;
4650    if (renderer().shouldUseTransformFromContainer(containerRenderer)) {
4651        TransformationMatrix containerTransform;
4652        renderer().getTransformFromContainer(containerRenderer, offset, containerTransform);
4653        transformState->applyTransform(containerTransform, HitTestingTransformState::AccumulateTransform);
4654    } else {
4655        transformState->translate(offset.width(), offset.height(), HitTestingTransformState::AccumulateTransform);
4656    }
4657
4658    return transformState;
4659}
4660
4661
4662static bool isHitCandidate(const RenderLayer* hitLayer, bool canDepthSort, double* zOffset, const HitTestingTransformState* transformState)
4663{
4664    if (!hitLayer)
4665        return false;
4666
4667    // RenderNamedFlowFragments are not hit candidates. The hit test algorithm will pick the parent
4668    // layer, the one of the region.
4669    if (hitLayer->renderer().isRenderNamedFlowFragment())
4670        return false;
4671
4672    // The hit layer is depth-sorting with other layers, so just say that it was hit.
4673    if (canDepthSort)
4674        return true;
4675
4676    // We need to look at z-depth to decide if this layer was hit.
4677    if (zOffset) {
4678        ASSERT(transformState);
4679        // This is actually computing our z, but that's OK because the hitLayer is coplanar with us.
4680        double childZOffset = computeZOffset(*transformState);
4681        if (childZOffset > *zOffset) {
4682            *zOffset = childZOffset;
4683            return true;
4684        }
4685        return false;
4686    }
4687
4688    return true;
4689}
4690
4691RenderLayer* RenderLayer::hitTestFixedLayersInNamedFlows(RenderLayer* /*rootLayer*/,
4692    const HitTestRequest& request, HitTestResult& result,
4693    const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
4694    const HitTestingTransformState* transformState,
4695    double* zOffsetForDescendants, double* zOffset,
4696    const HitTestingTransformState* unflattenedTransformState,
4697    bool depthSortDescendants)
4698{
4699    if (!isRootLayer())
4700        return 0;
4701
4702    // Get the named flows for the view
4703    if (!renderer().view().hasRenderNamedFlowThreads())
4704        return 0;
4705
4706    Vector<RenderLayer*> fixedLayers;
4707    renderer().view().flowThreadController().collectFixedPositionedLayers(fixedLayers);
4708
4709    // Hit test the layers
4710    RenderLayer* resultLayer = 0;
4711    for (int i = fixedLayers.size() - 1; i >= 0; --i) {
4712        RenderLayer* fixedLayer = fixedLayers.at(i);
4713
4714        HitTestResult tempResult(result.hitTestLocation());
4715        RenderLayer* hitLayer = fixedLayer->hitTestLayer(fixedLayer->renderer().flowThreadContainingBlock()->layer(), nullptr, request, tempResult,
4716            hitTestRect, hitTestLocation, false, transformState, zOffsetForDescendants);
4717
4718        // If it a rect-based test, we can safely append the temporary result since it might had hit
4719        // nodes but not necesserily had hitLayer set.
4720        if (result.isRectBasedTest())
4721            result.append(tempResult);
4722
4723        if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState)) {
4724            resultLayer = hitLayer;
4725            if (!result.isRectBasedTest())
4726                result = tempResult;
4727            if (!depthSortDescendants)
4728                break;
4729        }
4730    }
4731
4732    return resultLayer;
4733}
4734
4735// hitTestLocation and hitTestRect are relative to rootLayer.
4736// A 'flattening' layer is one preserves3D() == false.
4737// transformState.m_accumulatedTransform holds the transform from the containing flattening layer.
4738// transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the containing flattening layer.
4739// transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of the containing flattening layer.
4740//
4741// If zOffset is non-null (which indicates that the caller wants z offset information),
4742//  *zOffset on return is the z offset of the hit point relative to the containing flattening layer.
4743RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
4744                                       const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, bool appliedTransform,
4745                                       const HitTestingTransformState* transformState, double* zOffset)
4746{
4747    if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
4748        return 0;
4749
4750    RenderNamedFlowFragment* namedFlowFragment = currentRenderNamedFlowFragment();
4751
4752    // Prevent hitting the fixed layers inside the flow thread when hitting through regions.
4753    if (renderer().fixedPositionedWithNamedFlowContainingBlock() && namedFlowFragment)
4754        return 0;
4755
4756    // Don't hit-test the layer if the renderer doesn't belong to this region.
4757    // This is true as long as we clamp the range of a box to its containing block range.
4758    // FIXME: Fix hit testing with in-flow threads included in out-of-flow threads.
4759    if (namedFlowFragment) {
4760        ASSERT(namedFlowFragment->isValid());
4761        RenderFlowThread* flowThread = namedFlowFragment->flowThread();
4762        if (!flowThread->objectShouldFragmentInFlowRegion(&renderer(), namedFlowFragment))
4763            return 0;
4764    }
4765
4766    // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
4767
4768    // Apply a transform if we have one.
4769    if (transform() && !appliedTransform) {
4770        if (enclosingPaginationLayer(IncludeCompositedPaginatedLayers))
4771            return hitTestTransformedLayerInFragments(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset);
4772
4773        // Make sure the parent's clip rects have been calculated.
4774        if (parent()) {
4775            ClipRectsContext clipRectsContext(rootLayer, RootRelativeClipRects, IncludeOverlayScrollbarSize);
4776            ClipRect clipRect = backgroundClipRect(clipRectsContext);
4777            // Go ahead and test the enclosing clip now.
4778            if (!clipRect.intersects(hitTestLocation))
4779                return 0;
4780        }
4781
4782        return hitTestLayerByApplyingTransform(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset);
4783    }
4784
4785    // Ensure our lists and 3d status are up-to-date.
4786    updateCompositingAndLayerListsIfNeeded();
4787    update3DTransformedDescendantStatus();
4788
4789    RefPtr<HitTestingTransformState> localTransformState;
4790    if (appliedTransform) {
4791        // We computed the correct state in the caller (above code), so just reference it.
4792        ASSERT(transformState);
4793        localTransformState = const_cast<HitTestingTransformState*>(transformState);
4794    } else if (transformState || has3DTransformedDescendant() || preserves3D()) {
4795        // We need transform state for the first time, or to offset the container state, so create it here.
4796        localTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState);
4797    }
4798
4799    // Check for hit test on backface if backface-visibility is 'hidden'
4800    if (localTransformState && renderer().style().backfaceVisibility() == BackfaceVisibilityHidden) {
4801        TransformationMatrix invertedMatrix = localTransformState->m_accumulatedTransform.inverse();
4802        // If the z-vector of the matrix is negative, the back is facing towards the viewer.
4803        if (invertedMatrix.m33() < 0)
4804            return 0;
4805    }
4806
4807    RefPtr<HitTestingTransformState> unflattenedTransformState = localTransformState;
4808    if (localTransformState && !preserves3D()) {
4809        // Keep a copy of the pre-flattening state, for computing z-offsets for the container
4810        unflattenedTransformState = HitTestingTransformState::create(*localTransformState);
4811        // This layer is flattening, so flatten the state passed to descendants.
4812        localTransformState->flatten();
4813    }
4814
4815    // The following are used for keeping track of the z-depth of the hit point of 3d-transformed
4816    // descendants.
4817    double localZOffset = -std::numeric_limits<double>::infinity();
4818    double* zOffsetForDescendantsPtr = 0;
4819    double* zOffsetForContentsPtr = 0;
4820
4821    bool depthSortDescendants = false;
4822    if (preserves3D()) {
4823        depthSortDescendants = true;
4824        // Our layers can depth-test with our container, so share the z depth pointer with the container, if it passed one down.
4825        zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
4826        zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
4827    } else if (zOffset) {
4828        zOffsetForDescendantsPtr = 0;
4829        // Container needs us to give back a z offset for the hit layer.
4830        zOffsetForContentsPtr = zOffset;
4831    }
4832
4833    // This variable tracks which layer the mouse ends up being inside.
4834    RenderLayer* candidateLayer = 0;
4835
4836    // Check the fixed positioned layers within flow threads that are positioned by the view.
4837    RenderLayer* hitLayer = hitTestFixedLayersInNamedFlows(rootLayer, request, result, hitTestRect, hitTestLocation,
4838        localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
4839    if (hitLayer) {
4840        if (!depthSortDescendants)
4841            return hitLayer;
4842        candidateLayer = hitLayer;
4843    }
4844
4845    // Begin by walking our list of positive layers from highest z-index down to the lowest z-index.
4846    hitLayer = hitTestList(posZOrderList(), rootLayer, request, result, hitTestRect, hitTestLocation,
4847                                        localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
4848    if (hitLayer) {
4849        if (!depthSortDescendants)
4850            return hitLayer;
4851        candidateLayer = hitLayer;
4852    }
4853
4854    // Now check our overflow objects.
4855    hitLayer = hitTestList(m_normalFlowList.get(), rootLayer, request, result, hitTestRect, hitTestLocation,
4856                           localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
4857    if (hitLayer) {
4858        if (!depthSortDescendants)
4859            return hitLayer;
4860        candidateLayer = hitLayer;
4861    }
4862
4863    // Collect the fragments. This will compute the clip rectangles for each layer fragment.
4864    LayerFragments layerFragments;
4865    collectFragments(layerFragments, rootLayer, hitTestRect, IncludeCompositedPaginatedLayers, RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip,
4866        offsetFromAncestor(rootLayer));
4867
4868    if (canResize() && hitTestResizerInFragments(layerFragments, hitTestLocation)) {
4869        renderer().updateHitTestResult(result, hitTestLocation.point());
4870        return this;
4871    }
4872
4873    hitLayer = hitTestFlowThreadIfRegionForFragments(layerFragments, rootLayer, request, result, hitTestRect, hitTestLocation,
4874        localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
4875    if (hitLayer) {
4876        if (!depthSortDescendants)
4877            return hitLayer;
4878        candidateLayer = hitLayer;
4879    }
4880
4881    // Next we want to see if the mouse pos is inside the child RenderObjects of the layer. Check
4882    // every fragment in reverse order.
4883    if (isSelfPaintingLayer()) {
4884        // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost.
4885        HitTestResult tempResult(result.hitTestLocation());
4886        bool insideFragmentForegroundRect = false;
4887        if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestDescendants, insideFragmentForegroundRect)
4888            && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
4889            if (result.isRectBasedTest())
4890                result.append(tempResult);
4891            else
4892                result = tempResult;
4893            if (!depthSortDescendants)
4894                return this;
4895            // Foreground can depth-sort with descendant layers, so keep this as a candidate.
4896            candidateLayer = this;
4897        } else if (insideFragmentForegroundRect && result.isRectBasedTest())
4898            result.append(tempResult);
4899    }
4900
4901    // Now check our negative z-index children.
4902    hitLayer = hitTestList(negZOrderList(), rootLayer, request, result, hitTestRect, hitTestLocation,
4903        localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
4904    if (hitLayer) {
4905        if (!depthSortDescendants)
4906            return hitLayer;
4907        candidateLayer = hitLayer;
4908    }
4909
4910    // If we found a layer, return. Child layers, and foreground always render in front of background.
4911    if (candidateLayer)
4912        return candidateLayer;
4913
4914    if (isSelfPaintingLayer()) {
4915        HitTestResult tempResult(result.hitTestLocation());
4916        bool insideFragmentBackgroundRect = false;
4917        if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestSelf, insideFragmentBackgroundRect)
4918            && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
4919            if (result.isRectBasedTest())
4920                result.append(tempResult);
4921            else
4922                result = tempResult;
4923            return this;
4924        }
4925        if (insideFragmentBackgroundRect && result.isRectBasedTest())
4926            result.append(tempResult);
4927    }
4928
4929    return 0;
4930}
4931
4932bool RenderLayer::hitTestContentsForFragments(const LayerFragments& layerFragments, const HitTestRequest& request, HitTestResult& result,
4933    const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter, bool& insideClipRect) const
4934{
4935    if (layerFragments.isEmpty())
4936        return false;
4937
4938    for (int i = layerFragments.size() - 1; i >= 0; --i) {
4939        const LayerFragment& fragment = layerFragments.at(i);
4940        if ((hitTestFilter == HitTestSelf && !fragment.backgroundRect.intersects(hitTestLocation))
4941            || (hitTestFilter == HitTestDescendants && !fragment.foregroundRect.intersects(hitTestLocation)))
4942            continue;
4943        insideClipRect = true;
4944        if (hitTestContents(request, result, fragment.layerBounds, hitTestLocation, hitTestFilter))
4945            return true;
4946    }
4947
4948    return false;
4949}
4950
4951bool RenderLayer::hitTestResizerInFragments(const LayerFragments& layerFragments, const HitTestLocation& hitTestLocation) const
4952{
4953    if (layerFragments.isEmpty())
4954        return false;
4955
4956    for (int i = layerFragments.size() - 1; i >= 0; --i) {
4957        const LayerFragment& fragment = layerFragments.at(i);
4958        if (fragment.backgroundRect.intersects(hitTestLocation) && resizerCornerRect(this, pixelSnappedIntRect(fragment.layerBounds)).contains(hitTestLocation.roundedPoint()))
4959            return true;
4960    }
4961
4962    return false;
4963}
4964
4965RenderLayer* RenderLayer::hitTestTransformedLayerInFragments(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
4966    const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset)
4967{
4968    LayerFragments enclosingPaginationFragments;
4969    LayoutSize offsetOfPaginationLayerFromRoot;
4970    RenderLayer* paginatedLayer = enclosingPaginationLayer(IncludeCompositedPaginatedLayers);
4971    LayoutRect transformedExtent = transparencyClipBox(*this, paginatedLayer, HitTestingTransparencyClipBox, RootOfTransparencyClipBox);
4972    paginatedLayer->collectFragments(enclosingPaginationFragments, rootLayer, hitTestRect, IncludeCompositedPaginatedLayers,
4973        RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, offsetOfPaginationLayerFromRoot, &transformedExtent);
4974
4975    for (int i = enclosingPaginationFragments.size() - 1; i >= 0; --i) {
4976        const LayerFragment& fragment = enclosingPaginationFragments.at(i);
4977
4978        // Apply the page/column clip for this fragment, as well as any clips established by layers in between us and
4979        // the enclosing pagination layer.
4980        LayoutRect clipRect = fragment.backgroundRect.rect();
4981
4982        // Now compute the clips within a given fragment
4983        if (parent() != paginatedLayer) {
4984            offsetOfPaginationLayerFromRoot = toLayoutSize(paginatedLayer->convertToLayerCoords(rootLayer, toLayoutPoint(offsetOfPaginationLayerFromRoot)));
4985
4986            ClipRectsContext clipRectsContext(paginatedLayer, RootRelativeClipRects, IncludeOverlayScrollbarSize);
4987            LayoutRect parentClipRect = backgroundClipRect(clipRectsContext).rect();
4988            parentClipRect.move(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
4989            clipRect.intersect(parentClipRect);
4990        }
4991
4992        if (!hitTestLocation.intersects(clipRect))
4993            continue;
4994
4995        RenderLayer* hitLayer = hitTestLayerByApplyingTransform(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation,
4996            transformState, zOffset, fragment.paginationOffset);
4997        if (hitLayer)
4998            return hitLayer;
4999    }
5000
5001    return 0;
5002}
5003
5004RenderLayer* RenderLayer::hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
5005    const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset,
5006    const LayoutSize& translationOffset)
5007{
5008    // Create a transform state to accumulate this transform.
5009    RefPtr<HitTestingTransformState> newTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState, translationOffset);
5010
5011    // If the transform can't be inverted, then don't hit test this layer at all.
5012    if (!newTransformState->m_accumulatedTransform.isInvertible())
5013        return 0;
5014
5015    // Compute the point and the hit test rect in the coords of this layer by using the values
5016    // from the transformState, which store the point and quad in the coords of the last flattened
5017    // layer, and the accumulated transform which lets up map through preserve-3d layers.
5018    //
5019    // We can't just map hitTestLocation and hitTestRect because they may have been flattened (losing z)
5020    // by our container.
5021    FloatPoint localPoint = newTransformState->mappedPoint();
5022    FloatQuad localPointQuad = newTransformState->mappedQuad();
5023    LayoutRect localHitTestRect = newTransformState->boundsOfMappedArea();
5024    HitTestLocation newHitTestLocation;
5025    if (hitTestLocation.isRectBasedTest())
5026        newHitTestLocation = HitTestLocation(localPoint, localPointQuad);
5027    else
5028        newHitTestLocation = HitTestLocation(localPoint);
5029
5030    // Now do a hit test with the root layer shifted to be us.
5031    return hitTestLayer(this, containerLayer, request, result, localHitTestRect, newHitTestLocation, true, newTransformState.get(), zOffset);
5032}
5033
5034bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter) const
5035{
5036    ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
5037
5038    if (!renderer().hitTest(request, result, hitTestLocation, toLayoutPoint(layerBounds.location() - renderBoxLocation()), hitTestFilter)) {
5039        // It's wrong to set innerNode, but then claim that you didn't hit anything, unless it is
5040        // a rect-based test.
5041        ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBasedTestResult().size()));
5042        return false;
5043    }
5044
5045    // For positioned generated content, we might still not have a
5046    // node by the time we get to the layer level, since none of
5047    // the content in the layer has an element. So just walk up
5048    // the tree.
5049    if (!result.innerNode() || !result.innerNonSharedNode()) {
5050        if (isOutOfFlowRenderFlowThread()) {
5051            // The flowthread doesn't have an enclosing element, so when hitting the layer of the
5052            // flowthread (e.g. the descent area of the RootInlineBox for the image flowed alone
5053            // inside the flow thread) we're letting the hit testing continue so it will hit the region.
5054            return false;
5055        }
5056
5057        Element* e = enclosingElement();
5058        if (!result.innerNode())
5059            result.setInnerNode(e);
5060        if (!result.innerNonSharedNode())
5061            result.setInnerNonSharedNode(e);
5062    }
5063
5064    return true;
5065}
5066
5067RenderLayer* RenderLayer::hitTestList(Vector<RenderLayer*>* list, RenderLayer* rootLayer,
5068                                      const HitTestRequest& request, HitTestResult& result,
5069                                      const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
5070                                      const HitTestingTransformState* transformState,
5071                                      double* zOffsetForDescendants, double* zOffset,
5072                                      const HitTestingTransformState* unflattenedTransformState,
5073                                      bool depthSortDescendants)
5074{
5075    if (!list)
5076        return 0;
5077
5078    if (!hasSelfPaintingLayerDescendant())
5079        return 0;
5080
5081    RenderLayer* resultLayer = 0;
5082    for (int i = list->size() - 1; i >= 0; --i) {
5083        RenderLayer* childLayer = list->at(i);
5084        if (childLayer->isFlowThreadCollectingGraphicsLayersUnderRegions())
5085            continue;
5086        RenderLayer* hitLayer = 0;
5087        HitTestResult tempResult(result.hitTestLocation());
5088        hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestLocation, false, transformState, zOffsetForDescendants);
5089
5090        // If it a rect-based test, we can safely append the temporary result since it might had hit
5091        // nodes but not necesserily had hitLayer set.
5092        if (result.isRectBasedTest())
5093            result.append(tempResult);
5094
5095        if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState)) {
5096            resultLayer = hitLayer;
5097            if (!result.isRectBasedTest())
5098                result = tempResult;
5099            if (!depthSortDescendants)
5100                break;
5101        }
5102    }
5103
5104    return resultLayer;
5105}
5106
5107void RenderLayer::updateClipRects(const ClipRectsContext& clipRectsContext)
5108{
5109    ClipRectsType clipRectsType = clipRectsContext.clipRectsType;
5110    ASSERT(clipRectsType < NumCachedClipRectsTypes);
5111    if (m_clipRectsCache && m_clipRectsCache->getClipRects(clipRectsType, clipRectsContext.respectOverflowClip)) {
5112        ASSERT(clipRectsContext.rootLayer == m_clipRectsCache->m_clipRectsRoot[clipRectsType]);
5113        ASSERT(m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] == clipRectsContext.overlayScrollbarSizeRelevancy);
5114
5115#ifdef CHECK_CACHED_CLIP_RECTS
5116        // This code is useful to check cached clip rects, but is too expensive to leave enabled in debug builds by default.
5117        ClipRectsContext tempContext(clipRectsContext);
5118        tempContext.clipRectsType = TemporaryClipRects;
5119        ClipRects clipRects;
5120        calculateClipRects(tempContext, clipRects);
5121        ASSERT(clipRects == *m_clipRectsCache->getClipRects(clipRectsType, clipRectsContext.respectOverflowClip).get());
5122#endif
5123        return; // We have the correct cached value.
5124    }
5125
5126    // For transformed layers, the root layer was shifted to be us, so there is no need to
5127    // examine the parent.  We want to cache clip rects with us as the root.
5128    RenderLayer* parentLayer = clipRectsContext.rootLayer != this ? parent() : 0;
5129    if (parentLayer)
5130        parentLayer->updateClipRects(clipRectsContext);
5131
5132    ClipRects clipRects;
5133    calculateClipRects(clipRectsContext, clipRects);
5134
5135    if (!m_clipRectsCache)
5136        m_clipRectsCache = std::make_unique<ClipRectsCache>();
5137
5138    if (parentLayer && parentLayer->clipRects(clipRectsContext) && clipRects == *parentLayer->clipRects(clipRectsContext))
5139        m_clipRectsCache->setClipRects(clipRectsType, clipRectsContext.respectOverflowClip, parentLayer->clipRects(clipRectsContext));
5140    else
5141        m_clipRectsCache->setClipRects(clipRectsType, clipRectsContext.respectOverflowClip, ClipRects::create(clipRects));
5142
5143#ifndef NDEBUG
5144    m_clipRectsCache->m_clipRectsRoot[clipRectsType] = clipRectsContext.rootLayer;
5145    m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] = clipRectsContext.overlayScrollbarSizeRelevancy;
5146#endif
5147}
5148
5149bool RenderLayer::mapLayerClipRectsToFragmentationLayer(ClipRects& clipRects) const
5150{
5151    RenderNamedFlowFragment* namedFlowFragment = currentRenderNamedFlowFragment();
5152    if (!namedFlowFragment)
5153        return false;
5154
5155    ASSERT(namedFlowFragment->parent() && namedFlowFragment->parent()->isRenderNamedFlowFragmentContainer());
5156
5157    CurrentRenderFlowThreadDisabler flowThreadDisabler(&renderer().view());
5158    ClipRectsContext targetClipRectsContext(&namedFlowFragment->fragmentContainerLayer(), TemporaryClipRects);
5159    namedFlowFragment->fragmentContainerLayer().calculateClipRects(targetClipRectsContext, clipRects);
5160
5161    LayoutRect flowThreadPortionRect = namedFlowFragment->flowThreadPortionRect();
5162
5163    LayoutPoint portionLocation = flowThreadPortionRect.location();
5164    LayoutRect regionContentBox = namedFlowFragment->fragmentContainer().contentBoxRect();
5165    LayoutSize moveOffset = portionLocation - regionContentBox.location() + namedFlowFragment->fragmentContainer().scrolledContentOffset();
5166
5167    ClipRect newOverflowClipRect = clipRects.overflowClipRect();
5168    newOverflowClipRect.move(moveOffset);
5169    clipRects.setOverflowClipRect(newOverflowClipRect);
5170
5171    ClipRect newFixedClipRect = clipRects.fixedClipRect();
5172    newFixedClipRect.move(moveOffset);
5173    clipRects.setFixedClipRect(newFixedClipRect);
5174
5175    ClipRect newPosClipRect = clipRects.posClipRect();
5176    newPosClipRect.move(moveOffset);
5177    clipRects.setPosClipRect(newPosClipRect);
5178
5179    return true;
5180}
5181
5182void RenderLayer::calculateClipRects(const ClipRectsContext& clipRectsContext, ClipRects& clipRects) const
5183{
5184    if (!parent()) {
5185        // The root layer's clip rect is always infinite.
5186        clipRects.reset(LayoutRect::infiniteRect());
5187        return;
5188    }
5189
5190    ClipRectsType clipRectsType = clipRectsContext.clipRectsType;
5191    bool useCached = clipRectsType != TemporaryClipRects;
5192
5193    if (renderer().isRenderNamedFlowThread() && mapLayerClipRectsToFragmentationLayer(clipRects))
5194        return;
5195
5196    // For transformed layers, the root layer was shifted to be us, so there is no need to
5197    // examine the parent. We want to cache clip rects with us as the root.
5198    RenderLayer* parentLayer = clipRectsContext.rootLayer != this ? parent() : 0;
5199
5200    // Ensure that our parent's clip has been calculated so that we can examine the values.
5201    if (parentLayer) {
5202        if (useCached && parentLayer->clipRects(clipRectsContext))
5203            clipRects = *parentLayer->clipRects(clipRectsContext);
5204        else {
5205            ClipRectsContext parentContext(clipRectsContext);
5206            parentContext.overlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize; // FIXME: why?
5207            parentLayer->calculateClipRects(parentContext, clipRects);
5208        }
5209    } else
5210        clipRects.reset(LayoutRect::infiniteRect());
5211
5212    // A fixed object is essentially the root of its containing block hierarchy, so when
5213    // we encounter such an object, we reset our clip rects to the fixedClipRect.
5214    if (renderer().style().position() == FixedPosition) {
5215        clipRects.setPosClipRect(clipRects.fixedClipRect());
5216        clipRects.setOverflowClipRect(clipRects.fixedClipRect());
5217        clipRects.setFixed(true);
5218    } else if (renderer().style().hasInFlowPosition())
5219        clipRects.setPosClipRect(clipRects.overflowClipRect());
5220    else if (renderer().style().position() == AbsolutePosition)
5221        clipRects.setOverflowClipRect(clipRects.posClipRect());
5222
5223    // Update the clip rects that will be passed to child layers.
5224#if PLATFORM(IOS)
5225    if (renderer().hasClipOrOverflowClip() && (clipRectsContext.respectOverflowClip == RespectOverflowClip || this != clipRectsContext.rootLayer)) {
5226#else
5227    if ((renderer().hasOverflowClip() && (clipRectsContext.respectOverflowClip == RespectOverflowClip || this != clipRectsContext.rootLayer)) || renderer().hasClip()) {
5228#endif
5229        // This layer establishes a clip of some kind.
5230
5231        // This offset cannot use convertToLayerCoords, because sometimes our rootLayer may be across
5232        // some transformed layer boundary, for example, in the RenderLayerCompositor overlapMap, where
5233        // clipRects are needed in view space.
5234        LayoutPoint offset;
5235        offset = roundedLayoutPoint(renderer().localToContainerPoint(FloatPoint(), &clipRectsContext.rootLayer->renderer()));
5236        if (clipRects.fixed() && &clipRectsContext.rootLayer->renderer() == &renderer().view())
5237            offset -= renderer().view().frameView().scrollOffsetForFixedPosition();
5238
5239        if (renderer().hasOverflowClip()) {
5240            ClipRect newOverflowClip = toRenderBox(renderer()).overflowClipRectForChildLayers(offset, currentRenderNamedFlowFragment(), clipRectsContext.overlayScrollbarSizeRelevancy);
5241            newOverflowClip.setHasRadius(renderer().style().hasBorderRadius());
5242            clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect()));
5243            if (renderer().isPositioned())
5244                clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect()));
5245        }
5246        if (renderer().hasClip()) {
5247            LayoutRect newPosClip = toRenderBox(renderer()).clipRect(offset, currentRenderNamedFlowFragment());
5248            clipRects.setPosClipRect(intersection(newPosClip, clipRects.posClipRect()));
5249            clipRects.setOverflowClipRect(intersection(newPosClip, clipRects.overflowClipRect()));
5250            clipRects.setFixedClipRect(intersection(newPosClip, clipRects.fixedClipRect()));
5251        }
5252    }
5253}
5254
5255void RenderLayer::parentClipRects(const ClipRectsContext& clipRectsContext, ClipRects& clipRects) const
5256{
5257    ASSERT(parent());
5258    if (renderer().isRenderNamedFlowThread() && mapLayerClipRectsToFragmentationLayer(clipRects))
5259        return;
5260
5261    if (clipRectsContext.clipRectsType == TemporaryClipRects) {
5262        parent()->calculateClipRects(clipRectsContext, clipRects);
5263        return;
5264    }
5265
5266    parent()->updateClipRects(clipRectsContext);
5267    clipRects = *parent()->clipRects(clipRectsContext);
5268}
5269
5270static inline ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, EPosition position)
5271{
5272    if (position == FixedPosition)
5273        return parentRects.fixedClipRect();
5274
5275    if (position == AbsolutePosition)
5276        return parentRects.posClipRect();
5277
5278    return parentRects.overflowClipRect();
5279}
5280
5281ClipRect RenderLayer::backgroundClipRect(const ClipRectsContext& clipRectsContext) const
5282{
5283    ASSERT(parent());
5284
5285    ClipRects parentRects;
5286
5287    // If we cross into a different pagination context, then we can't rely on the cache.
5288    // Just switch over to using TemporaryClipRects.
5289    if (clipRectsContext.clipRectsType != TemporaryClipRects && parent()->enclosingPaginationLayer(IncludeCompositedPaginatedLayers) != enclosingPaginationLayer(IncludeCompositedPaginatedLayers)) {
5290        ClipRectsContext tempContext(clipRectsContext);
5291        tempContext.clipRectsType = TemporaryClipRects;
5292        parentClipRects(tempContext, parentRects);
5293    } else
5294        parentClipRects(clipRectsContext, parentRects);
5295
5296    ClipRect backgroundClipRect = backgroundClipRectForPosition(parentRects, renderer().style().position());
5297    RenderView& view = renderer().view();
5298
5299    // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite.
5300    if (parentRects.fixed() && &clipRectsContext.rootLayer->renderer() == &view && backgroundClipRect != LayoutRect::infiniteRect())
5301        backgroundClipRect.move(view.frameView().scrollOffsetForFixedPosition());
5302
5303    return backgroundClipRect;
5304}
5305
5306void RenderLayer::calculateRects(const ClipRectsContext& clipRectsContext, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
5307    ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutSize& offsetFromRoot) const
5308{
5309    if (clipRectsContext.rootLayer != this && parent()) {
5310        backgroundRect = backgroundClipRect(clipRectsContext);
5311        backgroundRect.intersect(paintDirtyRect);
5312    } else
5313        backgroundRect = paintDirtyRect;
5314
5315    LayoutSize offsetFromRootLocal = offsetFromRoot;
5316    RenderNamedFlowFragment* namedFlowFragment = currentRenderNamedFlowFragment();
5317    // If the view is scrolled, the flow thread is not scrolled with it and we should
5318    // take the scroll offset into account.
5319    if (clipRectsContext.rootLayer->isOutOfFlowRenderFlowThread() && !namedFlowFragment) {
5320        LayoutPoint absPos = LayoutPoint(renderer().view().localToAbsolute(FloatPoint(), IsFixed));
5321        offsetFromRootLocal += toLayoutSize(absPos);
5322    }
5323
5324    layerBounds = LayoutRect(toLayoutPoint(offsetFromRootLocal), size());
5325
5326    foregroundRect = backgroundRect;
5327    outlineRect = backgroundRect;
5328
5329    RenderFlowThread* flowThread = namedFlowFragment ? namedFlowFragment->flowThread() : 0;
5330    if (isSelfPaintingLayer() && flowThread && !renderer().isInFlowRenderFlowThread()) {
5331        ASSERT(namedFlowFragment->isValid());
5332        const RenderBoxModelObject& boxModelObject = toRenderBoxModelObject(renderer());
5333        LayoutRect layerBoundsWithVisualOverflow = namedFlowFragment->visualOverflowRectForBox(&boxModelObject);
5334
5335        // Layers are in physical coordinates so the origin must be moved to the physical top-left of the flowthread.
5336        if (&boxModelObject == flowThread && flowThread->style().isFlippedBlocksWritingMode()) {
5337            if (flowThread->style().isHorizontalWritingMode())
5338                layerBoundsWithVisualOverflow.moveBy(LayoutPoint(0, flowThread->height()));
5339            else
5340                layerBoundsWithVisualOverflow.moveBy(LayoutPoint(flowThread->width(), 0));
5341        } else {
5342            RenderBlock* rendererContainingBlock = boxModelObject.enclosingBox().isRenderBlock() ? toRenderBlock(&boxModelObject.enclosingBox()) : 0;
5343            if (rendererContainingBlock)
5344                rendererContainingBlock->flipForWritingMode(layerBoundsWithVisualOverflow);
5345        }
5346
5347        layerBoundsWithVisualOverflow.move(offsetFromRootLocal);
5348        backgroundRect.intersect(layerBoundsWithVisualOverflow);
5349
5350        foregroundRect = backgroundRect;
5351        outlineRect = backgroundRect;
5352
5353        // If the region does not clip its overflow, inflate the outline rect.
5354        if (namedFlowFragment) {
5355            if (!(namedFlowFragment->parent()->hasOverflowClip() && (&namedFlowFragment->fragmentContainerLayer() != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip)))
5356                outlineRect.inflate(renderer().maximalOutlineSize(PaintPhaseOutline));
5357        }
5358    }
5359
5360    // Update the clip rects that will be passed to child layers.
5361    if (renderer().hasClipOrOverflowClip()) {
5362        // This layer establishes a clip of some kind.
5363        if (renderer().hasOverflowClip() && (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip)) {
5364            foregroundRect.intersect(toRenderBox(renderer()).overflowClipRect(toLayoutPoint(offsetFromRootLocal), namedFlowFragment, clipRectsContext.overlayScrollbarSizeRelevancy));
5365            foregroundRect.setHasRadius(renderer().style().hasBorderRadius());
5366        }
5367
5368        if (renderer().hasClip()) {
5369            // Clip applies to *us* as well, so go ahead and update the damageRect.
5370            LayoutRect newPosClip = toRenderBox(renderer()).clipRect(toLayoutPoint(offsetFromRootLocal), namedFlowFragment);
5371            backgroundRect.intersect(newPosClip);
5372            foregroundRect.intersect(newPosClip);
5373            outlineRect.intersect(newPosClip);
5374        }
5375
5376        // If we establish a clip at all, then go ahead and make sure our background
5377        // rect is intersected with our layer's bounds including our visual overflow,
5378        // since any visual overflow like box-shadow or border-outset is not clipped by overflow:auto/hidden.
5379        if (renderBox()->hasVisualOverflow()) {
5380            // FIXME: Does not do the right thing with CSS regions yet, since we don't yet factor in the
5381            // individual region boxes as overflow.
5382            LayoutRect layerBoundsWithVisualOverflow = namedFlowFragment ? namedFlowFragment->visualOverflowRectForBox(renderBox()) : renderBox()->visualOverflowRect();
5383            renderBox()->flipForWritingMode(layerBoundsWithVisualOverflow); // Layers are in physical coordinates, so the overflow has to be flipped.
5384            layerBoundsWithVisualOverflow.move(offsetFromRootLocal);
5385            if (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip)
5386                backgroundRect.intersect(layerBoundsWithVisualOverflow);
5387        } else {
5388            // Shift the bounds to be for our region only.
5389            LayoutRect bounds = renderBox()->borderBoxRectInRegion(namedFlowFragment);
5390            if (namedFlowFragment)
5391                bounds = namedFlowFragment->rectFlowPortionForBox(renderBox(), bounds);
5392
5393            bounds.move(offsetFromRootLocal);
5394            if (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip)
5395                backgroundRect.intersect(bounds);
5396
5397            // Boxes inside flow threads don't have their logical left computed to avoid
5398            // floats. Instead, that information is kept in their RenderBoxRegionInfo structure.
5399            // As such, the layer bounds must be enlarged to encompass their background rect
5400            // to ensure intersecting them won't result in an empty rect, which would eventually
5401            // cause paint rejection.
5402            if (flowThread && flowThread->isRenderNamedFlowThread()) {
5403                if (flowThread->style().isHorizontalWritingMode())
5404                    layerBounds.shiftMaxXEdgeTo(std::max(layerBounds.maxX(), backgroundRect.rect().maxX()));
5405                else
5406                    layerBounds.shiftMaxYEdgeTo(std::max(layerBounds.maxY(), backgroundRect.rect().maxY()));
5407            }
5408        }
5409    }
5410}
5411
5412LayoutRect RenderLayer::childrenClipRect() const
5413{
5414    // FIXME: border-radius not accounted for.
5415    // FIXME: Regions not accounted for.
5416    RenderLayer* clippingRootLayer = clippingRootForPainting();
5417    LayoutRect layerBounds;
5418    ClipRect backgroundRect, foregroundRect, outlineRect;
5419    ClipRectsContext clipRectsContext(clippingRootLayer, TemporaryClipRects);
5420    // Need to use temporary clip rects, because the value of 'dontClipToOverflow' may be different from the painting path (<rdar://problem/11844909>).
5421    calculateRects(clipRectsContext, renderer().view().unscaledDocumentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect, offsetFromAncestor(clipRectsContext.rootLayer));
5422    return clippingRootLayer->renderer().localToAbsoluteQuad(FloatQuad(foregroundRect.rect())).enclosingBoundingBox();
5423}
5424
5425LayoutRect RenderLayer::selfClipRect() const
5426{
5427    // FIXME: border-radius not accounted for.
5428    // FIXME: Regions not accounted for.
5429    RenderLayer* clippingRootLayer = clippingRootForPainting();
5430    LayoutRect layerBounds;
5431    ClipRect backgroundRect, foregroundRect, outlineRect;
5432    ClipRectsContext clipRectsContext(clippingRootLayer, PaintingClipRects);
5433    calculateRects(clipRectsContext, renderer().view().documentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect, offsetFromAncestor(clippingRootLayer));
5434    return clippingRootLayer->renderer().localToAbsoluteQuad(FloatQuad(backgroundRect.rect())).enclosingBoundingBox();
5435}
5436
5437LayoutRect RenderLayer::localClipRect(bool& clipExceedsBounds) const
5438{
5439    clipExceedsBounds = false;
5440    // FIXME: border-radius not accounted for.
5441    // FIXME: Regions not accounted for.
5442    RenderLayer* clippingRootLayer = clippingRootForPainting();
5443    LayoutSize offsetFromRoot = offsetFromAncestor(clippingRootLayer);
5444
5445    LayoutRect layerBounds;
5446    ClipRect backgroundRect, foregroundRect, outlineRect;
5447    ClipRectsContext clipRectsContext(clippingRootLayer, PaintingClipRects);
5448    calculateRects(clipRectsContext, LayoutRect::infiniteRect(), layerBounds, backgroundRect, foregroundRect, outlineRect, offsetFromRoot);
5449
5450    LayoutRect clipRect = backgroundRect.rect();
5451    if (clipRect == LayoutRect::infiniteRect())
5452        return clipRect;
5453
5454    if (renderer().hasClip()) {
5455        // CSS clip may be larger than our border box.
5456        LayoutRect cssClipRect = toRenderBox(renderer()).clipRect(toLayoutPoint(offsetFromRoot), currentRenderNamedFlowFragment());
5457        clipExceedsBounds = !clipRect.contains(cssClipRect);
5458    }
5459
5460    clipRect.move(-offsetFromRoot);
5461    return clipRect;
5462}
5463
5464void RenderLayer::addBlockSelectionGapsBounds(const LayoutRect& bounds)
5465{
5466    m_blockSelectionGapsBounds.unite(enclosingIntRect(bounds));
5467}
5468
5469void RenderLayer::clearBlockSelectionGapsBounds()
5470{
5471    m_blockSelectionGapsBounds = IntRect();
5472    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
5473        child->clearBlockSelectionGapsBounds();
5474}
5475
5476void RenderLayer::repaintBlockSelectionGaps()
5477{
5478    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
5479        child->repaintBlockSelectionGaps();
5480
5481    if (m_blockSelectionGapsBounds.isEmpty())
5482        return;
5483
5484    LayoutRect rect = m_blockSelectionGapsBounds;
5485    rect.move(-scrolledContentOffset());
5486    if (renderer().hasOverflowClip() && !usesCompositedScrolling())
5487        rect.intersect(toRenderBox(renderer()).overflowClipRect(LayoutPoint(), nullptr)); // FIXME: Regions not accounted for.
5488    if (renderer().hasClip())
5489        rect.intersect(toRenderBox(renderer()).clipRect(LayoutPoint(), nullptr)); // FIXME: Regions not accounted for.
5490    if (!rect.isEmpty())
5491        renderer().repaintRectangle(rect);
5492}
5493
5494bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutSize& offsetFromRoot, const LayoutRect* cachedBoundingBox) const
5495{
5496    // Always examine the canvas and the root.
5497    // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
5498    // paints the root's background.
5499    if (isRootLayer() || renderer().isRoot())
5500        return true;
5501
5502    // If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we
5503    // can go ahead and return true.
5504    if (!renderer().isRenderInline()) {
5505        LayoutRect b = layerBounds;
5506        b.inflate(renderer().view().maximalOutlineSize());
5507        if (b.intersects(damageRect))
5508            return true;
5509    }
5510
5511    RenderNamedFlowFragment* namedFlowFragment = currentRenderNamedFlowFragment();
5512    // When using regions, some boxes might have their frame rect relative to the flow thread, which could
5513    // cause the paint rejection algorithm to prevent them from painting when using different width regions.
5514    // e.g. an absolutely positioned box with bottom:0px and right:0px would have it's frameRect.x relative
5515    // to the flow thread, not the last region (in which it will end up because of bottom:0px)
5516    if (namedFlowFragment && renderer().flowThreadContainingBlock()) {
5517        LayoutRect b = layerBounds;
5518        b.moveBy(namedFlowFragment->visualOverflowRectForBox(toRenderBoxModelObject(&renderer())).location());
5519        b.inflate(renderer().view().maximalOutlineSize());
5520        if (b.intersects(damageRect))
5521            return true;
5522    }
5523
5524    // Otherwise we need to compute the bounding box of this single layer and see if it intersects
5525    // the damage rect. It's possible the fragment computed the bounding box already, in which case we
5526    // can use the cached value.
5527    if (cachedBoundingBox)
5528        return cachedBoundingBox->intersects(damageRect);
5529
5530    return boundingBox(rootLayer, offsetFromRoot).intersects(damageRect);
5531}
5532
5533LayoutRect RenderLayer::localBoundingBox(CalculateLayerBoundsFlags flags) const
5534{
5535    // There are three special cases we need to consider.
5536    // (1) Inline Flows.  For inline flows we will create a bounding box that fully encompasses all of the lines occupied by the
5537    // inline.  In other words, if some <span> wraps to three lines, we'll create a bounding box that fully encloses the
5538    // line boxes of all three lines (including overflow on those lines).
5539    // (2) Left/Top Overflow.  The width/height of layers already includes right/bottom overflow.  However, in the case of left/top
5540    // overflow, we have to create a bounding box that will extend to include this overflow.
5541    // (3) Floats.  When a layer has overhanging floats that it paints, we need to make sure to include these overhanging floats
5542    // as part of our bounding box.  We do this because we are the responsible layer for both hit testing and painting those
5543    // floats.
5544    LayoutRect result;
5545    if (renderer().isInline() && renderer().isRenderInline())
5546        result = toRenderInline(renderer()).linesVisualOverflowBoundingBox();
5547    else if (renderer().isTableRow()) {
5548        RenderTableRow& tableRow = toRenderTableRow(renderer());
5549        // Our bounding box is just the union of all of our cells' border/overflow rects.
5550        for (RenderTableCell* cell = tableRow.firstCell(); cell; cell = cell->nextCell()) {
5551            LayoutRect bbox = cell->borderBoxRect();
5552            result.unite(bbox);
5553            LayoutRect overflowRect = tableRow.visualOverflowRect();
5554            if (bbox != overflowRect)
5555                result.unite(overflowRect);
5556        }
5557    } else {
5558        RenderBox* box = renderBox();
5559        ASSERT(box);
5560        if (!(flags & DontConstrainForMask) && box->hasMask()) {
5561            result = box->maskClipRect();
5562            box->flipForWritingMode(result); // The mask clip rect is in physical coordinates, so we have to flip, since localBoundingBox is not.
5563        } else {
5564            LayoutRect bbox = box->borderBoxRect();
5565            result = bbox;
5566            LayoutRect overflowRect = box->visualOverflowRect();
5567            if (bbox != overflowRect)
5568                result.unite(overflowRect);
5569        }
5570    }
5571
5572    result.inflate(renderer().view().maximalOutlineSize()); // Used to apply a fudge factor to dirty-rect checks on blocks/tables.
5573    return result;
5574}
5575
5576LayoutRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer, const LayoutSize& offsetFromRoot, CalculateLayerBoundsFlags flags) const
5577{
5578    LayoutRect result = localBoundingBox(flags);
5579    if (renderer().isBox())
5580        renderBox()->flipForWritingMode(result);
5581    else
5582        renderer().containingBlock()->flipForWritingMode(result);
5583
5584    PaginationInclusionMode inclusionMode = ExcludeCompositedPaginatedLayers;
5585    if (flags & UseFragmentBoxesIncludingCompositing)
5586        inclusionMode = IncludeCompositedPaginatedLayers;
5587    const RenderLayer* paginationLayer = nullptr;
5588    if (flags & UseFragmentBoxesExcludingCompositing || flags & UseFragmentBoxesIncludingCompositing)
5589        paginationLayer = enclosingPaginationLayerInSubtree(ancestorLayer, inclusionMode);
5590
5591    const RenderLayer* childLayer = this;
5592    bool isPaginated = paginationLayer;
5593    while (paginationLayer) {
5594        // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
5595        // get our true bounding box.
5596        result.move(childLayer->offsetFromAncestor(paginationLayer));
5597
5598        RenderFlowThread& enclosingFlowThread = toRenderFlowThread(paginationLayer->renderer());
5599        result = enclosingFlowThread.fragmentsBoundingBox(result);
5600
5601        childLayer = paginationLayer;
5602        paginationLayer = paginationLayer->parent()->enclosingPaginationLayerInSubtree(ancestorLayer, inclusionMode);
5603    }
5604
5605    if (isPaginated) {
5606        result.move(childLayer->offsetFromAncestor(ancestorLayer));
5607        return result;
5608    }
5609
5610    result.move(offsetFromRoot);
5611    return result;
5612}
5613
5614IntRect RenderLayer::absoluteBoundingBox() const
5615{
5616    const RenderLayer* rootLayer = root();
5617    return pixelSnappedIntRect(boundingBox(rootLayer, offsetFromAncestor(rootLayer)));
5618}
5619
5620FloatRect RenderLayer::absoluteBoundingBoxForPainting() const
5621{
5622    const RenderLayer* rootLayer = root();
5623    return pixelSnappedForPainting(boundingBox(rootLayer, offsetFromAncestor(rootLayer)), renderer().document().deviceScaleFactor());
5624}
5625
5626LayoutRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutSize& offsetFromRoot, CalculateLayerBoundsFlags flags) const
5627{
5628    if (!isSelfPaintingLayer())
5629        return LayoutRect();
5630
5631    // FIXME: This could be improved to do a check like hasVisibleNonCompositingDescendantLayers() (bug 92580).
5632    if ((flags & ExcludeHiddenDescendants) && this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant())
5633        return LayoutRect();
5634
5635    if (isRootLayer()) {
5636        // The root layer is always just the size of the document.
5637        return renderer().view().unscaledDocumentRect();
5638    }
5639
5640    LayoutRect boundingBoxRect = localBoundingBox(flags);
5641
5642    if (renderer().isBox())
5643        toRenderBox(renderer()).flipForWritingMode(boundingBoxRect);
5644    else
5645        renderer().containingBlock()->flipForWritingMode(boundingBoxRect);
5646
5647    if (renderer().isRoot()) {
5648        // If the root layer becomes composited (e.g. because some descendant with negative z-index is composited),
5649        // then it has to be big enough to cover the viewport in order to display the background. This is akin
5650        // to the code in RenderBox::paintRootBoxFillLayers().
5651        const FrameView& frameView = renderer().view().frameView();
5652        boundingBoxRect.setWidth(std::max(boundingBoxRect.width(), frameView.contentsWidth() - boundingBoxRect.x()));
5653        boundingBoxRect.setHeight(std::max(boundingBoxRect.height(), frameView.contentsHeight() - boundingBoxRect.y()));
5654    }
5655
5656    LayoutRect unionBounds = boundingBoxRect;
5657
5658    if (flags & UseLocalClipRectIfPossible) {
5659        bool clipExceedsBounds = false;
5660        LayoutRect localClipRect = this->localClipRect(clipExceedsBounds);
5661        if (localClipRect != LayoutRect::infiniteRect() && !clipExceedsBounds) {
5662            if ((flags & IncludeSelfTransform) && paintsWithTransform(PaintBehaviorNormal))
5663                localClipRect = transform()->mapRect(localClipRect);
5664
5665            localClipRect.move(offsetFromAncestor(ancestorLayer));
5666            return localClipRect;
5667        }
5668    }
5669
5670    // FIXME: should probably just pass 'flags' down to descendants.
5671    CalculateLayerBoundsFlags descendantFlags = DefaultCalculateLayerBoundsFlags | (flags & ExcludeHiddenDescendants) | (flags & IncludeCompositedDescendants);
5672
5673    const_cast<RenderLayer*>(this)->updateLayerListsIfNeeded();
5674
5675    if (RenderLayer* reflection = reflectionLayer()) {
5676        if (!reflection->isComposited()) {
5677            LayoutRect childUnionBounds = reflection->calculateLayerBounds(this, reflection->offsetFromAncestor(this), descendantFlags);
5678            unionBounds.unite(childUnionBounds);
5679        }
5680    }
5681
5682    ASSERT(isStackingContainer() || (!posZOrderList() || !posZOrderList()->size()));
5683
5684#if !ASSERT_DISABLED
5685    LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(this));
5686#endif
5687
5688    if (Vector<RenderLayer*>* negZOrderList = this->negZOrderList()) {
5689        size_t listSize = negZOrderList->size();
5690        for (size_t i = 0; i < listSize; ++i) {
5691            RenderLayer* curLayer = negZOrderList->at(i);
5692            if (flags & IncludeCompositedDescendants || !curLayer->isComposited()) {
5693                LayoutRect childUnionBounds = curLayer->calculateLayerBounds(this, curLayer->offsetFromAncestor(this), descendantFlags);
5694                unionBounds.unite(childUnionBounds);
5695            }
5696        }
5697    }
5698
5699    if (Vector<RenderLayer*>* posZOrderList = this->posZOrderList()) {
5700        size_t listSize = posZOrderList->size();
5701        for (size_t i = 0; i < listSize; ++i) {
5702            RenderLayer* curLayer = posZOrderList->at(i);
5703            // The RenderNamedFlowThread is ignored when we calculate the bounds of the RenderView.
5704            if ((flags & IncludeCompositedDescendants || !curLayer->isComposited()) && !curLayer->isFlowThreadCollectingGraphicsLayersUnderRegions()) {
5705                LayoutRect childUnionBounds = curLayer->calculateLayerBounds(this, curLayer->offsetFromAncestor(this), descendantFlags);
5706                unionBounds.unite(childUnionBounds);
5707            }
5708        }
5709    }
5710
5711    if (Vector<RenderLayer*>* normalFlowList = this->normalFlowList()) {
5712        size_t listSize = normalFlowList->size();
5713        for (size_t i = 0; i < listSize; ++i) {
5714            RenderLayer* curLayer = normalFlowList->at(i);
5715            // RenderView will always return the size of the document, before reaching this point,
5716            // so there's no way we could hit a RenderNamedFlowThread here.
5717            ASSERT(!curLayer->isFlowThreadCollectingGraphicsLayersUnderRegions());
5718            if (flags & IncludeCompositedDescendants || !curLayer->isComposited()) {
5719                LayoutRect curAbsBounds = curLayer->calculateLayerBounds(this, curLayer->offsetFromAncestor(this), descendantFlags);
5720                unionBounds.unite(curAbsBounds);
5721            }
5722        }
5723    }
5724
5725#if ENABLE(CSS_FILTERS)
5726    // FIXME: We can optimize the size of the composited layers, by not enlarging
5727    // filtered areas with the outsets if we know that the filter is going to render in hardware.
5728    // https://bugs.webkit.org/show_bug.cgi?id=81239
5729    if (flags & IncludeLayerFilterOutsets)
5730        renderer().style().filterOutsets().expandRect(unionBounds);
5731#endif
5732
5733    if ((flags & IncludeSelfTransform) && paintsWithTransform(PaintBehaviorNormal)) {
5734        TransformationMatrix* affineTrans = transform();
5735        boundingBoxRect = affineTrans->mapRect(boundingBoxRect);
5736        unionBounds = affineTrans->mapRect(unionBounds);
5737    }
5738    unionBounds.move(offsetFromRoot);
5739    return unionBounds;
5740}
5741
5742void RenderLayer::clearClipRectsIncludingDescendants(ClipRectsType typeToClear)
5743{
5744    // FIXME: it's not clear how this layer not having clip rects guarantees that no descendants have any.
5745    if (!m_clipRectsCache)
5746        return;
5747
5748    clearClipRects(typeToClear);
5749
5750    for (RenderLayer* l = firstChild(); l; l = l->nextSibling())
5751        l->clearClipRectsIncludingDescendants(typeToClear);
5752}
5753
5754void RenderLayer::clearClipRects(ClipRectsType typeToClear)
5755{
5756    if (typeToClear == AllClipRectTypes)
5757        m_clipRectsCache = nullptr;
5758    else {
5759        ASSERT(typeToClear < NumCachedClipRectsTypes);
5760        RefPtr<ClipRects> dummy;
5761        m_clipRectsCache->setClipRects(typeToClear, RespectOverflowClip, dummy);
5762        m_clipRectsCache->setClipRects(typeToClear, IgnoreOverflowClip, dummy);
5763    }
5764}
5765
5766RenderLayerBacking* RenderLayer::ensureBacking()
5767{
5768    if (!m_backing) {
5769        m_backing = std::make_unique<RenderLayerBacking>(*this);
5770        compositor().layerBecameComposited(*this);
5771
5772#if ENABLE(CSS_FILTERS)
5773        updateOrRemoveFilterEffectRenderer();
5774#endif
5775    }
5776    return m_backing.get();
5777}
5778
5779void RenderLayer::clearBacking(bool layerBeingDestroyed)
5780{
5781    if (m_backing && !renderer().documentBeingDestroyed())
5782        compositor().layerBecameNonComposited(*this);
5783    m_backing = nullptr;
5784
5785#if ENABLE(CSS_FILTERS)
5786    if (!layerBeingDestroyed)
5787        updateOrRemoveFilterEffectRenderer();
5788#else
5789    UNUSED_PARAM(layerBeingDestroyed);
5790#endif
5791}
5792
5793bool RenderLayer::hasCompositedMask() const
5794{
5795    return m_backing && m_backing->hasMaskLayer();
5796}
5797
5798GraphicsLayer* RenderLayer::layerForScrolling() const
5799{
5800    return m_backing ? m_backing->scrollingContentsLayer() : 0;
5801}
5802
5803GraphicsLayer* RenderLayer::layerForHorizontalScrollbar() const
5804{
5805    return m_backing ? m_backing->layerForHorizontalScrollbar() : 0;
5806}
5807
5808GraphicsLayer* RenderLayer::layerForVerticalScrollbar() const
5809{
5810    return m_backing ? m_backing->layerForVerticalScrollbar() : 0;
5811}
5812
5813GraphicsLayer* RenderLayer::layerForScrollCorner() const
5814{
5815    return m_backing ? m_backing->layerForScrollCorner() : 0;
5816}
5817
5818bool RenderLayer::paintsWithTransform(PaintBehavior paintBehavior) const
5819{
5820    bool paintsToWindow = !isComposited() || backing()->paintsIntoWindow();
5821    return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || paintsToWindow);
5822}
5823
5824bool RenderLayer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
5825{
5826    if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
5827        return false;
5828
5829    if (paintsWithTransparency(PaintBehaviorNormal))
5830        return false;
5831
5832    // We can't use hasVisibleContent(), because that will be true if our renderer is hidden, but some child
5833    // is visible and that child doesn't cover the entire rect.
5834    if (renderer().style().visibility() != VISIBLE)
5835        return false;
5836
5837#if ENABLE(CSS_FILTERS)
5838    if (paintsWithFilters() && renderer().style().filter().hasFilterThatAffectsOpacity())
5839        return false;
5840#endif
5841
5842    // FIXME: Handle simple transforms.
5843    if (paintsWithTransform(PaintBehaviorNormal))
5844        return false;
5845
5846    // FIXME: Remove this check.
5847    // This function should not be called when layer-lists are dirty.
5848    // It is somehow getting triggered during style update.
5849    if (m_zOrderListsDirty || m_normalFlowListDirty)
5850        return false;
5851
5852    // FIXME: We currently only check the immediate renderer,
5853    // which will miss many cases.
5854    if (renderer().backgroundIsKnownToBeOpaqueInRect(localRect))
5855        return true;
5856
5857    // We can't consult child layers if we clip, since they might cover
5858    // parts of the rect that are clipped out.
5859    if (renderer().hasOverflowClip())
5860        return false;
5861
5862    return listBackgroundIsKnownToBeOpaqueInRect(posZOrderList(), localRect)
5863        || listBackgroundIsKnownToBeOpaqueInRect(negZOrderList(), localRect)
5864        || listBackgroundIsKnownToBeOpaqueInRect(normalFlowList(), localRect);
5865}
5866
5867bool RenderLayer::listBackgroundIsKnownToBeOpaqueInRect(const Vector<RenderLayer*>* list, const LayoutRect& localRect) const
5868{
5869    if (!list || list->isEmpty())
5870        return false;
5871
5872    for (Vector<RenderLayer*>::const_reverse_iterator iter = list->rbegin(); iter != list->rend(); ++iter) {
5873        const RenderLayer* childLayer = *iter;
5874        if (childLayer->isComposited())
5875            continue;
5876
5877        if (!childLayer->canUseConvertToLayerCoords())
5878            continue;
5879
5880        LayoutRect childLocalRect(localRect);
5881        childLocalRect.move(-childLayer->offsetFromAncestor(this));
5882
5883        if (childLayer->backgroundIsKnownToBeOpaqueInRect(childLocalRect))
5884            return true;
5885    }
5886    return false;
5887}
5888
5889void RenderLayer::setParent(RenderLayer* parent)
5890{
5891    if (parent == m_parent)
5892        return;
5893
5894    if (m_parent && !renderer().documentBeingDestroyed())
5895        compositor().layerWillBeRemoved(*m_parent, *this);
5896
5897    m_parent = parent;
5898
5899    if (m_parent && !renderer().documentBeingDestroyed())
5900        compositor().layerWasAdded(*m_parent, *this);
5901}
5902
5903void RenderLayer::dirtyZOrderLists()
5904{
5905    ASSERT(m_layerListMutationAllowed);
5906    ASSERT(isStackingContainer());
5907
5908    if (m_posZOrderList)
5909        m_posZOrderList->clear();
5910    if (m_negZOrderList)
5911        m_negZOrderList->clear();
5912    m_zOrderListsDirty = true;
5913
5914    if (!renderer().documentBeingDestroyed()) {
5915        if (isFlowThreadCollectingGraphicsLayersUnderRegions())
5916            toRenderFlowThread(renderer()).setNeedsLayerToRegionMappingsUpdate();
5917        compositor().setCompositingLayersNeedRebuild();
5918        if (acceleratedCompositingForOverflowScrollEnabled())
5919            compositor().setShouldReevaluateCompositingAfterLayout();
5920    }
5921}
5922
5923void RenderLayer::dirtyStackingContainerZOrderLists()
5924{
5925    RenderLayer* sc = stackingContainer();
5926    if (sc)
5927        sc->dirtyZOrderLists();
5928}
5929
5930void RenderLayer::dirtyNormalFlowList()
5931{
5932    ASSERT(m_layerListMutationAllowed);
5933
5934    if (m_normalFlowList)
5935        m_normalFlowList->clear();
5936    m_normalFlowListDirty = true;
5937
5938    if (!renderer().documentBeingDestroyed()) {
5939        if (isFlowThreadCollectingGraphicsLayersUnderRegions())
5940            toRenderFlowThread(renderer()).setNeedsLayerToRegionMappingsUpdate();
5941        compositor().setCompositingLayersNeedRebuild();
5942        if (acceleratedCompositingForOverflowScrollEnabled())
5943            compositor().setShouldReevaluateCompositingAfterLayout();
5944    }
5945}
5946
5947void RenderLayer::rebuildZOrderLists()
5948{
5949    ASSERT(m_layerListMutationAllowed);
5950    ASSERT(isDirtyStackingContainer());
5951    rebuildZOrderLists(StopAtStackingContainers, m_posZOrderList, m_negZOrderList);
5952    m_zOrderListsDirty = false;
5953}
5954
5955void RenderLayer::rebuildZOrderLists(CollectLayersBehavior behavior, std::unique_ptr<Vector<RenderLayer*>>& posZOrderList, std::unique_ptr<Vector<RenderLayer*>>& negZOrderList)
5956{
5957    bool includeHiddenLayers = compositor().inCompositingMode();
5958    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
5959        if (!m_reflection || reflectionLayer() != child)
5960            child->collectLayers(includeHiddenLayers, behavior, posZOrderList, negZOrderList);
5961
5962    // Sort the two lists.
5963    if (posZOrderList)
5964        std::stable_sort(posZOrderList->begin(), posZOrderList->end(), compareZIndex);
5965
5966    if (negZOrderList)
5967        std::stable_sort(negZOrderList->begin(), negZOrderList->end(), compareZIndex);
5968}
5969
5970void RenderLayer::updateNormalFlowList()
5971{
5972    if (!m_normalFlowListDirty)
5973        return;
5974
5975    ASSERT(m_layerListMutationAllowed);
5976
5977    for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
5978        // Ignore non-overflow layers and reflections.
5979        if (child->isNormalFlowOnly() && (!m_reflection || reflectionLayer() != child)) {
5980            if (!m_normalFlowList)
5981                m_normalFlowList = std::make_unique<Vector<RenderLayer*>>();
5982            m_normalFlowList->append(child);
5983        }
5984    }
5985
5986    m_normalFlowListDirty = false;
5987}
5988
5989void RenderLayer::collectLayers(bool includeHiddenLayers, CollectLayersBehavior behavior, std::unique_ptr<Vector<RenderLayer*>>& posBuffer, std::unique_ptr<Vector<RenderLayer*>>& negBuffer)
5990{
5991    updateDescendantDependentFlags();
5992
5993    bool isStacking = behavior == StopAtStackingContexts ? isStackingContext() : isStackingContainer();
5994    // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists.
5995    bool includeHiddenLayer = includeHiddenLayers || (m_hasVisibleContent || (m_hasVisibleDescendant && isStacking));
5996    if (includeHiddenLayer && !isNormalFlowOnly()) {
5997        // Determine which buffer the child should be in.
5998        std::unique_ptr<Vector<RenderLayer*>>& buffer = (zIndex() >= 0) ? posBuffer : negBuffer;
5999
6000        // Create the buffer if it doesn't exist yet.
6001        if (!buffer)
6002            buffer = std::make_unique<Vector<RenderLayer*>>();
6003
6004        // Append ourselves at the end of the appropriate buffer.
6005        buffer->append(this);
6006    }
6007
6008    // Recur into our children to collect more layers, but only if we don't establish
6009    // a stacking context/container.
6010    if ((includeHiddenLayers || m_hasVisibleDescendant) && !isStacking) {
6011        for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
6012            // Ignore reflections.
6013            if (!m_reflection || reflectionLayer() != child)
6014                child->collectLayers(includeHiddenLayers, behavior, posBuffer, negBuffer);
6015        }
6016    }
6017}
6018
6019void RenderLayer::updateLayerListsIfNeeded()
6020{
6021    bool shouldUpdateDescendantsAreContiguousInStackingOrder = isStackingContext() && (m_zOrderListsDirty || m_normalFlowListDirty);
6022    updateZOrderLists();
6023    updateNormalFlowList();
6024
6025    if (RenderLayer* reflectionLayer = this->reflectionLayer()) {
6026        reflectionLayer->updateZOrderLists();
6027        reflectionLayer->updateNormalFlowList();
6028    }
6029
6030    if (shouldUpdateDescendantsAreContiguousInStackingOrder) {
6031        updateDescendantsAreContiguousInStackingOrder();
6032        // The above function can cause us to update m_needsCompositedScrolling
6033        // and dirty our layer lists. Refresh them if necessary.
6034        updateZOrderLists();
6035        updateNormalFlowList();
6036    }
6037}
6038
6039void RenderLayer::updateDescendantsLayerListsIfNeeded(bool recursive)
6040{
6041    Vector<RenderLayer*> layersToUpdate;
6042
6043    if (isStackingContainer()) {
6044        if (Vector<RenderLayer*>* list = negZOrderList()) {
6045            size_t listSize = list->size();
6046            for (size_t i = 0; i < listSize; ++i) {
6047                RenderLayer* childLayer = list->at(i);
6048                layersToUpdate.append(childLayer);
6049            }
6050        }
6051    }
6052
6053    if (Vector<RenderLayer*>* list = normalFlowList()) {
6054        size_t listSize = list->size();
6055        for (size_t i = 0; i < listSize; ++i) {
6056            RenderLayer* childLayer = list->at(i);
6057            layersToUpdate.append(childLayer);
6058        }
6059    }
6060
6061    if (isStackingContainer()) {
6062        if (Vector<RenderLayer*>* list = posZOrderList()) {
6063            size_t listSize = list->size();
6064            for (size_t i = 0; i < listSize; ++i) {
6065                RenderLayer* childLayer = list->at(i);
6066                layersToUpdate.append(childLayer);
6067            }
6068        }
6069    }
6070
6071    size_t listSize = layersToUpdate.size();
6072    for (size_t i = 0; i < listSize; ++i) {
6073        RenderLayer* childLayer = layersToUpdate.at(i);
6074        childLayer->updateLayerListsIfNeeded();
6075
6076        if (recursive)
6077            childLayer->updateDescendantsLayerListsIfNeeded(true);
6078    }
6079}
6080
6081void RenderLayer::updateCompositingAndLayerListsIfNeeded()
6082{
6083    if (compositor().inCompositingMode()) {
6084        if (isDirtyStackingContainer() || m_normalFlowListDirty)
6085            compositor().updateCompositingLayers(CompositingUpdateOnHitTest, this);
6086        return;
6087    }
6088
6089    updateLayerListsIfNeeded();
6090}
6091
6092void RenderLayer::repaintIncludingDescendants()
6093{
6094    renderer().repaint();
6095    for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling())
6096        curr->repaintIncludingDescendants();
6097
6098    // If this is a region, we must also repaint the flow thread's layer since it is the one
6099    // doing the actual painting of the flowed content, but only if the region is valid.
6100    if (renderer().isRenderNamedFlowFragmentContainer()) {
6101        RenderNamedFlowFragment* region = toRenderBlockFlow(renderer()).renderNamedFlowFragment();
6102        if (region->isValid())
6103            region->flowThread()->layer()->repaintIncludingDescendants();
6104    }
6105}
6106
6107void RenderLayer::setBackingNeedsRepaint(GraphicsLayer::ShouldClipToLayer shouldClip)
6108{
6109    ASSERT(isComposited());
6110    if (backing()->paintsIntoWindow()) {
6111        // If we're trying to repaint the placeholder document layer, propagate the
6112        // repaint to the native view system.
6113        renderer().view().repaintViewRectangle(absoluteBoundingBox());
6114    } else
6115        backing()->setContentsNeedDisplay(shouldClip);
6116}
6117
6118void RenderLayer::setBackingNeedsRepaintInRect(const LayoutRect& r, GraphicsLayer::ShouldClipToLayer shouldClip)
6119{
6120    // https://bugs.webkit.org/show_bug.cgi?id=61159 describes an unreproducible crash here,
6121    // so assert but check that the layer is composited.
6122    ASSERT(isComposited());
6123    if (!isComposited() || backing()->paintsIntoWindow()) {
6124        // If we're trying to repaint the placeholder document layer, propagate the
6125        // repaint to the native view system.
6126        LayoutRect absRect(r);
6127        absRect.move(offsetFromAncestor(root()));
6128
6129        renderer().view().repaintViewRectangle(absRect);
6130    } else
6131        backing()->setContentsNeedDisplayInRect(r, shouldClip);
6132}
6133
6134// Since we're only painting non-composited layers, we know that they all share the same repaintContainer.
6135void RenderLayer::repaintIncludingNonCompositingDescendants(RenderLayerModelObject* repaintContainer)
6136{
6137    renderer().repaintUsingContainer(repaintContainer, renderer().clippedOverflowRectForRepaint(repaintContainer));
6138
6139    for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling()) {
6140        if (!curr->isComposited())
6141            curr->repaintIncludingNonCompositingDescendants(repaintContainer);
6142    }
6143}
6144
6145bool RenderLayer::shouldBeNormalFlowOnly() const
6146{
6147    return (renderer().hasOverflowClip()
6148        || renderer().hasReflection()
6149        || renderer().hasMask()
6150        || renderer().isCanvas()
6151        || renderer().isVideo()
6152        || renderer().isEmbeddedObject()
6153        || renderer().isRenderIFrame()
6154        || (renderer().style().specifiesColumns() && !isRootLayer())
6155        || renderer().isInFlowRenderFlowThread())
6156        && !renderer().isPositioned()
6157        && !renderer().hasTransform()
6158        && !renderer().hasClipPath()
6159#if ENABLE(CSS_FILTERS)
6160        && !renderer().hasFilter()
6161#endif
6162#if PLATFORM(IOS)
6163        && !hasAcceleratedTouchScrolling()
6164#endif
6165#if ENABLE(CSS_COMPOSITING)
6166        && !renderer().hasBlendMode()
6167#endif
6168        && !isTransparent()
6169        && !needsCompositedScrolling()
6170        && !renderer().style().hasFlowFrom();
6171}
6172
6173bool RenderLayer::shouldBeSelfPaintingLayer() const
6174{
6175    return !isNormalFlowOnly()
6176        || hasOverlayScrollbars()
6177        || needsCompositedScrolling()
6178        || isolatesBlending()
6179        || renderer().hasReflection()
6180        || renderer().hasMask()
6181        || renderer().isTableRow()
6182        || renderer().isCanvas()
6183        || renderer().isVideo()
6184        || renderer().isEmbeddedObject()
6185        || renderer().isRenderIFrame()
6186        || renderer().isInFlowRenderFlowThread();
6187}
6188
6189void RenderLayer::updateSelfPaintingLayer()
6190{
6191    bool isSelfPaintingLayer = shouldBeSelfPaintingLayer();
6192    if (m_isSelfPaintingLayer == isSelfPaintingLayer)
6193        return;
6194
6195    m_isSelfPaintingLayer = isSelfPaintingLayer;
6196    if (!parent())
6197        return;
6198    if (isSelfPaintingLayer)
6199        parent()->setAncestorChainHasSelfPaintingLayerDescendant();
6200    else
6201        parent()->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
6202}
6203
6204bool RenderLayer::hasNonEmptyChildRenderers() const
6205{
6206    // Some HTML can cause whitespace text nodes to have renderers, like:
6207    // <div>
6208    // <img src=...>
6209    // </div>
6210    // so test for 0x0 RenderTexts here
6211    for (RenderObject* child = renderer().firstChild(); child; child = child->nextSibling()) {
6212        if (!child->hasLayer()) {
6213            if (child->isRenderInline() || !child->isBox())
6214                return true;
6215
6216            if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0)
6217                return true;
6218        }
6219    }
6220    return false;
6221}
6222
6223static bool hasBoxDecorations(const RenderStyle& style)
6224{
6225    return style.hasBorder() || style.hasBorderRadius() || style.hasOutline() || style.hasAppearance() || style.boxShadow() || style.hasFilter();
6226}
6227
6228bool RenderLayer::hasBoxDecorationsOrBackground() const
6229{
6230    return hasBoxDecorations(renderer().style()) || renderer().hasBackground();
6231}
6232
6233bool RenderLayer::hasVisibleBoxDecorations() const
6234{
6235    if (!hasVisibleContent())
6236        return false;
6237
6238    return hasBoxDecorationsOrBackground() || hasOverflowControls();
6239}
6240
6241bool RenderLayer::isVisuallyNonEmpty() const
6242{
6243    ASSERT(!m_visibleDescendantStatusDirty);
6244
6245    if (hasVisibleContent() && hasNonEmptyChildRenderers())
6246        return true;
6247
6248    if (renderer().isReplaced() || renderer().hasMask())
6249        return true;
6250
6251    if (hasVisibleBoxDecorations())
6252        return true;
6253
6254    return false;
6255}
6256
6257void RenderLayer::updateStackingContextsAfterStyleChange(const RenderStyle* oldStyle)
6258{
6259    if (!oldStyle)
6260        return;
6261
6262    bool wasStackingContext = isStackingContext(oldStyle);
6263    bool isStackingContext = this->isStackingContext();
6264    if (isStackingContext != wasStackingContext) {
6265        dirtyStackingContainerZOrderLists();
6266        if (isStackingContext)
6267            dirtyZOrderLists();
6268        else
6269            clearZOrderLists();
6270
6271#if ENABLE(CSS_COMPOSITING)
6272        if (parent()) {
6273            if (isStackingContext) {
6274                if (!hasNotIsolatedBlendingDescendantsStatusDirty() && hasNotIsolatedBlendingDescendants())
6275                    parent()->dirtyAncestorChainHasBlendingDescendants();
6276            } else {
6277                if (hasNotIsolatedBlendingDescendantsStatusDirty())
6278                    parent()->dirtyAncestorChainHasBlendingDescendants();
6279                else if (hasNotIsolatedBlendingDescendants())
6280                    parent()->updateAncestorChainHasBlendingDescendants();
6281            }
6282        }
6283#endif
6284
6285        return;
6286    }
6287
6288    // FIXME: RenderLayer already handles visibility changes through our visiblity dirty bits. This logic could
6289    // likely be folded along with the rest.
6290    if (oldStyle->zIndex() != renderer().style().zIndex() || oldStyle->visibility() != renderer().style().visibility()) {
6291        dirtyStackingContainerZOrderLists();
6292        if (isStackingContext)
6293            dirtyZOrderLists();
6294    }
6295}
6296
6297static bool overflowRequiresScrollbar(EOverflow overflow)
6298{
6299    return overflow == OSCROLL;
6300}
6301
6302static bool overflowDefinesAutomaticScrollbar(EOverflow overflow)
6303{
6304    return overflow == OAUTO || overflow == OOVERLAY;
6305}
6306
6307void RenderLayer::updateScrollbarsAfterStyleChange(const RenderStyle* oldStyle)
6308{
6309    // Overflow are a box concept.
6310    RenderBox* box = renderBox();
6311    if (!box)
6312        return;
6313
6314    // List box parts handle the scrollbars by themselves so we have nothing to do.
6315    if (box->style().appearance() == ListboxPart)
6316        return;
6317
6318    EOverflow overflowX = box->style().overflowX();
6319    EOverflow overflowY = box->style().overflowY();
6320
6321    // To avoid doing a relayout in updateScrollbarsAfterLayout, we try to keep any automatic scrollbar that was already present.
6322    bool needsHorizontalScrollbar = (hasHorizontalScrollbar() && overflowDefinesAutomaticScrollbar(overflowX)) || overflowRequiresScrollbar(overflowX);
6323    bool needsVerticalScrollbar = (hasVerticalScrollbar() && overflowDefinesAutomaticScrollbar(overflowY)) || overflowRequiresScrollbar(overflowY);
6324    setHasHorizontalScrollbar(needsHorizontalScrollbar);
6325    setHasVerticalScrollbar(needsVerticalScrollbar);
6326
6327    // With overflow: scroll, scrollbars are always visible but may be disabled.
6328    // When switching to another value, we need to re-enable them (see bug 11985).
6329    if (needsHorizontalScrollbar && oldStyle && oldStyle->overflowX() == OSCROLL && overflowX != OSCROLL) {
6330        ASSERT(hasHorizontalScrollbar());
6331        m_hBar->setEnabled(true);
6332    }
6333
6334    if (needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == OSCROLL && overflowY != OSCROLL) {
6335        ASSERT(hasVerticalScrollbar());
6336        m_vBar->setEnabled(true);
6337    }
6338
6339    if (!m_scrollDimensionsDirty)
6340        updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
6341}
6342
6343void RenderLayer::setAncestorChainHasOutOfFlowPositionedDescendant(RenderBlock* containingBlock)
6344{
6345    for (RenderLayer* layer = this; layer; layer = layer->parent()) {
6346        if (!layer->m_hasOutOfFlowPositionedDescendantDirty && layer->hasOutOfFlowPositionedDescendant())
6347            break;
6348
6349        layer->m_hasOutOfFlowPositionedDescendantDirty = false;
6350        layer->m_hasOutOfFlowPositionedDescendant = true;
6351        layer->updateNeedsCompositedScrolling();
6352
6353        if (&layer->renderer() == containingBlock)
6354            break;
6355    }
6356}
6357
6358void RenderLayer::dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus()
6359{
6360    m_hasOutOfFlowPositionedDescendantDirty = true;
6361    if (parent())
6362        parent()->dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
6363}
6364
6365void RenderLayer::updateOutOfFlowPositioned(const RenderStyle* oldStyle)
6366{
6367    bool wasOutOfFlowPositioned = oldStyle && (oldStyle->position() == AbsolutePosition || oldStyle->position() == FixedPosition);
6368    if (parent() && (renderer().isOutOfFlowPositioned() != wasOutOfFlowPositioned)) {
6369        parent()->dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
6370        if (!renderer().documentBeingDestroyed() && acceleratedCompositingForOverflowScrollEnabled())
6371            compositor().setShouldReevaluateCompositingAfterLayout();
6372    }
6373}
6374
6375inline bool RenderLayer::needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
6376{
6377    ASSERT(newStyle);
6378    return oldStyle && (oldStyle->clip() != newStyle->clip() || oldStyle->hasClip() != newStyle->hasClip());
6379}
6380
6381inline bool RenderLayer::needsCompositingLayersRebuiltForOverflow(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
6382{
6383    ASSERT(newStyle);
6384    return !isComposited() && oldStyle && (oldStyle->overflowX() != newStyle->overflowX()) && stackingContainer()->hasCompositingDescendant();
6385}
6386
6387void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle)
6388{
6389    bool isNormalFlowOnly = shouldBeNormalFlowOnly();
6390    if (isNormalFlowOnly != m_isNormalFlowOnly) {
6391        m_isNormalFlowOnly = isNormalFlowOnly;
6392        RenderLayer* p = parent();
6393        if (p)
6394            p->dirtyNormalFlowList();
6395        dirtyStackingContainerZOrderLists();
6396    }
6397
6398    if (renderer().style().overflowX() == OMARQUEE && renderer().style().marqueeBehavior() != MNONE && renderer().isBox()) {
6399        if (!m_marquee)
6400            m_marquee = std::make_unique<RenderMarquee>(this);
6401        m_marquee->updateMarqueeStyle();
6402    }
6403    else if (m_marquee) {
6404        m_marquee = nullptr;
6405    }
6406
6407    updateScrollbarsAfterStyleChange(oldStyle);
6408    updateStackingContextsAfterStyleChange(oldStyle);
6409    // Overlay scrollbars can make this layer self-painting so we need
6410    // to recompute the bit once scrollbars have been updated.
6411    updateSelfPaintingLayer();
6412    updateOutOfFlowPositioned(oldStyle);
6413
6414    if (!hasReflection() && m_reflection)
6415        removeReflection();
6416    else if (hasReflection()) {
6417        if (!m_reflection)
6418            createReflection();
6419        else
6420            m_reflection->setStyle(createReflectionStyle());
6421    }
6422
6423    // FIXME: Need to detect a swap from custom to native scrollbars (and vice versa).
6424    if (m_hBar)
6425        m_hBar->styleChanged();
6426    if (m_vBar)
6427        m_vBar->styleChanged();
6428
6429    updateScrollCornerStyle();
6430    updateResizerStyle();
6431
6432    updateDescendantDependentFlags();
6433    updateTransform();
6434#if ENABLE(CSS_COMPOSITING)
6435    updateBlendMode();
6436#endif
6437#if ENABLE(CSS_FILTERS)
6438    updateOrRemoveFilterClients();
6439#endif
6440
6441    updateNeedsCompositedScrolling();
6442
6443    const RenderStyle& newStyle = renderer().style();
6444    if (compositor().updateLayerCompositingState(*this)
6445        || needsCompositingLayersRebuiltForClip(oldStyle, &newStyle)
6446        || needsCompositingLayersRebuiltForOverflow(oldStyle, &newStyle))
6447        compositor().setCompositingLayersNeedRebuild();
6448    else if (isComposited()) {
6449        // FIXME: updating geometry here is potentially harmful, because layout is not up-to-date.
6450        backing()->updateGeometry();
6451        backing()->updateAfterDescendents();
6452    }
6453
6454    if (oldStyle) {
6455        // Compositing layers keep track of whether they are clipped by any of the ancestors.
6456        // When the current layer's clipping behaviour changes, we need to propagate it to the descendants.
6457        const RenderStyle& style = renderer().style();
6458        bool wasClipping = oldStyle->hasClip() || oldStyle->overflowX() != OVISIBLE || oldStyle->overflowY() != OVISIBLE;
6459        bool isClipping = style.hasClip() || style.overflowX() != OVISIBLE || style.overflowY() != OVISIBLE;
6460        if (isClipping != wasClipping) {
6461            if (checkIfDescendantClippingContextNeedsUpdate(isClipping))
6462                compositor().setCompositingLayersNeedRebuild();
6463        }
6464    }
6465
6466#if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS)
6467    if (diff == StyleDifferenceRecompositeLayer || diff >= StyleDifferenceLayoutPositionedMovementOnly)
6468        renderer().document().dirtyTouchEventRects();
6469#else
6470    UNUSED_PARAM(diff);
6471#endif
6472
6473#if ENABLE(CSS_FILTERS)
6474    updateOrRemoveFilterEffectRenderer();
6475    bool backingDidCompositeLayers = isComposited() && backing()->canCompositeFilters();
6476    if (isComposited() && backingDidCompositeLayers && !backing()->canCompositeFilters()) {
6477        // The filters used to be drawn by platform code, but now the platform cannot draw them anymore.
6478        // Fallback to drawing them in software.
6479        setBackingNeedsRepaint();
6480    }
6481#endif
6482}
6483
6484void RenderLayer::updateScrollableAreaSet(bool hasOverflow)
6485{
6486    FrameView& frameView = renderer().view().frameView();
6487
6488    bool isVisibleToHitTest = renderer().visibleToHitTesting();
6489    if (HTMLFrameOwnerElement* owner = frameView.frame().ownerElement())
6490        isVisibleToHitTest &= owner->renderer() && owner->renderer()->visibleToHitTesting();
6491
6492    bool isScrollable = hasOverflow && isVisibleToHitTest;
6493    bool addedOrRemoved = false;
6494    if (isScrollable)
6495        addedOrRemoved = frameView.addScrollableArea(this);
6496    else
6497        addedOrRemoved = frameView.removeScrollableArea(this);
6498
6499    if (addedOrRemoved)
6500        updateNeedsCompositedScrolling();
6501
6502#if PLATFORM(IOS)
6503    if (addedOrRemoved) {
6504        if (isScrollable && !hasAcceleratedTouchScrolling())
6505            registerAsTouchEventListenerForScrolling();
6506        else {
6507            // We only need the touch listener for unaccelerated overflow scrolling, so if we became
6508            // accelerated, remove ourselves as a touch event listener.
6509            unregisterAsTouchEventListenerForScrolling();
6510        }
6511    }
6512#endif
6513}
6514
6515void RenderLayer::updateScrollCornerStyle()
6516{
6517    RenderElement* actualRenderer = rendererForScrollbar(renderer());
6518    RefPtr<RenderStyle> corner = renderer().hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), &actualRenderer->style()) : PassRefPtr<RenderStyle>(0);
6519
6520    if (!corner) {
6521        m_scrollCorner = nullptr;
6522        return;
6523    }
6524
6525    if (!m_scrollCorner) {
6526        m_scrollCorner = createRenderer<RenderScrollbarPart>(renderer().document(), corner.releaseNonNull());
6527        m_scrollCorner->setParent(&renderer());
6528        m_scrollCorner->initializeStyle();
6529    } else
6530        m_scrollCorner->setStyle(corner.releaseNonNull());
6531}
6532
6533void RenderLayer::updateResizerStyle()
6534{
6535    RenderElement* actualRenderer = rendererForScrollbar(renderer());
6536    RefPtr<RenderStyle> resizer = renderer().hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(PseudoStyleRequest(RESIZER), &actualRenderer->style()) : PassRefPtr<RenderStyle>(0);
6537
6538    if (!resizer) {
6539        m_resizer = nullptr;
6540        return;
6541    }
6542
6543    if (!m_resizer) {
6544        m_resizer = createRenderer<RenderScrollbarPart>(renderer().document(), resizer.releaseNonNull());
6545        m_resizer->setParent(&renderer());
6546        m_resizer->initializeStyle();
6547    } else
6548        m_resizer->setStyle(resizer.releaseNonNull());
6549}
6550
6551RenderLayer* RenderLayer::reflectionLayer() const
6552{
6553    return m_reflection ? m_reflection->layer() : 0;
6554}
6555
6556void RenderLayer::createReflection()
6557{
6558    ASSERT(!m_reflection);
6559    m_reflection = createRenderer<RenderReplica>(renderer().document(), createReflectionStyle());
6560    m_reflection->setParent(&renderer()); // We create a 1-way connection.
6561    m_reflection->initializeStyle();
6562}
6563
6564void RenderLayer::removeReflection()
6565{
6566    if (!m_reflection->documentBeingDestroyed())
6567        m_reflection->removeLayers(this);
6568
6569    m_reflection->setParent(0);
6570    m_reflection = nullptr;
6571}
6572
6573PassRef<RenderStyle> RenderLayer::createReflectionStyle()
6574{
6575    auto newStyle = RenderStyle::create();
6576    newStyle.get().inheritFrom(&renderer().style());
6577
6578    // Map in our transform.
6579    TransformOperations transform;
6580    switch (renderer().style().boxReflect()->direction()) {
6581        case ReflectionBelow:
6582            transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed), Length(100., Percent), TransformOperation::TRANSLATE));
6583            transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed), renderer().style().boxReflect()->offset(), TransformOperation::TRANSLATE));
6584            transform.operations().append(ScaleTransformOperation::create(1.0, -1.0, ScaleTransformOperation::SCALE));
6585            break;
6586        case ReflectionAbove:
6587            transform.operations().append(ScaleTransformOperation::create(1.0, -1.0, ScaleTransformOperation::SCALE));
6588            transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed), Length(100., Percent), TransformOperation::TRANSLATE));
6589            transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed), renderer().style().boxReflect()->offset(), TransformOperation::TRANSLATE));
6590            break;
6591        case ReflectionRight:
6592            transform.operations().append(TranslateTransformOperation::create(Length(100., Percent), Length(0, Fixed), TransformOperation::TRANSLATE));
6593            transform.operations().append(TranslateTransformOperation::create(renderer().style().boxReflect()->offset(), Length(0, Fixed), TransformOperation::TRANSLATE));
6594            transform.operations().append(ScaleTransformOperation::create(-1.0, 1.0, ScaleTransformOperation::SCALE));
6595            break;
6596        case ReflectionLeft:
6597            transform.operations().append(ScaleTransformOperation::create(-1.0, 1.0, ScaleTransformOperation::SCALE));
6598            transform.operations().append(TranslateTransformOperation::create(Length(100., Percent), Length(0, Fixed), TransformOperation::TRANSLATE));
6599            transform.operations().append(TranslateTransformOperation::create(renderer().style().boxReflect()->offset(), Length(0, Fixed), TransformOperation::TRANSLATE));
6600            break;
6601    }
6602    newStyle.get().setTransform(transform);
6603
6604    // Map in our mask.
6605    newStyle.get().setMaskBoxImage(renderer().style().boxReflect()->mask());
6606
6607    return newStyle;
6608}
6609
6610#if ENABLE(CSS_FILTERS)
6611
6612void RenderLayer::updateOrRemoveFilterClients()
6613{
6614    if (!hasFilter()) {
6615        FilterInfo::remove(*this);
6616        return;
6617    }
6618
6619    if (renderer().style().filter().hasReferenceFilter())
6620        FilterInfo::get(*this).updateReferenceFilterClients(renderer().style().filter());
6621    else if (FilterInfo* filterInfo = FilterInfo::getIfExists(*this))
6622        filterInfo->removeReferenceFilterClients();
6623}
6624
6625void RenderLayer::updateOrRemoveFilterEffectRenderer()
6626{
6627    // FilterEffectRenderer is only used to render the filters in software mode,
6628    // so we always need to run updateOrRemoveFilterEffectRenderer after the composited
6629    // mode might have changed for this layer.
6630    if (!paintsWithFilters()) {
6631        // Don't delete the whole filter info here, because we might use it
6632        // for loading SVG reference filter files.
6633        if (FilterInfo* filterInfo = FilterInfo::getIfExists(*this))
6634            filterInfo->setRenderer(0);
6635
6636        // Early-return only if we *don't* have reference filters.
6637        // For reference filters, we still want the FilterEffect graph built
6638        // for us, even if we're composited.
6639        if (!renderer().style().filter().hasReferenceFilter())
6640            return;
6641    }
6642
6643    FilterInfo& filterInfo = FilterInfo::get(*this);
6644    if (!filterInfo.renderer()) {
6645        RefPtr<FilterEffectRenderer> filterRenderer = FilterEffectRenderer::create();
6646        filterRenderer->setFilterScale(renderer().frame().page()->deviceScaleFactor());
6647        RenderingMode renderingMode = renderer().frame().settings().acceleratedFiltersEnabled() ? Accelerated : Unaccelerated;
6648        filterRenderer->setRenderingMode(renderingMode);
6649        filterInfo.setRenderer(filterRenderer.release());
6650
6651        // We can optimize away code paths in other places if we know that there are no software filters.
6652        renderer().view().setHasSoftwareFilters(true);
6653    } else if (filterInfo.renderer()->filterScale() != renderer().frame().page()->deviceScaleFactor()) {
6654        filterInfo.renderer()->setFilterScale(renderer().frame().page()->deviceScaleFactor());
6655        filterInfo.renderer()->clearIntermediateResults();
6656    }
6657
6658    // If the filter fails to build, remove it from the layer. It will still attempt to
6659    // go through regular processing (e.g. compositing), but never apply anything.
6660    if (!filterInfo.renderer()->build(&renderer(), renderer().style().filter(), FilterProperty))
6661        filterInfo.setRenderer(0);
6662}
6663
6664void RenderLayer::filterNeedsRepaint()
6665{
6666    // We use the enclosing element so that we recalculate style for the ancestor of an anonymous object.
6667    if (Element* element = enclosingElement())
6668        element->setNeedsStyleRecalc(SyntheticStyleChange);
6669    renderer().repaint();
6670}
6671
6672#endif
6673
6674void RenderLayer::paintNamedFlowThreadInsideRegion(GraphicsContext* context, RenderNamedFlowFragment* region, LayoutRect paintDirtyRect, LayoutPoint paintOffset, PaintBehavior paintBehavior, PaintLayerFlags paintFlags)
6675{
6676    LayoutRect regionContentBox = toRenderBox(region->layerOwner()).contentBoxRect();
6677    LayoutSize moveOffset = region->flowThreadPortionLocation() - (paintOffset + regionContentBox.location()) + region->fragmentContainer().scrolledContentOffset();
6678
6679    FloatPoint adjustedPaintOffset = roundedForPainting(LayoutPoint(-moveOffset.width(), -moveOffset.height()), renderer().document().deviceScaleFactor());
6680    paintDirtyRect.move(moveOffset);
6681
6682    context->save();
6683    context->translate(adjustedPaintOffset.x(), adjustedPaintOffset.y());
6684
6685    CurrentRenderFlowThreadMaintainer flowThreadMaintainer(toRenderFlowThread(&renderer()));
6686    CurrentRenderRegionMaintainer regionMaintainer(*region);
6687
6688    region->setRegionObjectsRegionStyle();
6689    paint(context, paintDirtyRect, paintBehavior, nullptr, paintFlags | PaintLayerTemporaryClipRects);
6690    region->restoreRegionObjectsOriginalStyle();
6691
6692    context->restore();
6693}
6694
6695void RenderLayer::paintFlowThreadIfRegionForFragments(const LayerFragments& fragments, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
6696{
6697    if (!renderer().isRenderNamedFlowFragmentContainer())
6698        return;
6699
6700    RenderBlockFlow* renderNamedFlowFragmentContainer = toRenderBlockFlow(&renderer());
6701    RenderNamedFlowFragment* flowFragment = renderNamedFlowFragmentContainer->renderNamedFlowFragment();
6702    if (!flowFragment->isValid())
6703        return;
6704
6705    RenderNamedFlowThread* flowThread = flowFragment->namedFlowThread();
6706    RenderLayer* flowThreadLayer = flowThread->layer();
6707
6708    LayoutRect regionClipRect = LayoutRect::infiniteRect();
6709    if (flowFragment->shouldClipFlowThreadContent()) {
6710        regionClipRect = renderNamedFlowFragmentContainer->paddingBoxRect();
6711
6712        // When the layer of the flow fragment's container is composited, the flow fragment container receives a
6713        // GraphicsLayer of its own so the clipping coordinates (caused by overflow:hidden) must be relative to the
6714        // GraphicsLayer coordinates in which the fragment gets painted. So what is computed so far is enough.
6715        // If the layer of the flowFragment is not composited, then we change the coordinates to be relative to the flow
6716        // thread's layer.
6717        if (!isComposited())
6718            regionClipRect.move(offsetFromAncestor(paintingInfo.rootLayer));
6719    }
6720
6721    for (size_t i = 0; i < fragments.size(); ++i) {
6722        const LayerFragment& fragment = fragments.at(i);
6723
6724        ClipRect clipRect = fragment.foregroundRect;
6725        if (flowFragment->shouldClipFlowThreadContent())
6726            clipRect.intersect(regionClipRect);
6727
6728        bool shouldClip = (clipRect != LayoutRect::infiniteRect());
6729        // Optimize clipping for the single fragment case.
6730        if (shouldClip)
6731            clipToRect(paintingInfo, context, clipRect);
6732
6733        flowThreadLayer->paintNamedFlowThreadInsideRegion(context, flowFragment, paintingInfo.paintDirtyRect, fragment.layerBounds.location() + paintingInfo.subpixelAccumulation,
6734            paintingInfo.paintBehavior, paintFlags);
6735
6736        if (shouldClip)
6737            restoreClip(context, paintingInfo.paintDirtyRect, clipRect);
6738    }
6739}
6740
6741RenderLayer* RenderLayer::hitTestFlowThreadIfRegionForFragments(const LayerFragments& fragments, RenderLayer*, const HitTestRequest& request, HitTestResult& result, const LayoutRect& hitTestRect,
6742    const HitTestLocation& hitTestLocation,
6743    const HitTestingTransformState* transformState,
6744    double* zOffsetForDescendants, double* zOffset,
6745    const HitTestingTransformState* unflattenedTransformState, bool depthSortDescendants)
6746{
6747    if (!renderer().isRenderNamedFlowFragmentContainer())
6748        return 0;
6749
6750    RenderNamedFlowFragment* region = toRenderBlockFlow(&renderer())->renderNamedFlowFragment();
6751    if (!region->isValid())
6752        return 0;
6753
6754    RenderFlowThread* flowThread = region->flowThread();
6755    LayoutPoint portionLocation = region->flowThreadPortionRect().location();
6756    if (flowThread->style().isFlippedBlocksWritingMode()) {
6757        // The portion location coordinate must be translated into physical coordinates.
6758        if (flowThread->style().isHorizontalWritingMode())
6759            portionLocation.setY(flowThread->height() - (portionLocation.y() + region->contentHeight()));
6760        else
6761            portionLocation.setX(flowThread->width() - (portionLocation.x() + region->contentWidth()));
6762    }
6763
6764    LayoutRect regionContentBox = toRenderBlockFlow(&renderer())->contentBoxRect();
6765
6766    RenderLayer* resultLayer = 0;
6767    for (int i = fragments.size() - 1; i >= 0; --i) {
6768        const LayerFragment& fragment = fragments.at(i);
6769
6770        if (!fragment.backgroundRect.intersects(hitTestLocation))
6771            continue;
6772
6773        LayoutSize hitTestOffset = portionLocation - (fragment.layerBounds.location() + regionContentBox.location()) + region->fragmentContainer().scrolledContentOffset();
6774
6775        // Always ignore clipping, since the RenderFlowThread has nothing to do with the bounds of the FrameView.
6776        HitTestRequest newRequest(request.type() | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent);
6777
6778        // Make a new temporary HitTestLocation in the new region.
6779        HitTestLocation newHitTestLocation(hitTestLocation, hitTestOffset);
6780
6781        // Expand the hit-test rect to the flow thread's coordinate system.
6782        LayoutRect hitTestRectInFlowThread = hitTestRect;
6783        hitTestRectInFlowThread.move(hitTestOffset);
6784        hitTestRectInFlowThread.expand(LayoutSize(fabs((double)hitTestOffset.width()), fabs((double)hitTestOffset.height())));
6785
6786        CurrentRenderFlowThreadMaintainer flowThreadMaintainer(flowThread);
6787        CurrentRenderRegionMaintainer regionMaintainer(*region);
6788
6789        HitTestResult tempResult(result.hitTestLocation());
6790        RenderLayer* hitLayer = flowThread->layer()->hitTestLayer(flowThread->layer(), 0, newRequest, tempResult, hitTestRectInFlowThread, newHitTestLocation, false, transformState, zOffsetForDescendants);
6791        if (result.isRectBasedTest())
6792            result.append(tempResult);
6793        if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState)) {
6794            resultLayer = hitLayer;
6795            if (!result.isRectBasedTest())
6796                result = tempResult;
6797            if (!depthSortDescendants)
6798                break;
6799        }
6800    }
6801
6802    return resultLayer;
6803}
6804
6805RenderNamedFlowFragment* RenderLayer::currentRenderNamedFlowFragment() const
6806{
6807    return renderer().currentRenderNamedFlowFragment();
6808}
6809
6810} // namespace WebCore
6811
6812#ifndef NDEBUG
6813
6814void showLayerTree(const WebCore::RenderLayer* layer)
6815{
6816    if (!layer)
6817        return;
6818
6819    WTF::String output = externalRepresentation(&layer->renderer().frame(), WebCore::RenderAsTextShowAllLayers | WebCore::RenderAsTextShowLayerNesting | WebCore::RenderAsTextShowCompositedLayers | WebCore::RenderAsTextShowAddresses | WebCore::RenderAsTextShowIDAndClass | WebCore::RenderAsTextDontUpdateLayout | WebCore::RenderAsTextShowLayoutState | WebCore::RenderAsTextShowOverflow);
6820    fprintf(stderr, "%s\n", output.utf8().data());
6821}
6822
6823void showLayerTree(const WebCore::RenderObject* renderer)
6824{
6825    if (!renderer)
6826        return;
6827    showLayerTree(renderer->enclosingLayer());
6828}
6829
6830#endif
6831