1/*
2 * Copyright (C) 2003, 2009, 2012 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#ifndef RenderLayer_h
45#define RenderLayer_h
46
47#include "GraphicsLayer.h"
48#include "PaintInfo.h"
49#include "RenderBox.h"
50#include "RenderPtr.h"
51#include "ScrollableArea.h"
52#include <memory>
53
54namespace WebCore {
55
56class FilterEffectRenderer;
57class FilterEffectRendererHelper;
58class FilterOperations;
59class HitTestRequest;
60class HitTestResult;
61class HitTestingTransformState;
62class RenderFlowThread;
63class RenderGeometryMap;
64class RenderLayerBacking;
65class RenderLayerCompositor;
66class RenderMarquee;
67class RenderNamedFlowFragment;
68class RenderReplica;
69class RenderScrollbarPart;
70class RenderStyle;
71class RenderView;
72class Scrollbar;
73class TransformationMatrix;
74
75enum BorderRadiusClippingRule { IncludeSelfForBorderRadius, DoNotIncludeSelfForBorderRadius };
76enum IncludeSelfOrNot { IncludeSelf, ExcludeSelf };
77
78enum RepaintStatus {
79    NeedsNormalRepaint,
80    NeedsFullRepaint,
81    NeedsFullRepaintForPositionedMovementLayout
82};
83
84class ClipRect {
85public:
86    ClipRect()
87    : m_hasRadius(false)
88    { }
89
90    ClipRect(const LayoutRect& rect)
91    : m_rect(rect)
92    , m_hasRadius(false)
93    { }
94
95    const LayoutRect& rect() const { return m_rect; }
96    void setRect(const LayoutRect& rect) { m_rect = rect; }
97
98    bool hasRadius() const { return m_hasRadius; }
99    void setHasRadius(bool hasRadius) { m_hasRadius = hasRadius; }
100
101    bool operator==(const ClipRect& other) const { return rect() == other.rect() && hasRadius() == other.hasRadius(); }
102    bool operator!=(const ClipRect& other) const { return rect() != other.rect() || hasRadius() != other.hasRadius(); }
103    bool operator!=(const LayoutRect& otherRect) const { return rect() != otherRect; }
104
105    void intersect(const LayoutRect& other) { m_rect.intersect(other); }
106    void intersect(const ClipRect& other)
107    {
108        m_rect.intersect(other.rect());
109        if (other.hasRadius())
110            m_hasRadius = true;
111    }
112    void move(LayoutUnit x, LayoutUnit y) { m_rect.move(x, y); }
113    void move(const LayoutSize& size) { m_rect.move(size); }
114    void moveBy(const LayoutPoint& point) { m_rect.moveBy(point); }
115
116    bool isEmpty() const { return m_rect.isEmpty(); }
117    bool intersects(const LayoutRect& rect) const { return m_rect.intersects(rect); }
118    bool intersects(const HitTestLocation&) const;
119
120    void inflateX(LayoutUnit dx) { m_rect.inflateX(dx); }
121    void inflateY(LayoutUnit dy) { m_rect.inflateY(dy); }
122    void inflate(LayoutUnit d) { inflateX(d); inflateY(d); }
123
124private:
125    LayoutRect m_rect;
126    bool m_hasRadius;
127};
128
129inline ClipRect intersection(const ClipRect& a, const ClipRect& b)
130{
131    ClipRect c = a;
132    c.intersect(b);
133    return c;
134}
135
136class ClipRects {
137    WTF_MAKE_FAST_ALLOCATED;
138public:
139    static PassRefPtr<ClipRects> create()
140    {
141        return adoptRef(new ClipRects);
142    }
143
144    static PassRefPtr<ClipRects> create(const ClipRects& other)
145    {
146        return adoptRef(new ClipRects(other));
147    }
148
149    ClipRects()
150        : m_refCnt(1)
151        , m_fixed(false)
152    {
153    }
154
155    void reset(const LayoutRect& r)
156    {
157        m_overflowClipRect = r;
158        m_fixedClipRect = r;
159        m_posClipRect = r;
160        m_fixed = false;
161    }
162
163    const ClipRect& overflowClipRect() const { return m_overflowClipRect; }
164    void setOverflowClipRect(const ClipRect& r) { m_overflowClipRect = r; }
165
166    const ClipRect& fixedClipRect() const { return m_fixedClipRect; }
167    void setFixedClipRect(const ClipRect&r) { m_fixedClipRect = r; }
168
169    const ClipRect& posClipRect() const { return m_posClipRect; }
170    void setPosClipRect(const ClipRect& r) { m_posClipRect = r; }
171
172    bool fixed() const { return m_fixed; }
173    void setFixed(bool fixed) { m_fixed = fixed; }
174
175    void ref() { m_refCnt++; }
176    void deref()
177    {
178        if (!--m_refCnt)
179            delete this;
180    }
181
182    bool operator==(const ClipRects& other) const
183    {
184        return m_overflowClipRect == other.overflowClipRect() &&
185               m_fixedClipRect == other.fixedClipRect() &&
186               m_posClipRect == other.posClipRect() &&
187               m_fixed == other.fixed();
188    }
189
190    ClipRects& operator=(const ClipRects& other)
191    {
192        m_overflowClipRect = other.overflowClipRect();
193        m_fixedClipRect = other.fixedClipRect();
194        m_posClipRect = other.posClipRect();
195        m_fixed = other.fixed();
196        return *this;
197    }
198
199private:
200    ClipRects(const LayoutRect& r)
201        : m_overflowClipRect(r)
202        , m_fixedClipRect(r)
203        , m_posClipRect(r)
204        , m_refCnt(1)
205        , m_fixed(false)
206    {
207    }
208
209    ClipRects(const ClipRects& other)
210        : m_overflowClipRect(other.overflowClipRect())
211        , m_fixedClipRect(other.fixedClipRect())
212        , m_posClipRect(other.posClipRect())
213        , m_refCnt(1)
214        , m_fixed(other.fixed())
215    {
216    }
217
218    ClipRect m_overflowClipRect;
219    ClipRect m_fixedClipRect;
220    ClipRect m_posClipRect;
221    unsigned m_refCnt : 31;
222    bool m_fixed : 1;
223};
224
225enum ClipRectsType {
226    PaintingClipRects, // Relative to painting ancestor. Used for painting.
227    RootRelativeClipRects, // Relative to the ancestor treated as the root (e.g. transformed layer). Used for hit testing.
228    AbsoluteClipRects, // Relative to the RenderView's layer. Used for compositing overlap testing.
229    NumCachedClipRectsTypes,
230    AllClipRectTypes,
231    TemporaryClipRects
232};
233
234enum ShouldRespectOverflowClip {
235    IgnoreOverflowClip,
236    RespectOverflowClip
237};
238
239enum ShouldApplyRootOffsetToFragments {
240    ApplyRootOffsetToFragments,
241    IgnoreRootOffsetForFragments
242};
243
244struct ClipRectsCache {
245    WTF_MAKE_FAST_ALLOCATED;
246public:
247    ClipRectsCache()
248    {
249#ifndef NDEBUG
250        for (int i = 0; i < NumCachedClipRectsTypes; ++i) {
251            m_clipRectsRoot[i] = 0;
252            m_scrollbarRelevancy[i] = IgnoreOverlayScrollbarSize;
253        }
254#endif
255    }
256
257    PassRefPtr<ClipRects> getClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow) { return m_clipRects[getIndex(clipRectsType, respectOverflow)]; }
258    void setClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow, PassRefPtr<ClipRects> clipRects) { m_clipRects[getIndex(clipRectsType, respectOverflow)] = clipRects; }
259
260#ifndef NDEBUG
261    const RenderLayer* m_clipRectsRoot[NumCachedClipRectsTypes];
262    OverlayScrollbarSizeRelevancy m_scrollbarRelevancy[NumCachedClipRectsTypes];
263#endif
264
265private:
266    int getIndex(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow)
267    {
268        int index = static_cast<int>(clipRectsType);
269        if (respectOverflow == RespectOverflowClip)
270            index += static_cast<int>(NumCachedClipRectsTypes);
271        return index;
272    }
273
274    RefPtr<ClipRects> m_clipRects[NumCachedClipRectsTypes * 2];
275};
276
277struct LayerFragment {
278public:
279    LayerFragment()
280        : shouldPaintContent(false)
281        , hasBoundingBox(false)
282    { }
283
284    void setRects(const LayoutRect& bounds, const ClipRect& background, const ClipRect& foreground, const ClipRect& outline, const LayoutRect* bbox)
285    {
286        layerBounds = bounds;
287        backgroundRect = background;
288        foregroundRect = foreground;
289        outlineRect = outline;
290        if (bbox) {
291            boundingBox = *bbox;
292            hasBoundingBox = true;
293        }
294    }
295
296    void moveBy(const LayoutPoint& offset)
297    {
298        layerBounds.moveBy(offset);
299        backgroundRect.moveBy(offset);
300        foregroundRect.moveBy(offset);
301        outlineRect.moveBy(offset);
302        paginationClip.moveBy(offset);
303        boundingBox.moveBy(offset);
304    }
305
306    void intersect(const LayoutRect& rect)
307    {
308        backgroundRect.intersect(rect);
309        foregroundRect.intersect(rect);
310        outlineRect.intersect(rect);
311        boundingBox.intersect(rect);
312    }
313
314    bool shouldPaintContent;
315    bool hasBoundingBox;
316    LayoutRect layerBounds;
317    ClipRect backgroundRect;
318    ClipRect foregroundRect;
319    ClipRect outlineRect;
320    LayoutRect boundingBox;
321
322    // Unique to paginated fragments. The physical translation to apply to shift the layer when painting/hit-testing.
323    LayoutSize paginationOffset;
324
325    // Also unique to paginated fragments. An additional clip that applies to the layer. It is in layer-local
326    // (physical) coordinates.
327    LayoutRect paginationClip;
328};
329
330typedef Vector<LayerFragment, 1> LayerFragments;
331
332class RenderLayer final : public ScrollableArea {
333    WTF_MAKE_FAST_ALLOCATED;
334public:
335    friend class RenderReplica;
336
337    explicit RenderLayer(RenderLayerModelObject&);
338    virtual ~RenderLayer();
339
340#if PLATFORM(IOS)
341    // Called before the renderer's widget (if any) has been nulled out.
342    void willBeDestroyed();
343#endif
344    String name() const;
345
346    RenderLayerModelObject& renderer() const { return m_renderer; }
347    RenderBox* renderBox() const { return renderer().isBox() ? &toRenderBox(renderer()) : nullptr; }
348    RenderLayer* parent() const { return m_parent; }
349    RenderLayer* previousSibling() const { return m_previous; }
350    RenderLayer* nextSibling() const { return m_next; }
351    RenderLayer* firstChild() const { return m_first; }
352    RenderLayer* lastChild() const { return m_last; }
353
354    void addChild(RenderLayer* newChild, RenderLayer* beforeChild = nullptr);
355    RenderLayer* removeChild(RenderLayer*);
356
357    void removeOnlyThisLayer();
358    void insertOnlyThisLayer();
359
360    void repaintIncludingDescendants();
361
362    // Indicate that the layer contents need to be repainted. Only has an effect
363    // if layer compositing is being used.
364    void setBackingNeedsRepaint(GraphicsLayer::ShouldClipToLayer = GraphicsLayer::ClipToLayer);
365
366    // The rect is in the coordinate space of the layer's render object.
367    void setBackingNeedsRepaintInRect(const LayoutRect&, GraphicsLayer::ShouldClipToLayer = GraphicsLayer::ClipToLayer);
368    void repaintIncludingNonCompositingDescendants(RenderLayerModelObject* repaintContainer);
369
370    void styleChanged(StyleDifference, const RenderStyle* oldStyle);
371
372    RenderMarquee* marquee() const { return m_marquee.get(); }
373
374    bool isNormalFlowOnly() const { return m_isNormalFlowOnly; }
375    bool isSelfPaintingLayer() const { return m_isSelfPaintingLayer; }
376
377    bool cannotBlitToWindow() const;
378
379    bool isTransparent() const { return renderer().isTransparent() || renderer().hasMask(); }
380
381    bool hasReflection() const { return renderer().hasReflection(); }
382    bool isReflection() const { return renderer().isReplica(); }
383    RenderReplica* reflection() const { return m_reflection.get(); }
384    RenderLayer* reflectionLayer() const;
385
386    const RenderLayer* root() const
387    {
388        const RenderLayer* curr = this;
389        while (curr->parent())
390            curr = curr->parent();
391        return curr;
392    }
393
394    const LayoutPoint& location() const { return m_topLeft; }
395    void setLocation(const LayoutPoint& p) { m_topLeft = p; }
396
397    const IntSize& size() const { return m_layerSize; }
398    void setSize(const IntSize& size) { m_layerSize = size; }
399
400    LayoutRect rect() const { return LayoutRect(location(), size()); }
401
402    int scrollWidth() const;
403    int scrollHeight() const;
404
405    void panScrollFromPoint(const IntPoint&);
406
407    enum ScrollOffsetClamping {
408        ScrollOffsetUnclamped,
409        ScrollOffsetClamped
410    };
411
412    // Scrolling methods for layers that can scroll their overflow.
413    void scrollByRecursively(const IntSize&, ScrollOffsetClamping = ScrollOffsetUnclamped, ScrollableArea** scrolledArea = nullptr);
414    void scrollToOffset(const IntSize&, ScrollOffsetClamping = ScrollOffsetUnclamped);
415    void scrollToXOffset(int x, ScrollOffsetClamping clamp = ScrollOffsetUnclamped) { scrollToOffset(IntSize(x, scrollYOffset()), clamp); }
416    void scrollToYOffset(int y, ScrollOffsetClamping clamp = ScrollOffsetUnclamped) { scrollToOffset(IntSize(scrollXOffset(), y), clamp); }
417
418    int scrollXOffset() const { return m_scrollOffset.width() + scrollOrigin().x(); }
419    int scrollYOffset() const { return m_scrollOffset.height() + scrollOrigin().y(); }
420    IntSize scrollOffset() const { return IntSize(scrollXOffset(), scrollYOffset()); }
421    IntSize scrollableContentsSize() const;
422
423    void scrollRectToVisible(const LayoutRect&, const ScrollAlignment& alignX, const ScrollAlignment& alignY);
424
425    LayoutRect getRectToExpose(const LayoutRect& visibleRect, const LayoutRect& visibleRectRelativeToDocument, const LayoutRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY);
426
427    bool scrollsOverflow() const;
428    bool hasScrollbars() const { return m_hBar || m_vBar; }
429    void setHasHorizontalScrollbar(bool);
430    void setHasVerticalScrollbar(bool);
431
432    PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation);
433    void destroyScrollbar(ScrollbarOrientation);
434
435    bool hasHorizontalScrollbar() const { return horizontalScrollbar(); }
436    bool hasVerticalScrollbar() const { return verticalScrollbar(); }
437
438    // ScrollableArea overrides
439    virtual Scrollbar* horizontalScrollbar() const override { return m_hBar.get(); }
440    virtual Scrollbar* verticalScrollbar() const override { return m_vBar.get(); }
441    virtual ScrollableArea* enclosingScrollableArea() const override;
442
443#if PLATFORM(IOS)
444#if ENABLE(TOUCH_EVENTS)
445    virtual bool handleTouchEvent(const PlatformTouchEvent&) override;
446    virtual bool isTouchScrollable() const override { return true; }
447#endif
448    virtual bool isOverflowScroll() const override { return true; }
449
450    virtual void didStartScroll() override;
451    virtual void didEndScroll() override;
452    virtual void didUpdateScroll() override;
453    virtual void setIsUserScroll(bool isUserScroll) override { m_inUserScroll = isUserScroll; }
454
455    bool isInUserScroll() const { return m_inUserScroll; }
456
457    bool requiresScrollBoundsOriginUpdate() const { return m_requiresScrollBoundsOriginUpdate; }
458    void setRequiresScrollBoundsOriginUpdate(bool requiresUpdate = true) { m_requiresScrollBoundsOriginUpdate = requiresUpdate; }
459
460    // Returns true when the layer could do touch scrolling, but doesn't look at whether there is actually scrollable overflow.
461    bool hasAcceleratedTouchScrolling() const;
462    // Returns true when there is actually scrollable overflow (requires layout to be up-to-date).
463    bool hasTouchScrollableOverflow() const;
464#endif
465
466    int verticalScrollbarWidth(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
467    int horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
468
469    bool hasOverflowControls() const;
470    bool isPointInResizeControl(const IntPoint& absolutePoint) const;
471    bool hitTestOverflowControls(HitTestResult&, const IntPoint& localPoint);
472    IntSize offsetFromResizeCorner(const IntPoint& absolutePoint) const;
473
474    void paintOverflowControls(GraphicsContext*, const IntPoint&, const IntRect& damageRect, bool paintingOverlayControls = false);
475    void paintScrollCorner(GraphicsContext*, const IntPoint&, const IntRect& damageRect);
476    void paintResizer(GraphicsContext*, const LayoutPoint&, const LayoutRect& damageRect);
477
478    void updateScrollInfoAfterLayout();
479
480    bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1);
481    void autoscroll(const IntPoint&);
482
483    bool canResize() const;
484    void resize(const PlatformMouseEvent&, const LayoutSize&);
485    bool inResizeMode() const { return m_inResizeMode; }
486    void setInResizeMode(bool b) { m_inResizeMode = b; }
487
488    bool isRootLayer() const { return m_isRootLayer; }
489
490    RenderLayerCompositor& compositor() const;
491
492    // Notification from the renderer that its content changed (e.g. current frame of image changed).
493    // Allows updates of layer content without repainting.
494    void contentChanged(ContentChangeType);
495
496    bool canRender3DTransforms() const;
497
498    enum UpdateLayerPositionsFlag {
499        CheckForRepaint = 1 << 0,
500        NeedsFullRepaintInBacking = 1 << 1,
501        IsCompositingUpdateRoot = 1 << 2,
502        UpdateCompositingLayers = 1 << 3,
503        UpdatePagination = 1 << 4,
504        SeenTransformedLayer = 1 << 5,
505        Seen3DTransformedLayer = 1 << 6
506    };
507    typedef unsigned UpdateLayerPositionsFlags;
508    static const UpdateLayerPositionsFlags defaultFlags = CheckForRepaint | IsCompositingUpdateRoot | UpdateCompositingLayers;
509
510    void updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, UpdateLayerPositionsFlags);
511
512    void updateLayerPositionsAfterOverflowScroll();
513    void updateLayerPositionsAfterDocumentScroll();
514
515    void positionNewlyCreatedOverflowControls();
516
517    bool hasCompositedLayerInEnclosingPaginationChain() const;
518    enum PaginationInclusionMode { ExcludeCompositedPaginatedLayers, IncludeCompositedPaginatedLayers };
519    RenderLayer* enclosingPaginationLayer(PaginationInclusionMode mode) const
520    {
521        if (mode == ExcludeCompositedPaginatedLayers && hasCompositedLayerInEnclosingPaginationChain())
522            return nullptr;
523        return m_enclosingPaginationLayer;
524    }
525
526    void updateTransform();
527
528#if ENABLE(CSS_COMPOSITING)
529    void updateBlendMode();
530#endif
531
532    const LayoutSize& offsetForInFlowPosition() const { return m_offsetForInFlowPosition; }
533
534    void clearClipRectsIncludingDescendants(ClipRectsType typeToClear = AllClipRectTypes);
535    void clearClipRects(ClipRectsType typeToClear = AllClipRectTypes);
536
537    void addBlockSelectionGapsBounds(const LayoutRect&);
538    void clearBlockSelectionGapsBounds();
539    void repaintBlockSelectionGaps();
540
541    // A stacking context is a layer that has a non-auto z-index.
542    bool isStackingContext() const { return isStackingContext(&renderer().style()); }
543
544    // A stacking container can have z-order lists. All stacking contexts are
545    // stacking containers, but the converse is not true. Layers that use
546    // composited scrolling are stacking containers, but they may not
547    // necessarily be stacking contexts.
548    bool isStackingContainer() const { return isStackingContext() || needsCompositedScrolling(); }
549
550    // Gets the enclosing stacking container for this layer, excluding this
551    // layer itself.
552    RenderLayer* stackingContainer() const;
553
554    // Gets the enclosing stacking container for this layer, possibly the layer
555    // itself, if it is a stacking container.
556    RenderLayer* enclosingStackingContainer() { return isStackingContainer() ? this : stackingContainer(); }
557
558    void dirtyZOrderLists();
559    void dirtyStackingContainerZOrderLists();
560
561    Vector<RenderLayer*>* posZOrderList() const
562    {
563        ASSERT(!m_zOrderListsDirty);
564        ASSERT(isStackingContainer() || !m_posZOrderList);
565        return m_posZOrderList.get();
566    }
567
568    bool hasNegativeZOrderList() const { return negZOrderList() && negZOrderList()->size(); }
569
570    Vector<RenderLayer*>* negZOrderList() const
571    {
572        ASSERT(!m_zOrderListsDirty);
573        ASSERT(isStackingContainer() || !m_negZOrderList);
574        return m_negZOrderList.get();
575    }
576
577    void dirtyNormalFlowList();
578    Vector<RenderLayer*>* normalFlowList() const { ASSERT(!m_normalFlowListDirty); return m_normalFlowList.get(); }
579
580    // Update our normal and z-index lists.
581    void updateLayerListsIfNeeded();
582
583    // Update the normal and z-index lists of our descendants.
584    void updateDescendantsLayerListsIfNeeded(bool recursive);
585
586    // FIXME: We should ASSERT(!m_visibleContentStatusDirty) here, but see https://bugs.webkit.org/show_bug.cgi?id=71044
587    // ditto for hasVisibleDescendant(), see https://bugs.webkit.org/show_bug.cgi?id=71277
588    bool hasVisibleContent() const { return m_hasVisibleContent; }
589    bool hasVisibleDescendant() const { return m_hasVisibleDescendant; }
590
591    void setHasVisibleContent();
592    void dirtyVisibleContentStatus();
593
594    bool hasBoxDecorationsOrBackground() const;
595    bool hasVisibleBoxDecorations() const;
596    // Returns true if this layer has visible content (ignoring any child layers).
597    bool isVisuallyNonEmpty() const;
598    // True if this layer container renderers that paint.
599    bool hasNonEmptyChildRenderers() const;
600
601    // FIXME: We should ASSERT(!m_hasSelfPaintingLayerDescendantDirty); here but we hit the same bugs as visible content above.
602    // Part of the issue is with subtree relayout: we don't check if our ancestors have some descendant flags dirty, missing some updates.
603    bool hasSelfPaintingLayerDescendant() const { return m_hasSelfPaintingLayerDescendant; }
604
605    // This returns true if we have an out of flow positioned descendant whose
606    // containing block is not a descendant of ours. If this is true, we cannot
607    // automatically opt into composited scrolling since this out of flow
608    // positioned descendant would become clipped by us, possibly altering the
609    // rendering of the page.
610    // FIXME: We should ASSERT(!m_hasOutOfFlowPositionedDescendantDirty); here but we may hit the same bugs as visible content above.
611    bool hasOutOfFlowPositionedDescendant() const { return m_hasOutOfFlowPositionedDescendant; }
612
613    // Gets the nearest enclosing positioned ancestor layer (also includes
614    // the <html> layer and the root layer).
615    RenderLayer* enclosingPositionedAncestor() const;
616
617    // Returns the nearest enclosing layer that is scrollable.
618    RenderLayer* enclosingScrollableLayer() const;
619
620    // The layer relative to which clipping rects for this layer are computed.
621    RenderLayer* clippingRootForPainting() const;
622
623    RenderLayer* enclosingOverflowClipLayer(IncludeSelfOrNot) const;
624
625    // Enclosing compositing layer; if includeSelf is true, may return this.
626    RenderLayer* enclosingCompositingLayer(IncludeSelfOrNot = IncludeSelf) const;
627    RenderLayer* enclosingCompositingLayerForRepaint(IncludeSelfOrNot = IncludeSelf) const;
628    // Ancestor compositing layer, excluding this.
629    RenderLayer* ancestorCompositingLayer() const { return enclosingCompositingLayer(ExcludeSelf); }
630
631#if ENABLE(CSS_FILTERS)
632    RenderLayer* enclosingFilterLayer(IncludeSelfOrNot = IncludeSelf) const;
633    RenderLayer* enclosingFilterRepaintLayer() const;
634    void setFilterBackendNeedsRepaintingInRect(const LayoutRect&);
635    bool hasAncestorWithFilterOutsets() const;
636#endif
637
638    bool canUseConvertToLayerCoords() const
639    {
640        // These RenderObject have an impact on their layers' without them knowing about it.
641        return !renderer().hasTransform() && !renderer().isSVGRoot();
642    }
643
644    // FIXME: adjustForColumns allows us to position compositing layers in columns correctly, but eventually they need to be split across columns too.
645    enum ColumnOffsetAdjustment { DontAdjustForColumns, AdjustForColumns };
646    void convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& location, ColumnOffsetAdjustment adjustForColumns = DontAdjustForColumns) const;
647    LayoutPoint convertToLayerCoords(const RenderLayer* ancestorLayer, const LayoutPoint&, ColumnOffsetAdjustment adjustForColumns = DontAdjustForColumns) const;
648    LayoutSize offsetFromAncestor(const RenderLayer*) const;
649
650    int zIndex() const { return renderer().style().zIndex(); }
651
652    enum PaintLayerFlag {
653        PaintLayerHaveTransparency = 1,
654        PaintLayerAppliedTransform = 1 << 1,
655        PaintLayerTemporaryClipRects = 1 << 2,
656        PaintLayerPaintingReflection = 1 << 3,
657        PaintLayerPaintingOverlayScrollbars = 1 << 4,
658        PaintLayerPaintingCompositingBackgroundPhase = 1 << 5,
659        PaintLayerPaintingCompositingForegroundPhase = 1 << 6,
660        PaintLayerPaintingCompositingMaskPhase = 1 << 7,
661        PaintLayerPaintingCompositingScrollingPhase = 1 << 8,
662        PaintLayerPaintingOverflowContents = 1 << 9,
663        PaintLayerPaintingRootBackgroundOnly = 1 << 10,
664        PaintLayerPaintingSkipRootBackground = 1 << 11,
665        PaintLayerPaintingCompositingAllPhases = (PaintLayerPaintingCompositingBackgroundPhase | PaintLayerPaintingCompositingForegroundPhase | PaintLayerPaintingCompositingMaskPhase)
666    };
667
668    typedef unsigned PaintLayerFlags;
669
670    // The two main functions that use the layer system.  The paint method
671    // paints the layers that intersect the damage rect from back to
672    // front.  The hitTest method looks for mouse events by walking
673    // layers that intersect the point from front to back.
674    void paint(GraphicsContext*, const LayoutRect& damageRect, PaintBehavior = PaintBehaviorNormal, RenderObject* subtreePaintRoot = nullptr, PaintLayerFlags = 0);
675    bool hitTest(const HitTestRequest&, HitTestResult&);
676    bool hitTest(const HitTestRequest&, const HitTestLocation&, HitTestResult&);
677    void paintOverlayScrollbars(GraphicsContext*, const LayoutRect& damageRect, PaintBehavior, RenderObject* subtreePaintRoot = nullptr);
678
679    void paintNamedFlowThreadInsideRegion(GraphicsContext*, RenderNamedFlowFragment*, LayoutRect, LayoutPoint, PaintBehavior = PaintBehaviorNormal, PaintLayerFlags = 0);
680
681    struct ClipRectsContext {
682        ClipRectsContext(const RenderLayer* inRootLayer, ClipRectsType inClipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize, ShouldRespectOverflowClip inRespectOverflowClip = RespectOverflowClip)
683            : rootLayer(inRootLayer)
684            , clipRectsType(inClipRectsType)
685            , overlayScrollbarSizeRelevancy(inOverlayScrollbarSizeRelevancy)
686            , respectOverflowClip(inRespectOverflowClip)
687        { }
688        const RenderLayer* rootLayer;
689        ClipRectsType clipRectsType;
690        OverlayScrollbarSizeRelevancy overlayScrollbarSizeRelevancy;
691        ShouldRespectOverflowClip respectOverflowClip;
692    };
693
694    // This method figures out our layerBounds in coordinates relative to
695    // |rootLayer}.  It also computes our background and foreground clip rects
696    // for painting/event handling.
697    // Pass offsetFromRoot if known.
698    void calculateRects(const ClipRectsContext&, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
699        ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutSize& offsetFromRoot) const;
700
701    // Compute and cache clip rects computed with the given layer as the root
702    void updateClipRects(const ClipRectsContext&);
703    // Compute and return the clip rects. If useCached is true, will used previously computed clip rects on ancestors
704    // (rather than computing them all from scratch up the parent chain).
705    void calculateClipRects(const ClipRectsContext&, ClipRects&) const;
706
707    ClipRects* clipRects(const ClipRectsContext& context) const
708    {
709        ASSERT(context.clipRectsType < NumCachedClipRectsTypes);
710        return m_clipRectsCache ? m_clipRectsCache->getClipRects(context.clipRectsType, context.respectOverflowClip).get() : 0;
711    }
712
713    LayoutRect childrenClipRect() const; // Returns the foreground clip rect of the layer in the document's coordinate space.
714    LayoutRect selfClipRect() const; // Returns the background clip rect of the layer in the document's coordinate space.
715    LayoutRect localClipRect(bool& clipExceedsBounds) const; // Returns the background clip rect of the layer in the local coordinate space.
716
717    // Pass offsetFromRoot if known.
718    bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutSize& offsetFromRoot, const LayoutRect* cachedBoundingBox = nullptr) const;
719
720    enum CalculateLayerBoundsFlag {
721        IncludeSelfTransform = 1 << 0,
722        UseLocalClipRectIfPossible = 1 << 1,
723        IncludeLayerFilterOutsets = 1 << 2,
724        ExcludeHiddenDescendants = 1 << 3,
725        DontConstrainForMask = 1 << 4,
726        IncludeCompositedDescendants = 1 << 5,
727        UseFragmentBoxesExcludingCompositing = 1 << 6,
728        UseFragmentBoxesIncludingCompositing = 1 << 7,
729        DefaultCalculateLayerBoundsFlags =  IncludeSelfTransform | UseLocalClipRectIfPossible | IncludeLayerFilterOutsets | UseFragmentBoxesExcludingCompositing
730    };
731    typedef unsigned CalculateLayerBoundsFlags;
732
733    // Bounding box relative to some ancestor layer. Pass offsetFromRoot if known.
734    LayoutRect boundingBox(const RenderLayer* rootLayer, const LayoutSize& offsetFromRoot = LayoutSize(), CalculateLayerBoundsFlags = 0) const;
735    // Bounding box in the coordinates of this layer.
736    LayoutRect localBoundingBox(CalculateLayerBoundsFlags = 0) const;
737    // Deprecated: Pixel snapped bounding box relative to the root.
738    IntRect absoluteBoundingBox() const;
739    // Device pixel snapped bounding box relative to the root. absoluteBoundingBox() callers will be directed to this.
740    FloatRect absoluteBoundingBoxForPainting() const;
741
742    // Bounds used for layer overlap testing in RenderLayerCompositor.
743    LayoutRect overlapBounds() const { return overlapBoundsIncludeChildren() ? calculateLayerBounds(this, LayoutSize()) : localBoundingBox(); }
744
745#if ENABLE(CSS_FILTERS)
746    // If true, this layer's children are included in its bounds for overlap testing.
747    // We can't rely on the children's positions if this layer has a filter that could have moved the children's pixels around.
748    bool overlapBoundsIncludeChildren() const { return hasFilter() && renderer().style().filter().hasFilterThatMovesPixels(); }
749#else
750    bool overlapBoundsIncludeChildren() const { return false; }
751#endif
752
753    // Can pass offsetFromRoot if known.
754    LayoutRect calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutSize& offsetFromRoot, CalculateLayerBoundsFlags = DefaultCalculateLayerBoundsFlags) const;
755
756    // Return a cached repaint rect, computed relative to the layer renderer's containerForRepaint.
757    LayoutRect repaintRect() const { return m_repaintRect; }
758    LayoutRect repaintRectIncludingNonCompositingDescendants() const;
759
760    void setRepaintStatus(RepaintStatus status) { m_repaintStatus = status; }
761
762    LayoutUnit staticInlinePosition() const { return m_staticInlinePosition; }
763    LayoutUnit staticBlockPosition() const { return m_staticBlockPosition; }
764
765    void setStaticInlinePosition(LayoutUnit position) { m_staticInlinePosition = position; }
766    void setStaticBlockPosition(LayoutUnit position) { m_staticBlockPosition = position; }
767
768#if PLATFORM(IOS)
769    bool adjustForIOSCaretWhenScrolling() const { return m_adjustForIOSCaretWhenScrolling; }
770    void setAdjustForIOSCaretWhenScrolling(bool adjustForIOSCaretWhenScrolling) { m_adjustForIOSCaretWhenScrolling = adjustForIOSCaretWhenScrolling; }
771#endif
772
773    bool hasTransform() const { return renderer().hasTransform(); }
774    // Note that this transform has the transform-origin baked in.
775    TransformationMatrix* transform() const { return m_transform.get(); }
776    // currentTransform computes a transform which takes accelerated animations into account. The
777    // resulting transform has transform-origin baked in. If the layer does not have a transform,
778    // returns the identity matrix.
779    TransformationMatrix currentTransform(RenderStyle::ApplyTransformOrigin = RenderStyle::IncludeTransformOrigin) const;
780    TransformationMatrix renderableTransform(PaintBehavior) const;
781
782    // Get the perspective transform, which is applied to transformed sublayers.
783    // Returns true if the layer has a -webkit-perspective.
784    // Note that this transform has the perspective-origin baked in.
785    TransformationMatrix perspectiveTransform() const;
786    FloatPoint perspectiveOrigin() const;
787    bool preserves3D() const { return renderer().style().transformStyle3D() == TransformStyle3DPreserve3D; }
788    bool has3DTransform() const { return m_transform && !m_transform->isAffine(); }
789
790#if ENABLE(CSS_FILTERS)
791    virtual void filterNeedsRepaint();
792    bool hasFilter() const { return renderer().hasFilter(); }
793#else
794    bool hasFilter() const { return false; }
795#endif
796
797#if ENABLE(CSS_COMPOSITING)
798    bool hasBlendMode() const { return renderer().hasBlendMode(); }
799    BlendMode blendMode() const { return static_cast<BlendMode>(m_blendMode); }
800
801    bool isolatesCompositedBlending() const { return m_hasNotIsolatedCompositedBlendingDescendants && isStackingContext(); }
802    bool hasNotIsolatedCompositedBlendingDescendants() const { return m_hasNotIsolatedCompositedBlendingDescendants; }
803    void setHasNotIsolatedCompositedBlendingDescendants(bool hasNotIsolatedCompositedBlendingDescendants)
804    {
805        m_hasNotIsolatedCompositedBlendingDescendants = hasNotIsolatedCompositedBlendingDescendants;
806    }
807
808    bool isolatesBlending() const { return hasNotIsolatedBlendingDescendants() && isStackingContext(); }
809
810    // FIXME: We should ASSERT(!m_hasNotIsolatedBlendingDescendantsStatusDirty); here but we hit the same bugs as visible content above.
811    bool hasNotIsolatedBlendingDescendants() const { return m_hasNotIsolatedBlendingDescendants; }
812    bool hasNotIsolatedBlendingDescendantsStatusDirty() const { return m_hasNotIsolatedBlendingDescendantsStatusDirty; }
813#else
814    bool hasBlendMode() const { return false; }
815    bool isolatesCompositedBlending() const { return false; }
816    bool isolatesBlending() const { return false; }
817    bool hasNotIsolatedBlendingDescendantsStatusDirty() const { return false; }
818#endif
819
820    bool isComposited() const { return m_backing != 0; }
821    bool hasCompositingDescendant() const { return m_hasCompositingDescendant; }
822    bool hasCompositedMask() const;
823    RenderLayerBacking* backing() const { return m_backing.get(); }
824    RenderLayerBacking* ensureBacking();
825    void clearBacking(bool layerBeingDestroyed = false);
826    virtual GraphicsLayer* layerForScrolling() const override;
827    virtual GraphicsLayer* layerForHorizontalScrollbar() const override;
828    virtual GraphicsLayer* layerForVerticalScrollbar() const override;
829    virtual GraphicsLayer* layerForScrollCorner() const override;
830    virtual bool usesCompositedScrolling() const override;
831    bool needsCompositedScrolling() const;
832    bool needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const;
833    bool needsCompositingLayersRebuiltForOverflow(const RenderStyle* oldStyle, const RenderStyle* newStyle) const;
834
835    bool paintsWithTransparency(PaintBehavior paintBehavior) const
836    {
837        return (isTransparent() || hasBlendMode() || (isolatesBlending() && !renderer().isRoot())) && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || !isComposited());
838    }
839
840    bool paintsWithTransform(PaintBehavior) const;
841
842    // Returns true if background phase is painted opaque in the given rect.
843    // The query rect is given in local coordinates.
844    bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const;
845
846    bool containsDirtyOverlayScrollbars() const { return m_containsDirtyOverlayScrollbars; }
847    void setContainsDirtyOverlayScrollbars(bool dirtyScrollbars) { m_containsDirtyOverlayScrollbars = dirtyScrollbars; }
848
849#if ENABLE(CSS_FILTERS)
850    bool paintsWithFilters() const;
851    bool requiresFullLayerImageForFilters() const;
852    FilterEffectRenderer* filterRenderer() const;
853#endif
854
855#if !ASSERT_DISABLED
856    bool layerListMutationAllowed() const { return m_layerListMutationAllowed; }
857    void setLayerListMutationAllowed(bool flag) { m_layerListMutationAllowed = flag; }
858#endif
859
860    Element* enclosingElement() const;
861
862    enum ViewportConstrainedNotCompositedReason {
863        NoNotCompositedReason,
864        NotCompositedForBoundsOutOfView,
865        NotCompositedForNonViewContainer,
866        NotCompositedForNoVisibleContent,
867    };
868
869    void setViewportConstrainedNotCompositedReason(ViewportConstrainedNotCompositedReason reason) { m_viewportConstrainedNotCompositedReason = reason; }
870    ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason() const { return static_cast<ViewportConstrainedNotCompositedReason>(m_viewportConstrainedNotCompositedReason); }
871
872    bool isRenderFlowThread() const { return renderer().isRenderFlowThread(); }
873    bool isOutOfFlowRenderFlowThread() const { return renderer().isOutOfFlowRenderFlowThread(); }
874    bool isInsideFlowThread() const { return renderer().flowThreadState() != RenderObject::NotInsideFlowThread; }
875    bool isInsideOutOfFlowThread() const { return renderer().flowThreadState() == RenderObject::InsideOutOfFlowThread; }
876    bool isDirtyRenderFlowThread() const
877    {
878        ASSERT(isRenderFlowThread());
879        return m_zOrderListsDirty || m_normalFlowListDirty;
880    }
881
882    bool isFlowThreadCollectingGraphicsLayersUnderRegions() const;
883
884    RenderLayer* enclosingFlowThreadAncestor() const;
885
886private:
887    enum CollectLayersBehavior { StopAtStackingContexts, StopAtStackingContainers };
888
889    struct LayerPaintingInfo {
890        LayerPaintingInfo(RenderLayer* inRootLayer, const LayoutRect& inDirtyRect, PaintBehavior inPaintBehavior, const LayoutSize& inSubpixelAccumulation, RenderObject* inSubtreePaintRoot = nullptr, OverlapTestRequestMap* inOverlapTestRequests = nullptr)
891            : rootLayer(inRootLayer)
892            , subtreePaintRoot(inSubtreePaintRoot)
893            , paintDirtyRect(inDirtyRect)
894            , subpixelAccumulation(inSubpixelAccumulation)
895            , overlapTestRequests(inOverlapTestRequests)
896            , paintBehavior(inPaintBehavior)
897            , clipToDirtyRect(true)
898        { }
899        RenderLayer* rootLayer;
900        RenderObject* subtreePaintRoot; // only paint descendants of this object
901        LayoutRect paintDirtyRect; // relative to rootLayer;
902        LayoutSize subpixelAccumulation;
903        OverlapTestRequestMap* overlapTestRequests; // May be null.
904        PaintBehavior paintBehavior;
905        bool clipToDirtyRect;
906    };
907
908    void updateZOrderLists();
909    void rebuildZOrderLists();
910    void rebuildZOrderLists(CollectLayersBehavior, std::unique_ptr<Vector<RenderLayer*>>&, std::unique_ptr<Vector<RenderLayer*>>&);
911    void clearZOrderLists();
912
913    void updateNormalFlowList();
914
915    // Non-auto z-index always implies stacking context here, because StyleResolver::adjustRenderStyle already adjusts z-index
916    // based on positioning and other criteria.
917    bool isStackingContext(const RenderStyle* style) const { return !style->hasAutoZIndex() || isRootLayer(); }
918
919    bool isDirtyStackingContainer() const { return m_zOrderListsDirty && isStackingContainer(); }
920
921    void setAncestorChainHasSelfPaintingLayerDescendant();
922    void dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
923
924    bool acceleratedCompositingForOverflowScrollEnabled() const;
925    void updateDescendantsAreContiguousInStackingOrder();
926    void updateDescendantsAreContiguousInStackingOrderRecursive(const HashMap<const RenderLayer*, int>&, int& minIndex, int& maxIndex, int& count, bool firstIteration);
927
928    void computeRepaintRects(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* = nullptr);
929    void computeRepaintRectsIncludingDescendants();
930    void clearRepaintRects();
931
932    void clipToRect(const LayerPaintingInfo&, GraphicsContext*, const ClipRect&, BorderRadiusClippingRule = IncludeSelfForBorderRadius);
933    void restoreClip(GraphicsContext*, const LayoutRect& paintDirtyRect, const ClipRect&);
934
935    bool shouldRepaintAfterLayout() const;
936
937    void updateSelfPaintingLayer();
938    void updateStackingContextsAfterStyleChange(const RenderStyle* oldStyle);
939
940    void updateScrollbarsAfterStyleChange(const RenderStyle* oldStyle);
941    void updateScrollbarsAfterLayout();
942
943    void setAncestorChainHasOutOfFlowPositionedDescendant(RenderBlock* containingBlock);
944    void dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
945    void updateOutOfFlowPositioned(const RenderStyle* oldStyle);
946
947    void updateNeedsCompositedScrolling();
948
949    // Returns true if the position changed.
950    bool updateLayerPosition();
951
952    void updateLayerPositions(RenderGeometryMap* = nullptr, UpdateLayerPositionsFlags = defaultFlags);
953
954    enum UpdateLayerPositionsAfterScrollFlag {
955        NoFlag = 0,
956        IsOverflowScroll = 1 << 0,
957        HasSeenViewportConstrainedAncestor = 1 << 1,
958        HasSeenAncestorWithOverflowClip = 1 << 2,
959        HasChangedAncestor = 1 << 3
960    };
961    typedef unsigned UpdateLayerPositionsAfterScrollFlags;
962    void updateLayerPositionsAfterScroll(RenderGeometryMap*, UpdateLayerPositionsAfterScrollFlags = NoFlag);
963
964    friend IntSize RenderBox::scrolledContentOffset() const;
965    IntSize scrolledContentOffset() const { return m_scrollOffset; }
966
967    IntSize clampScrollOffset(const IntSize&) const;
968
969    RenderLayer* enclosingPaginationLayerInSubtree(const RenderLayer* rootLayer, PaginationInclusionMode) const;
970
971    void setNextSibling(RenderLayer* next) { m_next = next; }
972    void setPreviousSibling(RenderLayer* prev) { m_previous = prev; }
973    void setParent(RenderLayer* parent);
974    void setFirstChild(RenderLayer* first) { m_first = first; }
975    void setLastChild(RenderLayer* last) { m_last = last; }
976
977    LayoutPoint renderBoxLocation() const { return renderer().isBox() ? toRenderBox(renderer()).location() : LayoutPoint(); }
978
979    void collectLayers(bool includeHiddenLayers, CollectLayersBehavior, std::unique_ptr<Vector<RenderLayer*>>&, std::unique_ptr<Vector<RenderLayer*>>&);
980
981    void updateCompositingAndLayerListsIfNeeded();
982
983    bool setupFontSubpixelQuantization(GraphicsContext*, bool& didQuantizeFonts);
984    bool setupClipPath(GraphicsContext*, const LayerPaintingInfo&, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed);
985#if ENABLE(CSS_FILTERS)
986    std::unique_ptr<FilterEffectRendererHelper> setupFilters(GraphicsContext*, LayerPaintingInfo&, PaintLayerFlags, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed);
987    GraphicsContext* applyFilters(FilterEffectRendererHelper*, GraphicsContext* originalContext, LayerPaintingInfo&, LayerFragments&);
988#endif
989
990    void paintLayer(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
991    void paintFixedLayersInNamedFlows(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
992    void paintLayerContentsAndReflection(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
993    void paintLayerByApplyingTransform(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags, const LayoutSize& translationOffset = LayoutSize());
994    void paintLayerContents(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
995    void paintList(Vector<RenderLayer*>*, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
996
997    void collectFragments(LayerFragments&, const RenderLayer* rootLayer, const LayoutRect& dirtyRect,
998        PaginationInclusionMode,
999        ClipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip, const LayoutSize& offsetFromRoot,
1000        const LayoutRect* layerBoundingBox = nullptr, ShouldApplyRootOffsetToFragments = IgnoreRootOffsetForFragments);
1001    void updatePaintingInfoForFragments(LayerFragments&, const LayerPaintingInfo&, PaintLayerFlags, bool shouldPaintContent, const LayoutSize& offsetFromRoot);
1002    void paintBackgroundForFragments(const LayerFragments&, GraphicsContext*, GraphicsContext* transparencyLayerContext,
1003        const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer);
1004    void paintForegroundForFragments(const LayerFragments&, GraphicsContext*, GraphicsContext* transparencyLayerContext,
1005        const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer,
1006        bool selectionOnly, bool forceBlackText);
1007    void paintForegroundForFragmentsWithPhase(PaintPhase, const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer);
1008    void paintOutlineForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer);
1009    void paintOverflowControlsForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&);
1010    void paintMaskForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, RenderObject* paintingRootForRenderer);
1011    void paintTransformedLayerIntoFragments(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
1012
1013    RenderLayer* transparentPaintingAncestor();
1014    void beginTransparencyLayers(GraphicsContext*, const LayerPaintingInfo&, const LayoutRect& dirtyRect);
1015
1016    RenderLayer* hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
1017        const LayoutRect& hitTestRect, const HitTestLocation&, bool appliedTransform,
1018        const HitTestingTransformState* = nullptr, double* zOffset = nullptr);
1019    RenderLayer* hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&,
1020        const LayoutRect& hitTestRect, const HitTestLocation&, const HitTestingTransformState* = nullptr, double* zOffset = nullptr,
1021        const LayoutSize& translationOffset = LayoutSize());
1022    RenderLayer* hitTestList(Vector<RenderLayer*>*, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
1023        const LayoutRect& hitTestRect, const HitTestLocation&,
1024        const HitTestingTransformState*, double* zOffsetForDescendants, double* zOffset,
1025        const HitTestingTransformState* unflattenedTransformState, bool depthSortDescendants);
1026
1027    RenderLayer* hitTestFixedLayersInNamedFlows(RenderLayer* rootLayer,
1028        const HitTestRequest&, HitTestResult&,
1029        const LayoutRect& hitTestRect, const HitTestLocation&,
1030        const HitTestingTransformState*,
1031        double* zOffsetForDescendants, double* zOffset,
1032        const HitTestingTransformState* unflattenedTransformState,
1033        bool depthSortDescendants);
1034
1035    PassRefPtr<HitTestingTransformState> createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer,
1036        const LayoutRect& hitTestRect, const HitTestLocation&,
1037        const HitTestingTransformState* containerTransformState,
1038        const LayoutSize& translationOffset = LayoutSize()) const;
1039
1040    bool hitTestContents(const HitTestRequest&, HitTestResult&, const LayoutRect& layerBounds, const HitTestLocation&, HitTestFilter) const;
1041    bool hitTestContentsForFragments(const LayerFragments&, const HitTestRequest&, HitTestResult&, const HitTestLocation&, HitTestFilter, bool& insideClipRect) const;
1042    bool hitTestResizerInFragments(const LayerFragments&, const HitTestLocation&) const;
1043    RenderLayer* hitTestTransformedLayerInFragments(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&,
1044        const LayoutRect& hitTestRect, const HitTestLocation&, const HitTestingTransformState* = nullptr, double* zOffset = nullptr);
1045
1046    bool listBackgroundIsKnownToBeOpaqueInRect(const Vector<RenderLayer*>*, const LayoutRect&) const;
1047
1048    void computeScrollDimensions();
1049    bool hasHorizontalOverflow() const;
1050    bool hasVerticalOverflow() const;
1051    bool hasScrollableHorizontalOverflow() const;
1052    bool hasScrollableVerticalOverflow() const;
1053
1054    bool showsOverflowControls() const;
1055
1056    bool shouldBeNormalFlowOnly() const;
1057
1058    bool shouldBeSelfPaintingLayer() const;
1059
1060    virtual int scrollPosition(Scrollbar*) const override;
1061
1062    // ScrollableArea interface
1063    virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) override;
1064    virtual void invalidateScrollCornerRect(const IntRect&) override;
1065    virtual bool isActive() const override;
1066    virtual bool isScrollCornerVisible() const override;
1067    virtual IntRect scrollCornerRect() const override;
1068    virtual IntRect convertFromScrollbarToContainingView(const Scrollbar*, const IntRect&) const override;
1069    virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar*, const IntRect&) const override;
1070    virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar*, const IntPoint&) const override;
1071    virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar*, const IntPoint&) const override;
1072    virtual int scrollSize(ScrollbarOrientation) const override;
1073    virtual void setScrollOffset(const IntPoint&) override;
1074    virtual IntPoint scrollPosition() const override;
1075    virtual IntPoint minimumScrollPosition() const override;
1076    virtual IntPoint maximumScrollPosition() const override;
1077    virtual IntRect visibleContentRectInternal(VisibleContentRectIncludesScrollbars, VisibleContentRectBehavior) const override;
1078    virtual IntSize visibleSize() const override;
1079    virtual IntSize contentsSize() const override;
1080    virtual IntSize overhangAmount() const override;
1081    virtual IntPoint lastKnownMousePosition() const override;
1082    virtual bool isHandlingWheelEvent() const override;
1083    virtual bool shouldSuspendScrollAnimations() const override;
1084    virtual IntRect scrollableAreaBoundingBox() const override;
1085    virtual bool updatesScrollLayerPositionOnMainThread() const override { return true; }
1086    virtual bool forceUpdateScrollbarsOnMainThreadForPerformanceTesting() const override;
1087
1088#if PLATFORM(IOS)
1089    void registerAsTouchEventListenerForScrolling();
1090    void unregisterAsTouchEventListenerForScrolling();
1091#endif
1092
1093    // Rectangle encompassing the scroll corner and resizer rect.
1094    LayoutRect scrollCornerAndResizerRect() const;
1095
1096    // NOTE: This should only be called by the overriden setScrollOffset from ScrollableArea.
1097    void scrollTo(int, int);
1098    void updateCompositingLayersAfterScroll();
1099
1100    IntSize scrollbarOffset(const Scrollbar*) const;
1101
1102    void updateScrollableAreaSet(bool hasOverflow);
1103
1104    void dirtyAncestorChainVisibleDescendantStatus();
1105    void setAncestorChainHasVisibleDescendant();
1106
1107    void updateDescendantDependentFlags(HashSet<const RenderObject*>* outOfFlowDescendantContainingBlocks = nullptr);
1108    bool checkIfDescendantClippingContextNeedsUpdate(bool isClipping);
1109
1110    bool has3DTransformedDescendant() const { return m_has3DTransformedDescendant; }
1111
1112    bool hasTransformedAncestor() const { return m_hasTransformedAncestor; }
1113    bool has3DTransformedAncestor() const { return m_has3DTransformedAncestor; }
1114
1115    void dirty3DTransformedDescendantStatus();
1116    // Both updates the status, and returns true if descendants of this have 3d.
1117    bool update3DTransformedDescendantStatus();
1118
1119    void createReflection();
1120    void removeReflection();
1121
1122    PassRef<RenderStyle> createReflectionStyle();
1123    bool paintingInsideReflection() const { return m_paintingInsideReflection; }
1124    void setPaintingInsideReflection(bool b) { m_paintingInsideReflection = b; }
1125
1126#if ENABLE(CSS_FILTERS)
1127    void updateOrRemoveFilterClients();
1128    void updateOrRemoveFilterEffectRenderer();
1129#endif
1130
1131#if ENABLE(CSS_COMPOSITING)
1132    void updateAncestorChainHasBlendingDescendants();
1133    void dirtyAncestorChainHasBlendingDescendants();
1134#endif
1135
1136    void parentClipRects(const ClipRectsContext&, ClipRects&) const;
1137    ClipRect backgroundClipRect(const ClipRectsContext&) const;
1138
1139    RenderLayer* enclosingTransformedAncestor() const;
1140
1141    // Convert a point in absolute coords into layer coords, taking transforms into account
1142    LayoutPoint absoluteToContents(const LayoutPoint&) const;
1143
1144    void positionOverflowControls(const IntSize&);
1145    void updateScrollCornerStyle();
1146    void updateResizerStyle();
1147
1148    void drawPlatformResizerImage(GraphicsContext*, const LayoutRect& resizerCornerRect);
1149
1150    void updatePagination();
1151
1152    void setHasCompositingDescendant(bool b)  { m_hasCompositingDescendant = b; }
1153
1154    enum class IndirectCompositingReason {
1155        None,
1156        Stacking,
1157        Overlap,
1158        BackgroundLayer,
1159        GraphicalEffect, // opacity, mask, filter, transform etc.
1160        Perspective,
1161        Preserve3D
1162    };
1163
1164    void setIndirectCompositingReason(IndirectCompositingReason reason) { m_indirectCompositingReason = static_cast<unsigned>(reason); }
1165    IndirectCompositingReason indirectCompositingReason() const { return static_cast<IndirectCompositingReason>(m_indirectCompositingReason); }
1166    bool mustCompositeForIndirectReasons() const { return m_indirectCompositingReason; }
1167
1168    // Returns true if z ordering would not change if this layer were a stacking container.
1169    bool canBeStackingContainer() const;
1170
1171    friend class RenderLayerBacking;
1172    friend class RenderLayerCompositor;
1173    friend class RenderLayerModelObject;
1174
1175    LayoutUnit overflowTop() const;
1176    LayoutUnit overflowBottom() const;
1177    LayoutUnit overflowLeft() const;
1178    LayoutUnit overflowRight() const;
1179
1180    IntRect rectForHorizontalScrollbar(const IntRect& borderBoxRect) const;
1181    IntRect rectForVerticalScrollbar(const IntRect& borderBoxRect) const;
1182
1183    LayoutUnit verticalScrollbarStart(int minX, int maxX) const;
1184    LayoutUnit horizontalScrollbarStart(int minX) const;
1185
1186    bool overflowControlsIntersectRect(const IntRect& localRect) const;
1187
1188    RenderLayer* hitTestFlowThreadIfRegionForFragments(const LayerFragments&, RenderLayer*, const HitTestRequest&, HitTestResult&,
1189        const LayoutRect&, const HitTestLocation&,
1190        const HitTestingTransformState*, double* zOffsetForDescendants,
1191        double* zOffset, const HitTestingTransformState* unflattenedTransformState, bool depthSortDescendants);
1192    void paintFlowThreadIfRegionForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
1193    bool mapLayerClipRectsToFragmentationLayer(ClipRects&) const;
1194
1195    RenderNamedFlowFragment* currentRenderNamedFlowFragment() const;
1196
1197private:
1198    // The bitfields are up here so they will fall into the padding from ScrollableArea on 64-bit.
1199
1200    // Keeps track of whether the layer is currently resizing, so events can cause resizing to start and stop.
1201    bool m_inResizeMode : 1;
1202
1203    bool m_scrollDimensionsDirty : 1;
1204    bool m_zOrderListsDirty : 1;
1205    bool m_normalFlowListDirty: 1;
1206    bool m_isNormalFlowOnly : 1;
1207
1208    bool m_isSelfPaintingLayer : 1;
1209
1210    // If have no self-painting descendants, we don't have to walk our children during painting. This can lead to
1211    // significant savings, especially if the tree has lots of non-self-painting layers grouped together (e.g. table cells).
1212    bool m_hasSelfPaintingLayerDescendant : 1;
1213    bool m_hasSelfPaintingLayerDescendantDirty : 1;
1214
1215    // If we have no out of flow positioned descendants and no non-descendant
1216    // appears between our descendants in stacking order, then we may become a
1217    // stacking context.
1218    bool m_hasOutOfFlowPositionedDescendant : 1;
1219    bool m_hasOutOfFlowPositionedDescendantDirty : 1;
1220
1221    bool m_needsCompositedScrolling : 1;
1222
1223    // If this is true, then no non-descendant appears between any of our
1224    // descendants in stacking order. This is one of the requirements of being
1225    // able to safely become a stacking context.
1226    bool m_descendantsAreContiguousInStackingOrder : 1;
1227
1228    const bool m_isRootLayer : 1;
1229
1230    bool m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether
1231                                 // we ended up painting this layer or any descendants (and therefore need to
1232                                 // blend).
1233    bool m_paintingInsideReflection : 1;  // A state bit tracking if we are painting inside a replica.
1234    bool m_inOverflowRelayout : 1;
1235    unsigned m_repaintStatus : 2; // RepaintStatus
1236
1237    bool m_visibleContentStatusDirty : 1;
1238    bool m_hasVisibleContent : 1;
1239    bool m_visibleDescendantStatusDirty : 1;
1240    bool m_hasVisibleDescendant : 1;
1241
1242    bool m_3DTransformedDescendantStatusDirty : 1;
1243    bool m_has3DTransformedDescendant : 1;  // Set on a stacking context layer that has 3D descendants anywhere
1244                                            // in a preserves3D hierarchy. Hint to do 3D-aware hit testing.
1245    bool m_hasCompositingDescendant : 1; // In the z-order tree.
1246
1247    bool m_hasTransformedAncestor : 1;
1248    bool m_has3DTransformedAncestor : 1;
1249
1250    unsigned m_indirectCompositingReason : 3;
1251    unsigned m_viewportConstrainedNotCompositedReason : 2;
1252
1253#if PLATFORM(IOS)
1254    bool m_adjustForIOSCaretWhenScrolling : 1;
1255    bool m_registeredAsTouchEventListenerForScrolling : 1;
1256    bool m_inUserScroll : 1;
1257    bool m_requiresScrollBoundsOriginUpdate : 1;
1258#endif
1259
1260    bool m_containsDirtyOverlayScrollbars : 1;
1261    bool m_updatingMarqueePosition : 1;
1262
1263#if !ASSERT_DISABLED
1264    bool m_layerListMutationAllowed : 1;
1265#endif
1266
1267#if ENABLE(CSS_FILTERS)
1268    bool m_hasFilterInfo : 1;
1269#endif
1270
1271#if ENABLE(CSS_COMPOSITING)
1272    unsigned m_blendMode : 5;
1273    bool m_hasNotIsolatedCompositedBlendingDescendants : 1;
1274    bool m_hasNotIsolatedBlendingDescendants : 1;
1275    bool m_hasNotIsolatedBlendingDescendantsStatusDirty : 1;
1276#endif
1277
1278    RenderLayerModelObject& m_renderer;
1279
1280    RenderLayer* m_parent;
1281    RenderLayer* m_previous;
1282    RenderLayer* m_next;
1283    RenderLayer* m_first;
1284    RenderLayer* m_last;
1285
1286    LayoutRect m_repaintRect; // Cached repaint rects. Used by layout.
1287    LayoutRect m_outlineBox;
1288
1289    // Our current relative position offset.
1290    LayoutSize m_offsetForInFlowPosition;
1291
1292    // Our (x,y) coordinates are in our parent layer's coordinate space.
1293    LayoutPoint m_topLeft;
1294
1295    // The layer's width/height
1296    IntSize m_layerSize;
1297
1298    // This is the (scroll) offset from scrollOrigin().
1299    IntSize m_scrollOffset;
1300
1301    // The width/height of our scrolled area.
1302    LayoutSize m_scrollSize;
1303
1304    // For layers with overflow, we have a pair of scrollbars.
1305    RefPtr<Scrollbar> m_hBar;
1306    RefPtr<Scrollbar> m_vBar;
1307
1308    // For layers that establish stacking contexts, m_posZOrderList holds a sorted list of all the
1309    // descendant layers within the stacking context that have z-indices of 0 or greater
1310    // (auto will count as 0).  m_negZOrderList holds descendants within our stacking context with negative
1311    // z-indices.
1312    std::unique_ptr<Vector<RenderLayer*>> m_posZOrderList;
1313    std::unique_ptr<Vector<RenderLayer*>> m_negZOrderList;
1314
1315    // This list contains child layers that cannot create stacking contexts.  For now it is just
1316    // overflow layers, but that may change in the future.
1317    std::unique_ptr<Vector<RenderLayer*>> m_normalFlowList;
1318
1319    std::unique_ptr<ClipRectsCache> m_clipRectsCache;
1320
1321    IntPoint m_cachedOverlayScrollbarOffset;
1322
1323    std::unique_ptr<RenderMarquee> m_marquee; // Used by layers with overflow:marquee
1324
1325    // Cached normal flow values for absolute positioned elements with static left/top values.
1326    LayoutUnit m_staticInlinePosition;
1327    LayoutUnit m_staticBlockPosition;
1328
1329    std::unique_ptr<TransformationMatrix> m_transform;
1330
1331    // May ultimately be extended to many replicas (with their own paint order).
1332    RenderPtr<RenderReplica> m_reflection;
1333
1334    // Renderers to hold our custom scroll corner and resizer.
1335    RenderPtr<RenderScrollbarPart> m_scrollCorner;
1336    RenderPtr<RenderScrollbarPart> m_resizer;
1337
1338    // Pointer to the enclosing RenderLayer that caused us to be paginated. It is 0 if we are not paginated.
1339    RenderLayer* m_enclosingPaginationLayer;
1340
1341    IntRect m_blockSelectionGapsBounds;
1342
1343    std::unique_ptr<RenderLayerBacking> m_backing;
1344
1345    class FilterInfo;
1346};
1347
1348inline void RenderLayer::clearZOrderLists()
1349{
1350    ASSERT(!isStackingContainer());
1351
1352    m_posZOrderList = nullptr;
1353    m_negZOrderList = nullptr;
1354}
1355
1356inline void RenderLayer::updateZOrderLists()
1357{
1358    if (!m_zOrderListsDirty)
1359        return;
1360
1361    if (!isStackingContainer()) {
1362        clearZOrderLists();
1363        m_zOrderListsDirty = false;
1364        return;
1365    }
1366
1367    rebuildZOrderLists();
1368}
1369
1370#if !ASSERT_DISABLED
1371class LayerListMutationDetector {
1372public:
1373    LayerListMutationDetector(RenderLayer* layer)
1374        : m_layer(layer)
1375        , m_previousMutationAllowedState(layer->layerListMutationAllowed())
1376    {
1377        m_layer->setLayerListMutationAllowed(false);
1378    }
1379
1380    ~LayerListMutationDetector()
1381    {
1382        m_layer->setLayerListMutationAllowed(m_previousMutationAllowedState);
1383    }
1384
1385private:
1386    RenderLayer* m_layer;
1387    bool m_previousMutationAllowedState;
1388};
1389#endif
1390
1391void makeMatrixRenderable(TransformationMatrix&, bool has3DRendering);
1392
1393} // namespace WebCore
1394
1395#ifndef NDEBUG
1396// Outside the WebCore namespace for ease of invocation from gdb.
1397void showLayerTree(const WebCore::RenderLayer*);
1398void showLayerTree(const WebCore::RenderObject*);
1399#endif
1400
1401#endif // RenderLayer_h
1402