Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/painting/nsDisplayList.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
 */
7
8
/*
9
 * structures that represent things to be painted (ordered in z-order),
10
 * used during painting and hit testing
11
 */
12
13
#ifndef NSDISPLAYLIST_H_
14
#define NSDISPLAYLIST_H_
15
16
#include "mozilla/Attributes.h"
17
#include "gfxContext.h"
18
#include "mozilla/ArenaAllocator.h"
19
#include "mozilla/Assertions.h"
20
#include "mozilla/Attributes.h"
21
#include "mozilla/Array.h"
22
#include "mozilla/DebugOnly.h"
23
#include "mozilla/EnumSet.h"
24
#include "mozilla/Maybe.h"
25
#include "mozilla/RefPtr.h"
26
#include "mozilla/TemplateLib.h" // mozilla::tl::Max
27
#include "nsCOMPtr.h"
28
#include "nsContainerFrame.h"
29
#include "nsPoint.h"
30
#include "nsRect.h"
31
#include "nsRegion.h"
32
#include "nsDisplayListInvalidation.h"
33
#include "DisplayItemClipChain.h"
34
#include "DisplayListClipState.h"
35
#include "LayerState.h"
36
#include "FrameMetrics.h"
37
#include "ImgDrawResult.h"
38
#include "mozilla/EffectCompositor.h"
39
#include "mozilla/EnumeratedArray.h"
40
#include "mozilla/Maybe.h"
41
#include "mozilla/UniquePtr.h"
42
#include "mozilla/TimeStamp.h"
43
#include "mozilla/gfx/UserData.h"
44
#include "mozilla/layers/LayerAttributes.h"
45
#include "nsCSSRenderingBorders.h"
46
#include "nsPresArena.h"
47
#include "nsAutoLayoutPhase.h"
48
#include "nsDisplayItemTypes.h"
49
#include "RetainedDisplayListHelpers.h"
50
51
#include <stdint.h>
52
#include "nsTHashtable.h"
53
54
#include <stdlib.h>
55
#include <algorithm>
56
#include <unordered_set>
57
58
class gfxContext;
59
class nsIContent;
60
class nsDisplayList;
61
class nsDisplayTableItem;
62
class nsIScrollableFrame;
63
class nsSubDocumentFrame;
64
class nsDisplayCompositorHitTestInfo;
65
class nsDisplayScrollInfoLayer;
66
class nsCaret;
67
enum class nsDisplayOwnLayerFlags;
68
69
namespace mozilla {
70
class FrameLayerBuilder;
71
struct MotionPathData;
72
namespace layers {
73
class Layer;
74
class ImageLayer;
75
class ImageContainer;
76
class StackingContextHelper;
77
class WebRenderCommand;
78
class WebRenderScrollData;
79
class WebRenderLayerScrollData;
80
} // namespace layers
81
namespace wr {
82
class DisplayListBuilder;
83
} // namespace wr
84
namespace dom {
85
class Selection;
86
} // namespace dom
87
} // namespace mozilla
88
89
/*
90
 * An nsIFrame can have many different visual parts. For example an image frame
91
 * can have a background, border, and outline, the image itself, and a
92
 * translucent selection overlay. In general these parts can be drawn at
93
 * discontiguous z-levels; see CSS2.1 appendix E:
94
 * http://www.w3.org/TR/CSS21/zindex.html
95
 *
96
 * We construct a display list for a frame tree that contains one item
97
 * for each visual part. The display list is itself a tree since some items
98
 * are containers for other items; however, its structure does not match
99
 * the structure of its source frame tree. The display list items are sorted
100
 * by z-order. A display list can be used to paint the frames, to determine
101
 * which frame is the target of a mouse event, and to determine what areas
102
 * need to be repainted when scrolling. The display lists built for each task
103
 * may be different for efficiency; in particular some frames need special
104
 * display list items only for event handling, and do not create these items
105
 * when the display list will be used for painting (the common case). For
106
 * example, when painting we avoid creating nsDisplayBackground items for
107
 * frames that don't display a visible background, but for event handling
108
 * we need those backgrounds because they are not transparent to events.
109
 *
110
 * We could avoid constructing an explicit display list by traversing the
111
 * frame tree multiple times in clever ways. However, reifying the display list
112
 * reduces code complexity and reduces the number of times each frame must be
113
 * traversed to one, which seems to be good for performance. It also means
114
 * we can share code for painting, event handling and scroll analysis.
115
 *
116
 * Display lists are short-lived; content and frame trees cannot change
117
 * between a display list being created and destroyed. Display lists should
118
 * not be created during reflow because the frame tree may be in an
119
 * inconsistent state (e.g., a frame's stored overflow-area may not include
120
 * the bounds of all its children). However, it should be fine to create
121
 * a display list while a reflow is pending, before it starts.
122
 *
123
 * A display list covers the "extended" frame tree; the display list for
124
 * a frame tree containing FRAME/IFRAME elements can include frames from
125
 * the subdocuments.
126
 *
127
 * Display item's coordinates are relative to their nearest reference frame
128
 * ancestor. Both the display root and any frame with a transform act as a
129
 * reference frame for their frame subtrees.
130
 */
131
132
// All types are defined in nsDisplayItemTypes.h
133
#define NS_DISPLAY_DECL_NAME(n, e)                                             \
134
0
  const char* Name() const override { return n; }                              \
Unexecuted instantiation: nsDisplayCaret::Name() const
Unexecuted instantiation: nsDisplayBorder::Name() const
Unexecuted instantiation: nsDisplaySolidColor::Name() const
Unexecuted instantiation: nsDisplaySolidColorRegion::Name() const
Unexecuted instantiation: nsDisplayBackgroundImage::Name() const
Unexecuted instantiation: nsDisplayTableBackgroundImage::Name() const
Unexecuted instantiation: nsDisplayThemedBackground::Name() const
Unexecuted instantiation: nsDisplayTableThemedBackground::Name() const
Unexecuted instantiation: nsDisplayBackgroundColor::Name() const
Unexecuted instantiation: nsDisplayTableBackgroundColor::Name() const
Unexecuted instantiation: nsDisplayClearBackground::Name() const
Unexecuted instantiation: nsDisplayBoxShadowOuter::Name() const
Unexecuted instantiation: nsDisplayBoxShadowInner::Name() const
Unexecuted instantiation: nsDisplayOutline::Name() const
Unexecuted instantiation: nsDisplayEventReceiver::Name() const
Unexecuted instantiation: nsDisplayCompositorHitTestInfo::Name() const
Unexecuted instantiation: nsDisplayWrapList::Name() const
Unexecuted instantiation: nsDisplayOpacity::Name() const
Unexecuted instantiation: nsDisplayBlendMode::Name() const
Unexecuted instantiation: nsDisplayTableBlendMode::Name() const
Unexecuted instantiation: nsDisplayBlendContainer::Name() const
Unexecuted instantiation: nsDisplayTableBlendContainer::Name() const
Unexecuted instantiation: nsDisplayOwnLayer::Name() const
Unexecuted instantiation: nsDisplaySubDocument::Name() const
Unexecuted instantiation: nsDisplayResolution::Name() const
Unexecuted instantiation: nsDisplayStickyPosition::Name() const
Unexecuted instantiation: nsDisplayFixedPosition::Name() const
Unexecuted instantiation: nsDisplayTableFixedPosition::Name() const
Unexecuted instantiation: nsDisplayScrollInfoLayer::Name() const
Unexecuted instantiation: nsDisplayZoom::Name() const
Unexecuted instantiation: nsDisplayMask::Name() const
Unexecuted instantiation: nsDisplayFilter::Name() const
Unexecuted instantiation: nsDisplayTransform::Name() const
Unexecuted instantiation: nsDisplayPerspective::Name() const
Unexecuted instantiation: nsDisplaySVGWrapper::Name() const
Unexecuted instantiation: nsDisplayForeignObject::Name() const
Unexecuted instantiation: nsDisplayCanvasBackgroundColor::Name() const
Unexecuted instantiation: nsDisplayCanvasBackgroundImage::Name() const
Unexecuted instantiation: nsDisplayCanvasThemedBackground::Name() const
Unexecuted instantiation: nsDisplayImage::Name() const
Unexecuted instantiation: nsDisplayPlugin::Name() const
Unexecuted instantiation: nsDisplayPluginReadback::Name() const
Unexecuted instantiation: mozilla::css::nsDisplayTextOverflowMarker::Name() const
Unexecuted instantiation: nsDisplayBullet::Name() const
Unexecuted instantiation: nsDisplayColumnRule::Name() const
Unexecuted instantiation: nsDisplaySelectionOverlay::Name() const
Unexecuted instantiation: nsDisplayCanvasFocus::Name() const
Unexecuted instantiation: nsDisplayFramesetBorder::Name() const
Unexecuted instantiation: nsDisplayFramesetBlank::Name() const
Unexecuted instantiation: nsDisplayCanvas::Name() const
Unexecuted instantiation: nsDisplayAltFeedback::Name() const
Unexecuted instantiation: nsDisplayHeaderFooter::Name() const
Unexecuted instantiation: nsDisplayText::Name() const
Unexecuted instantiation: nsDisplayVideo::Name() const
Unexecuted instantiation: nsDisplayButtonBoxShadowOuter::Name() const
Unexecuted instantiation: nsDisplayButtonBorder::Name() const
Unexecuted instantiation: nsDisplayButtonForeground::Name() const
Unexecuted instantiation: nsDisplayComboboxFocus::Name() const
Unexecuted instantiation: nsDisplayFieldSetBorder::Name() const
Unexecuted instantiation: nsDisplayRangeFocusRing::Name() const
Unexecuted instantiation: nsDisplayOptionEventGrabber::Name() const
Unexecuted instantiation: nsDisplayListFocus::Name() const
Unexecuted instantiation: nsDisplayTableCellBackground::Name() const
Unexecuted instantiation: nsDisplayTableBorderCollapse::Name() const
Unexecuted instantiation: nsDisplayTableCellSelection::Name() const
Unexecuted instantiation: mozilla::SVGCharClipDisplayItem::Name() const
Unexecuted instantiation: nsDisplaySVGGeometry::Name() const
Unexecuted instantiation: nsDisplaySVGText::Name() const
Unexecuted instantiation: nsDisplayOuterSVG::Name() const
Unexecuted instantiation: nsDisplayXULEventRedirector::Name() const
Unexecuted instantiation: nsDisplayXULGroupBorder::Name() const
Unexecuted instantiation: nsDisplayXULImage::Name() const
Unexecuted instantiation: nsDisplayXULTextBox::Name() const
Unexecuted instantiation: nsDisplayXULTreeColSplitterTarget::Name() const
Unexecuted instantiation: nsDisplayTreeBody::Name() const
Unexecuted instantiation: nsDisplayMathMLSelectionRect::Name() const
Unexecuted instantiation: nsDisplayMathMLError::Name() const
Unexecuted instantiation: nsDisplayMathMLBar::Name() const
Unexecuted instantiation: nsDisplayNotation::Name() const
Unexecuted instantiation: nsDisplayMathMLSlash::Name() const
Unexecuted instantiation: nsDisplayMathMLCharForeground::Name() const
135
0
  DisplayItemType GetType() const override { return DisplayItemType::e; }      \
Unexecuted instantiation: nsDisplayCaret::GetType() const
Unexecuted instantiation: nsDisplayBorder::GetType() const
Unexecuted instantiation: nsDisplaySolidColor::GetType() const
Unexecuted instantiation: nsDisplaySolidColorRegion::GetType() const
Unexecuted instantiation: nsDisplayBackgroundImage::GetType() const
Unexecuted instantiation: nsDisplayTableBackgroundImage::GetType() const
Unexecuted instantiation: nsDisplayThemedBackground::GetType() const
Unexecuted instantiation: nsDisplayTableThemedBackground::GetType() const
Unexecuted instantiation: nsDisplayBackgroundColor::GetType() const
Unexecuted instantiation: nsDisplayTableBackgroundColor::GetType() const
Unexecuted instantiation: nsDisplayClearBackground::GetType() const
Unexecuted instantiation: nsDisplayBoxShadowOuter::GetType() const
Unexecuted instantiation: nsDisplayBoxShadowInner::GetType() const
Unexecuted instantiation: nsDisplayOutline::GetType() const
Unexecuted instantiation: nsDisplayEventReceiver::GetType() const
Unexecuted instantiation: nsDisplayCompositorHitTestInfo::GetType() const
Unexecuted instantiation: nsDisplayWrapList::GetType() const
Unexecuted instantiation: nsDisplayOpacity::GetType() const
Unexecuted instantiation: nsDisplayBlendMode::GetType() const
Unexecuted instantiation: nsDisplayTableBlendMode::GetType() const
Unexecuted instantiation: nsDisplayBlendContainer::GetType() const
Unexecuted instantiation: nsDisplayTableBlendContainer::GetType() const
Unexecuted instantiation: nsDisplayOwnLayer::GetType() const
Unexecuted instantiation: nsDisplaySubDocument::GetType() const
Unexecuted instantiation: nsDisplayResolution::GetType() const
Unexecuted instantiation: nsDisplayStickyPosition::GetType() const
Unexecuted instantiation: nsDisplayFixedPosition::GetType() const
Unexecuted instantiation: nsDisplayTableFixedPosition::GetType() const
Unexecuted instantiation: nsDisplayScrollInfoLayer::GetType() const
Unexecuted instantiation: nsDisplayZoom::GetType() const
Unexecuted instantiation: nsDisplayMask::GetType() const
Unexecuted instantiation: nsDisplayFilter::GetType() const
Unexecuted instantiation: nsDisplayTransform::GetType() const
Unexecuted instantiation: nsDisplayPerspective::GetType() const
Unexecuted instantiation: nsDisplaySVGWrapper::GetType() const
Unexecuted instantiation: nsDisplayForeignObject::GetType() const
Unexecuted instantiation: nsDisplayCanvasBackgroundColor::GetType() const
Unexecuted instantiation: nsDisplayCanvasBackgroundImage::GetType() const
Unexecuted instantiation: nsDisplayCanvasThemedBackground::GetType() const
Unexecuted instantiation: nsDisplayImage::GetType() const
Unexecuted instantiation: nsDisplayPlugin::GetType() const
Unexecuted instantiation: nsDisplayPluginReadback::GetType() const
Unexecuted instantiation: mozilla::css::nsDisplayTextOverflowMarker::GetType() const
Unexecuted instantiation: nsDisplayBullet::GetType() const
Unexecuted instantiation: nsDisplayColumnRule::GetType() const
Unexecuted instantiation: nsDisplaySelectionOverlay::GetType() const
Unexecuted instantiation: nsDisplayCanvasFocus::GetType() const
Unexecuted instantiation: nsDisplayFramesetBorder::GetType() const
Unexecuted instantiation: nsDisplayFramesetBlank::GetType() const
Unexecuted instantiation: nsDisplayCanvas::GetType() const
Unexecuted instantiation: nsDisplayAltFeedback::GetType() const
Unexecuted instantiation: nsDisplayHeaderFooter::GetType() const
Unexecuted instantiation: nsDisplayText::GetType() const
Unexecuted instantiation: nsDisplayVideo::GetType() const
Unexecuted instantiation: nsDisplayButtonBoxShadowOuter::GetType() const
Unexecuted instantiation: nsDisplayButtonBorder::GetType() const
Unexecuted instantiation: nsDisplayButtonForeground::GetType() const
Unexecuted instantiation: nsDisplayComboboxFocus::GetType() const
Unexecuted instantiation: nsDisplayFieldSetBorder::GetType() const
Unexecuted instantiation: nsDisplayRangeFocusRing::GetType() const
Unexecuted instantiation: nsDisplayOptionEventGrabber::GetType() const
Unexecuted instantiation: nsDisplayListFocus::GetType() const
Unexecuted instantiation: nsDisplayTableCellBackground::GetType() const
Unexecuted instantiation: nsDisplayTableBorderCollapse::GetType() const
Unexecuted instantiation: nsDisplayTableCellSelection::GetType() const
Unexecuted instantiation: mozilla::SVGCharClipDisplayItem::GetType() const
Unexecuted instantiation: nsDisplaySVGGeometry::GetType() const
Unexecuted instantiation: nsDisplaySVGText::GetType() const
Unexecuted instantiation: nsDisplayOuterSVG::GetType() const
Unexecuted instantiation: nsDisplayXULEventRedirector::GetType() const
Unexecuted instantiation: nsDisplayXULGroupBorder::GetType() const
Unexecuted instantiation: nsDisplayXULImage::GetType() const
Unexecuted instantiation: nsDisplayXULTextBox::GetType() const
Unexecuted instantiation: nsDisplayXULTreeColSplitterTarget::GetType() const
Unexecuted instantiation: nsDisplayTreeBody::GetType() const
Unexecuted instantiation: nsDisplayMathMLSelectionRect::GetType() const
Unexecuted instantiation: nsDisplayMathMLError::GetType() const
Unexecuted instantiation: nsDisplayMathMLBar::GetType() const
Unexecuted instantiation: nsDisplayNotation::GetType() const
Unexecuted instantiation: nsDisplayMathMLSlash::GetType() const
Unexecuted instantiation: nsDisplayMathMLCharForeground::GetType() const
136
                                                                               \
137
private:                                                                       \
138
  void* operator new(size_t aSize, nsDisplayListBuilder* aBuilder)             \
139
0
  {                                                                            \
140
0
    return aBuilder->Allocate(aSize, DisplayItemType::e);                      \
141
0
  }                                                                            \
Unexecuted instantiation: nsDisplayCaret::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayBorder::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplaySolidColor::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplaySolidColorRegion::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayBackgroundImage::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayTableBackgroundImage::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayThemedBackground::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayTableThemedBackground::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayBackgroundColor::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayTableBackgroundColor::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayClearBackground::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayBoxShadowOuter::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayBoxShadowInner::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayOutline::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayEventReceiver::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayCompositorHitTestInfo::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayWrapList::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayOpacity::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayBlendMode::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayTableBlendMode::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayBlendContainer::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayTableBlendContainer::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayOwnLayer::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplaySubDocument::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayResolution::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayStickyPosition::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayFixedPosition::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayTableFixedPosition::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayScrollInfoLayer::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayZoom::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayMask::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayFilter::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayTransform::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayPerspective::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplaySVGWrapper::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayForeignObject::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayCanvasBackgroundColor::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayCanvasBackgroundImage::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayCanvasThemedBackground::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayImage::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayPlugin::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayPluginReadback::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: mozilla::css::nsDisplayTextOverflowMarker::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayBullet::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayCanvasFocus::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayColumnRule::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplaySelectionOverlay::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayFramesetBorder::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayFramesetBlank::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayCanvas::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayAltFeedback::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayHeaderFooter::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayText::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayVideo::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayButtonBoxShadowOuter::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayButtonBorder::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayButtonForeground::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayComboboxFocus::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayFieldSetBorder::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayRangeFocusRing::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayOptionEventGrabber::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayListFocus::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayTableCellSelection::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayTableBorderCollapse::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayTableCellBackground::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplaySVGGeometry::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplaySVGText::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: mozilla::SVGCharClipDisplayItem::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayOuterSVG::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayXULEventRedirector::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayXULGroupBorder::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayXULImage::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayXULTextBox::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayTreeBody::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayXULTreeColSplitterTarget::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayMathMLSelectionRect::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayMathMLCharForeground::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayMathMLError::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayMathMLBar::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayNotation::operator new(unsigned long, nsDisplayListBuilder*)
Unexecuted instantiation: nsDisplayMathMLSlash::operator new(unsigned long, nsDisplayListBuilder*)
142
  template<typename T, typename... Args>                                       \
143
  friend T* ::MakeDisplayItem(nsDisplayListBuilder* aBuilder,                  \
144
                              Args&&... aArgs);                                \
145
                                                                               \
146
public:
147
148
/**
149
 * Represents a frame that is considered to have (or will have) "animated
150
 * geometry" for itself and descendant frames.
151
 *
152
 * For example the scrolled frames of scrollframes which are actively being
153
 * scrolled fall into this category. Frames with certain CSS properties that are
154
 * being animated (e.g. 'left'/'top' etc) are also placed in this category.
155
 * Frames with different active geometry roots are in different PaintedLayers,
156
 * so that we can animate the geometry root by changing its transform (either on
157
 * the main thread or in the compositor).
158
 *
159
 * nsDisplayListBuilder constructs a tree of these (for fast traversals) and
160
 * assigns one for each display item.
161
 *
162
 * The animated geometry root for a display item is required to be a descendant
163
 * (or equal to) the item's ReferenceFrame(), which means that we will fall back
164
 * to returning aItem->ReferenceFrame() when we can't find another animated
165
 * geometry root.
166
 *
167
 * The animated geometry root isn't strongly defined for a frame as transforms
168
 * and background-attachment:fixed can cause it to vary between display items
169
 * for a given frame.
170
 */
171
struct AnimatedGeometryRoot
172
{
173
  static already_AddRefed<AnimatedGeometryRoot> CreateAGRForFrame(
174
    nsIFrame* aFrame,
175
    AnimatedGeometryRoot* aParent,
176
    bool aIsAsync,
177
    bool aIsRetained)
178
0
  {
179
0
    RefPtr<AnimatedGeometryRoot> result;
180
0
    if (aIsRetained) {
181
0
      result = aFrame->GetProperty(AnimatedGeometryRootCache());
182
0
    }
183
0
184
0
    if (result) {
185
0
      result->mParentAGR = aParent;
186
0
      result->mIsAsync = aIsAsync;
187
0
    } else {
188
0
      result = new AnimatedGeometryRoot(aFrame, aParent, aIsAsync, aIsRetained);
189
0
    }
190
0
    return result.forget();
191
0
  }
192
193
0
  operator nsIFrame*() { return mFrame; }
194
195
0
  nsIFrame* operator->() const { return mFrame; }
196
197
  AnimatedGeometryRoot* GetAsyncAGR()
198
0
  {
199
0
    AnimatedGeometryRoot* agr = this;
200
0
    while (!agr->mIsAsync && agr->mParentAGR) {
201
0
      agr = agr->mParentAGR;
202
0
    }
203
0
    return agr;
204
0
  }
205
206
  NS_INLINE_DECL_REFCOUNTING(AnimatedGeometryRoot)
207
208
  nsIFrame* mFrame;
209
  RefPtr<AnimatedGeometryRoot> mParentAGR;
210
  bool mIsAsync;
211
  bool mIsRetained;
212
213
protected:
214
  static void DetachAGR(AnimatedGeometryRoot* aAGR)
215
0
  {
216
0
    aAGR->mFrame = nullptr;
217
0
    aAGR->mParentAGR = nullptr;
218
0
    NS_RELEASE(aAGR);
219
0
  }
220
221
  NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(AnimatedGeometryRootCache,
222
                                      AnimatedGeometryRoot,
223
                                      DetachAGR)
224
225
  AnimatedGeometryRoot(nsIFrame* aFrame,
226
                       AnimatedGeometryRoot* aParent,
227
                       bool aIsAsync,
228
                       bool aIsRetained)
229
    : mFrame(aFrame)
230
    , mParentAGR(aParent)
231
    , mIsAsync(aIsAsync)
232
    , mIsRetained(aIsRetained)
233
0
  {
234
0
    MOZ_ASSERT(mParentAGR || mIsAsync,
235
0
               "The root AGR should always be treated as an async AGR.");
236
0
    if (mIsRetained) {
237
0
      NS_ADDREF(this);
238
0
      aFrame->SetProperty(AnimatedGeometryRootCache(), this);
239
0
    }
240
0
  }
241
242
  ~AnimatedGeometryRoot()
243
0
  {
244
0
    if (mFrame && mIsRetained) {
245
0
      mFrame->DeleteProperty(AnimatedGeometryRootCache());
246
0
    }
247
0
  }
248
};
249
250
namespace mozilla {
251
252
/**
253
 * An active scrolled root (ASR) is similar to an animated geometry root (AGR).
254
 * The differences are:
255
 *  - ASRs are only created for async-scrollable scroll frames. This is a
256
 *    (hopefully) temporary restriction. In the future we will want to create
257
 *    ASRs for all the things that are currently creating AGRs, and then
258
 *    replace AGRs with ASRs and rename them from "active scrolled root" to
259
 *    "animated geometry root".
260
 *  - ASR objects are created during display list construction by the nsIFrames
261
 *    that induce ASRs. This is done using AutoCurrentActiveScrolledRootSetter.
262
 *    The current ASR is returned by
263
 *    nsDisplayListBuilder::CurrentActiveScrolledRoot().
264
 *  - There is no way to go from an nsIFrame pointer to the ASR of that frame.
265
 *    If you need to look up an ASR after display list construction, you need
266
 *    to store it while the AutoCurrentActiveScrolledRootSetter that creates it
267
 *    is on the stack.
268
 */
269
struct ActiveScrolledRoot
270
{
271
  static already_AddRefed<ActiveScrolledRoot> CreateASRForFrame(
272
    const ActiveScrolledRoot* aParent,
273
    nsIScrollableFrame* aScrollableFrame,
274
    bool aIsRetained)
275
0
  {
276
0
    nsIFrame* f = do_QueryFrame(aScrollableFrame);
277
0
278
0
    RefPtr<ActiveScrolledRoot> asr;
279
0
    if (aIsRetained) {
280
0
      asr = f->GetProperty(ActiveScrolledRootCache());
281
0
    }
282
0
283
0
    if (!asr) {
284
0
      asr = new ActiveScrolledRoot();
285
0
286
0
      if (aIsRetained) {
287
0
        RefPtr<ActiveScrolledRoot> ref = asr;
288
0
        f->SetProperty(ActiveScrolledRootCache(), ref.forget().take());
289
0
      }
290
0
    }
291
0
    asr->mParent = aParent;
292
0
    asr->mScrollableFrame = aScrollableFrame;
293
0
    asr->mViewId = Nothing();
294
0
    asr->mDepth = aParent ? aParent->mDepth + 1 : 1;
295
0
    asr->mRetained = aIsRetained;
296
0
297
0
    return asr.forget();
298
0
  }
299
300
  static const ActiveScrolledRoot* PickAncestor(const ActiveScrolledRoot* aOne,
301
                                                const ActiveScrolledRoot* aTwo)
302
0
  {
303
0
    MOZ_ASSERT(IsAncestor(aOne, aTwo) || IsAncestor(aTwo, aOne));
304
0
    return Depth(aOne) <= Depth(aTwo) ? aOne : aTwo;
305
0
  }
306
307
  static const ActiveScrolledRoot* PickDescendant(
308
    const ActiveScrolledRoot* aOne,
309
    const ActiveScrolledRoot* aTwo)
310
  {
311
    MOZ_ASSERT(IsAncestor(aOne, aTwo) || IsAncestor(aTwo, aOne));
312
    return Depth(aOne) >= Depth(aTwo) ? aOne : aTwo;
313
  }
314
315
  static bool IsAncestor(const ActiveScrolledRoot* aAncestor,
316
                         const ActiveScrolledRoot* aDescendant);
317
318
  static nsCString ToString(
319
    const mozilla::ActiveScrolledRoot* aActiveScrolledRoot);
320
321
  // Call this when inserting an ancestor.
322
0
  void IncrementDepth() { mDepth++; }
323
324
  /**
325
   * Find the view ID (or generate a new one) for the content element
326
   * corresponding to the ASR.
327
   */
328
  mozilla::layers::FrameMetrics::ViewID GetViewId() const
329
  {
330
    if (!mViewId.isSome()) {
331
      nsIContent* content = mScrollableFrame->GetScrolledFrame()->GetContent();
332
      mViewId = Some(nsLayoutUtils::FindOrCreateIDFor(content));
333
    }
334
    return *mViewId;
335
  }
336
337
  RefPtr<const ActiveScrolledRoot> mParent;
338
  nsIScrollableFrame* mScrollableFrame;
339
340
  NS_INLINE_DECL_REFCOUNTING(ActiveScrolledRoot)
341
342
private:
343
  ActiveScrolledRoot()
344
    : mScrollableFrame(nullptr)
345
    , mDepth(0)
346
    , mRetained(false)
347
0
  {
348
0
  }
349
350
  ~ActiveScrolledRoot()
351
0
  {
352
0
    if (mScrollableFrame && mRetained) {
353
0
      nsIFrame* f = do_QueryFrame(mScrollableFrame);
354
0
      f->DeleteProperty(ActiveScrolledRootCache());
355
0
    }
356
0
  }
357
358
  static void DetachASR(ActiveScrolledRoot* aASR)
359
0
  {
360
0
    aASR->mParent = nullptr;
361
0
    aASR->mScrollableFrame = nullptr;
362
0
    NS_RELEASE(aASR);
363
0
  }
364
  NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(ActiveScrolledRootCache,
365
                                      ActiveScrolledRoot,
366
                                      DetachASR)
367
368
  static uint32_t Depth(const ActiveScrolledRoot* aActiveScrolledRoot)
369
  {
370
    return aActiveScrolledRoot ? aActiveScrolledRoot->mDepth : 0;
371
  }
372
373
  // This field is lazily populated in GetViewId(). We don't want to do the
374
  // work of populating if webrender is disabled, because it is often not
375
  // needed.
376
  mutable Maybe<mozilla::layers::FrameMetrics::ViewID> mViewId;
377
378
  uint32_t mDepth;
379
  bool mRetained;
380
};
381
}
382
383
enum class nsDisplayListBuilderMode : uint8_t
384
{
385
  PAINTING,
386
  EVENT_DELIVERY,
387
  PLUGIN_GEOMETRY,
388
  FRAME_VISIBILITY,
389
  TRANSFORM_COMPUTATION,
390
  GENERATE_GLYPH,
391
  PAINTING_SELECTION_BACKGROUND
392
};
393
394
/**
395
 * This manages a display list and is passed as a parameter to
396
 * nsIFrame::BuildDisplayList.
397
 * It contains the parameters that don't change from frame to frame and manages
398
 * the display list memory using an arena. It also establishes the reference
399
 * coordinate system for all display list items. Some of the parameters are
400
 * available from the prescontext/presshell, but we copy them into the builder
401
 * for faster/more convenient access.
402
 */
403
class nsDisplayListBuilder
404
{
405
  typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
406
  typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
407
408
  /**
409
   * This manages status of a 3d context to collect visible rects of
410
   * descendants and passing a dirty rect.
411
   *
412
   * Since some transforms maybe singular, passing visible rects or
413
   * the dirty rect level by level from parent to children may get a
414
   * wrong result, being different from the result of appling with
415
   * effective transform directly.
416
   *
417
   * nsFrame::BuildDisplayListForStackingContext() uses
418
   * AutoPreserves3DContext to install an instance on the builder.
419
   *
420
   * \see AutoAccumulateTransform, AutoAccumulateRect,
421
   *      AutoPreserves3DContext, Accumulate, GetCurrentTransform,
422
   *      StartRoot.
423
   */
424
  class Preserves3DContext
425
  {
426
  public:
427
    typedef mozilla::gfx::Matrix4x4 Matrix4x4;
428
429
    Preserves3DContext()
430
      : mAccumulatedRectLevels(0)
431
0
    {
432
0
    }
433
434
    Preserves3DContext(const Preserves3DContext& aOther)
435
      : mAccumulatedTransform()
436
      , mAccumulatedRect()
437
      , mAccumulatedRectLevels(0)
438
      , mVisibleRect(aOther.mVisibleRect)
439
0
    {
440
0
    }
441
442
    // Accmulate transforms of ancestors on the preserves-3d chain.
443
    Matrix4x4 mAccumulatedTransform;
444
    // Accmulate visible rect of descendants in the preserves-3d context.
445
    nsRect mAccumulatedRect;
446
    // How far this frame is from the root of the current 3d context.
447
    int mAccumulatedRectLevels;
448
    nsRect mVisibleRect;
449
  };
450
451
  /**
452
   * A frame can be in one of three states of AGR.
453
   * AGR_NO     means the frame is not an AGR for now.
454
   * AGR_YES    means the frame is an AGR for now.
455
   * AGR_MAYBE  means the frame is not an AGR for now, but a transition
456
   *            to AGR_YES without restyling is possible.
457
   */
458
  enum AGRState
459
  {
460
    AGR_NO,
461
    AGR_YES,
462
    AGR_MAYBE
463
  };
464
465
public:
466
  typedef mozilla::FrameLayerBuilder FrameLayerBuilder;
467
  typedef mozilla::DisplayItemClip DisplayItemClip;
468
  typedef mozilla::DisplayItemClipChain DisplayItemClipChain;
469
  typedef mozilla::DisplayItemClipChainHasher DisplayItemClipChainHasher;
470
  typedef mozilla::DisplayItemClipChainEqualer DisplayItemClipChainEqualer;
471
  typedef mozilla::DisplayListClipState DisplayListClipState;
472
  typedef mozilla::ActiveScrolledRoot ActiveScrolledRoot;
473
  typedef nsIWidget::ThemeGeometry ThemeGeometry;
474
  typedef mozilla::layers::Layer Layer;
475
  typedef mozilla::layers::FrameMetrics FrameMetrics;
476
  typedef mozilla::layers::FrameMetrics::ViewID ViewID;
477
  typedef mozilla::gfx::Matrix4x4 Matrix4x4;
478
  typedef mozilla::Maybe<mozilla::layers::ScrollDirection> MaybeScrollDirection;
479
480
  /**
481
   * @param aReferenceFrame the frame at the root of the subtree; its origin
482
   * is the origin of the reference coordinate system for this display list
483
   * @param aMode encodes what the builder is being used for.
484
   * @param aBuildCaret whether or not we should include the caret in any
485
   * display lists that we make.
486
   */
487
  nsDisplayListBuilder(nsIFrame* aReferenceFrame,
488
                       nsDisplayListBuilderMode aMode,
489
                       bool aBuildCaret,
490
                       bool aRetainingDisplayList = false);
491
  ~nsDisplayListBuilder();
492
493
  void BeginFrame();
494
  void EndFrame();
495
496
  void AddTemporaryItem(nsDisplayItem* aItem)
497
0
  {
498
0
    mTemporaryItems.AppendElement(aItem);
499
0
  }
500
501
  void SetWillComputePluginGeometry(bool aWillComputePluginGeometry)
502
0
  {
503
0
    mWillComputePluginGeometry = aWillComputePluginGeometry;
504
0
  }
505
506
  void SetForPluginGeometry(bool aForPlugin)
507
0
  {
508
0
    if (aForPlugin) {
509
0
      NS_ASSERTION(mMode == nsDisplayListBuilderMode::PAINTING,
510
0
                   "Can only switch from PAINTING to PLUGIN_GEOMETRY");
511
0
      NS_ASSERTION(mWillComputePluginGeometry,
512
0
                   "Should have signalled this in advance");
513
0
      mMode = nsDisplayListBuilderMode::PLUGIN_GEOMETRY;
514
0
    } else {
515
0
      NS_ASSERTION(mMode == nsDisplayListBuilderMode::PLUGIN_GEOMETRY,
516
0
                   "Can only switch from PAINTING to PLUGIN_GEOMETRY");
517
0
      mMode = nsDisplayListBuilderMode::PAINTING;
518
0
    }
519
0
  }
520
521
  mozilla::layers::LayerManager* GetWidgetLayerManager(
522
    nsView** aView = nullptr);
523
524
  /**
525
   * @return true if the display is being built in order to determine which
526
   * frame is under the mouse position.
527
   */
528
  bool IsForEventDelivery() const
529
0
  {
530
0
    return mMode == nsDisplayListBuilderMode::EVENT_DELIVERY;
531
0
  }
532
533
  /**
534
   * Be careful with this. The display list will be built in PAINTING mode
535
   * first and then switched to PLUGIN_GEOMETRY before a second call to
536
   * ComputeVisibility.
537
   * @return true if the display list is being built to compute geometry
538
   * for plugins.
539
   */
540
  bool IsForPluginGeometry() const
541
0
  {
542
0
    return mMode == nsDisplayListBuilderMode::PLUGIN_GEOMETRY;
543
0
  }
544
545
  /**
546
   * @return true if the display list is being built for painting.
547
   */
548
  bool IsForPainting() const
549
0
  {
550
0
    return mMode == nsDisplayListBuilderMode::PAINTING;
551
0
  }
552
553
  /**
554
   * @return true if the display list is being built for determining frame
555
   * visibility.
556
   */
557
  bool IsForFrameVisibility() const
558
0
  {
559
0
    return mMode == nsDisplayListBuilderMode::FRAME_VISIBILITY;
560
0
  }
561
562
  /**
563
   * @return true if the display list is being built for creating the glyph
564
   * mask from text items.
565
   */
566
  bool IsForGenerateGlyphMask() const
567
0
  {
568
0
    return mMode == nsDisplayListBuilderMode::GENERATE_GLYPH;
569
0
  }
570
571
  /**
572
   * @return true if the display list is being built for painting selection
573
   * background.
574
   */
575
  bool IsForPaintingSelectionBG() const
576
0
  {
577
0
    return mMode == nsDisplayListBuilderMode::PAINTING_SELECTION_BACKGROUND;
578
0
  }
579
580
  bool BuildCompositorHitTestInfo() const
581
0
  {
582
0
    return mBuildCompositorHitTestInfo;
583
0
  }
584
585
0
  bool WillComputePluginGeometry() const { return mWillComputePluginGeometry; }
586
587
  /**
588
   * @return true if "painting is suppressed" during page load and we
589
   * should paint only the background of the document.
590
   */
591
  bool IsBackgroundOnly()
592
0
  {
593
0
    NS_ASSERTION(mPresShellStates.Length() > 0,
594
0
                 "don't call this if we're not in a presshell");
595
0
    return CurrentPresShellState()->mIsBackgroundOnly;
596
0
  }
597
  /**
598
   * @return true if the currently active BuildDisplayList call is being
599
   * applied to a frame at the root of a pseudo stacking context. A pseudo
600
   * stacking context is either a real stacking context or basically what
601
   * CSS2.1 appendix E refers to with "treat the element as if it created
602
   * a new stacking context
603
   */
604
  bool IsAtRootOfPseudoStackingContext() const
605
0
  {
606
0
    return mIsAtRootOfPseudoStackingContext;
607
0
  }
608
609
  /**
610
   * @return the selection that painting should be restricted to (or nullptr
611
   * in the normal unrestricted case)
612
   */
613
0
  mozilla::dom::Selection* GetBoundingSelection() { return mBoundingSelection; }
614
615
  /**
616
   * @return the root of given frame's (sub)tree, whose origin
617
   * establishes the coordinate system for the child display items.
618
   */
619
  const nsIFrame* FindReferenceFrameFor(const nsIFrame* aFrame,
620
                                        nsPoint* aOffset = nullptr) const;
621
622
  /**
623
   * @return the root of the display list's frame (sub)tree, whose origin
624
   * establishes the coordinate system for the display list
625
   */
626
0
  nsIFrame* RootReferenceFrame() const { return mReferenceFrame; }
627
628
  /**
629
   * @return a point pt such that adding pt to a coordinate relative to aFrame
630
   * makes it relative to ReferenceFrame(), i.e., returns
631
   * aFrame->GetOffsetToCrossDoc(ReferenceFrame()). The returned point is in
632
   * the appunits of aFrame.
633
   */
634
  const nsPoint ToReferenceFrame(const nsIFrame* aFrame) const
635
0
  {
636
0
    nsPoint result;
637
0
    FindReferenceFrameFor(aFrame, &result);
638
0
    return result;
639
0
  }
640
  /**
641
   * When building the display list, the scrollframe aFrame will be "ignored"
642
   * for the purposes of clipping, and its scrollbars will be hidden. We use
643
   * this to allow RenderOffscreen to render a whole document without beign
644
   * clipped by the viewport or drawing the viewport scrollbars.
645
   */
646
0
  void SetIgnoreScrollFrame(nsIFrame* aFrame) { mIgnoreScrollFrame = aFrame; }
647
  /**
648
   * Get the scrollframe to ignore, if any.
649
   */
650
0
  nsIFrame* GetIgnoreScrollFrame() { return mIgnoreScrollFrame; }
651
  /**
652
   * Get the ViewID of the nearest scrolling ancestor frame.
653
   */
654
0
  ViewID GetCurrentScrollParentId() const { return mCurrentScrollParentId; }
655
  /**
656
   * Get and set the flag that indicates if scroll parents should have layers
657
   * forcibly created. This flag is set when a deeply nested scrollframe has
658
   * a displayport, and for scroll handoff to work properly the ancestor
659
   * scrollframes should also get their own scrollable layers.
660
   */
661
0
  void ForceLayerForScrollParent() { mForceLayerForScrollParent = true; }
662
  /**
663
   * Get the ViewID and the scrollbar flags corresponding to the scrollbar for
664
   * which we are building display items at the moment.
665
   */
666
0
  ViewID GetCurrentScrollbarTarget() const { return mCurrentScrollbarTarget; }
667
  MaybeScrollDirection GetCurrentScrollbarDirection() const
668
0
  {
669
0
    return mCurrentScrollbarDirection;
670
0
  }
671
  /**
672
   * Returns true if building a scrollbar, and the scrollbar will not be
673
   * layerized.
674
   */
675
  bool IsBuildingNonLayerizedScrollbar() const
676
0
  {
677
0
    return mIsBuildingScrollbar && !mCurrentScrollbarWillHaveLayer;
678
0
  }
679
  /**
680
   * Calling this setter makes us include all out-of-flow descendant
681
   * frames in the display list, wherever they may be positioned (even
682
   * outside the dirty rects).
683
   */
684
0
  void SetIncludeAllOutOfFlows() { mIncludeAllOutOfFlows = true; }
685
0
  bool GetIncludeAllOutOfFlows() const { return mIncludeAllOutOfFlows; }
686
  /**
687
   * Calling this setter makes us exclude all leaf frames that aren't
688
   * selected.
689
   */
690
0
  void SetSelectedFramesOnly() { mSelectedFramesOnly = true; }
691
0
  bool GetSelectedFramesOnly() { return mSelectedFramesOnly; }
692
  /**
693
   * Calling this setter makes us compute accurate visible regions at the cost
694
   * of performance if regions get very complex.
695
   */
696
  bool GetAccurateVisibleRegions()
697
0
  {
698
0
    return mMode == nsDisplayListBuilderMode::PLUGIN_GEOMETRY;
699
0
  }
700
  /**
701
   * @return Returns true if we should include the caret in any display lists
702
   * that we make.
703
   */
704
0
  bool IsBuildingCaret() const { return mBuildCaret; }
705
706
0
  bool IsRetainingDisplayList() const { return mRetainingDisplayList; }
707
708
0
  bool IsPartialUpdate() const { return mPartialUpdate; }
709
0
  void SetPartialUpdate(bool aPartial) { mPartialUpdate = aPartial; }
710
711
0
  bool IsBuilding() const { return mIsBuilding; }
712
  void SetIsBuilding(bool aIsBuilding)
713
0
  {
714
0
    mIsBuilding = aIsBuilding;
715
0
    for (nsIFrame* f : mModifiedFramesDuringBuilding) {
716
0
      f->SetFrameIsModified(false);
717
0
    }
718
0
    mModifiedFramesDuringBuilding.Clear();
719
0
  }
720
721
0
  bool InInvalidSubtree() const { return mInInvalidSubtree; }
722
723
  /**
724
   * Allows callers to selectively override the regular paint suppression
725
   * checks, so that methods like GetFrameForPoint work when painting is
726
   * suppressed.
727
   */
728
0
  void IgnorePaintSuppression() { mIgnoreSuppression = true; }
729
  /**
730
   * @return Returns if this builder will ignore paint suppression.
731
   */
732
0
  bool IsIgnoringPaintSuppression() { return mIgnoreSuppression; }
733
  /**
734
   * Call this if we're doing normal painting to the window.
735
   */
736
0
  void SetPaintingToWindow(bool aToWindow) { mIsPaintingToWindow = aToWindow; }
737
  bool IsPaintingToWindow() const { return mIsPaintingToWindow; }
738
  /**
739
   * Call this to prevent descending into subdocuments.
740
   */
741
  void SetDescendIntoSubdocuments(bool aDescend)
742
0
  {
743
0
    mDescendIntoSubdocuments = aDescend;
744
0
  }
745
746
0
  bool GetDescendIntoSubdocuments() { return mDescendIntoSubdocuments; }
747
748
  /**
749
   * Get dirty rect relative to current frame (the frame that we're calling
750
   * BuildDisplayList on right now).
751
   */
752
0
  const nsRect& GetVisibleRect() { return mVisibleRect; }
753
0
  const nsRect& GetDirtyRect() { return mDirtyRect; }
754
755
  void SetVisibleRect(const nsRect& aVisibleRect)
756
0
  {
757
0
    mVisibleRect = aVisibleRect;
758
0
  }
759
760
  void IntersectVisibleRect(const nsRect& aVisibleRect)
761
0
  {
762
0
    mVisibleRect.IntersectRect(mVisibleRect, aVisibleRect);
763
0
  }
764
765
0
  void SetDirtyRect(const nsRect& aDirtyRect) { mDirtyRect = aDirtyRect; }
766
767
  void IntersectDirtyRect(const nsRect& aDirtyRect)
768
0
  {
769
0
    mDirtyRect.IntersectRect(mDirtyRect, aDirtyRect);
770
0
  }
771
772
  const nsIFrame* GetCurrentFrame() { return mCurrentFrame; }
773
0
  const nsIFrame* GetCurrentReferenceFrame() { return mCurrentReferenceFrame; }
774
775
  const nsPoint& GetCurrentFrameOffsetToReferenceFrame()
776
0
  {
777
0
    return mCurrentOffsetToReferenceFrame;
778
0
  }
779
780
  AnimatedGeometryRoot* GetCurrentAnimatedGeometryRoot() { return mCurrentAGR; }
781
0
  AnimatedGeometryRoot* GetRootAnimatedGeometryRoot() { return mRootAGR; }
782
783
  void RecomputeCurrentAnimatedGeometryRoot();
784
785
0
  void Check() { mPool.Check(); }
786
787
  /**
788
   * Returns true if merging and flattening of display lists should be
789
   * performed while computing visibility.
790
   */
791
  bool AllowMergingAndFlattening() { return mAllowMergingAndFlattening; }
792
  void SetAllowMergingAndFlattening(bool aAllow)
793
0
  {
794
0
    mAllowMergingAndFlattening = aAllow;
795
0
  }
796
797
  /**
798
   * Sets the current compositor hit test info to |aHitTestInfo|.
799
   * This is used during display list building to determine if the parent frame
800
   * hit test info contains the same information that child frame needs.
801
   */
802
  void SetCompositorHitTestInfo(nsDisplayCompositorHitTestInfo* aHitTestInfo)
803
0
  {
804
0
    mCompositorHitTestInfo = aHitTestInfo;
805
0
  }
806
807
  nsDisplayCompositorHitTestInfo* GetCompositorHitTestInfo() const
808
0
  {
809
0
    return mCompositorHitTestInfo;
810
0
  }
811
812
  /**
813
   * Builds a new nsDisplayCompositorHitTestInfo for the frame |aFrame| if
814
   * needed, and adds it to the top of |aList|. If |aBuildNew| is true, the
815
   * previous hit test info will not be reused.
816
   */
817
  void BuildCompositorHitTestInfoIfNeeded(nsIFrame* aFrame,
818
                                          nsDisplayList* aList,
819
                                          const bool aBuildNew);
820
821
  bool IsInsidePointerEventsNoneDoc()
822
0
  {
823
0
    return CurrentPresShellState()->mInsidePointerEventsNoneDoc;
824
0
  }
825
826
  bool GetAncestorHasApzAwareEventHandler() const
827
0
  {
828
0
    return mAncestorHasApzAwareEventHandler;
829
0
  }
830
831
  void SetAncestorHasApzAwareEventHandler(bool aValue)
832
0
  {
833
0
    mAncestorHasApzAwareEventHandler = aValue;
834
0
  }
835
836
0
  bool HaveScrollableDisplayPort() const { return mHaveScrollableDisplayPort; }
837
0
  void SetHaveScrollableDisplayPort() { mHaveScrollableDisplayPort = true; }
838
0
  void ClearHaveScrollableDisplayPort() { mHaveScrollableDisplayPort = false; }
839
840
  bool SetIsCompositingCheap(bool aCompositingCheap)
841
0
  {
842
0
    bool temp = mIsCompositingCheap;
843
0
    mIsCompositingCheap = aCompositingCheap;
844
0
    return temp;
845
0
  }
846
847
  bool IsCompositingCheap() const { return mIsCompositingCheap; }
848
  /**
849
   * Display the caret if needed.
850
   */
851
  bool DisplayCaret(nsIFrame* aFrame, nsDisplayList* aList)
852
0
  {
853
0
    nsIFrame* frame = GetCaretFrame();
854
0
    if (aFrame == frame) {
855
0
      frame->DisplayCaret(this, aList);
856
0
      return true;
857
0
    }
858
0
    return false;
859
0
  }
860
  /**
861
   * Get the frame that the caret is supposed to draw in.
862
   * If the caret is currently invisible, this will be null.
863
   */
864
0
  nsIFrame* GetCaretFrame() { return CurrentPresShellState()->mCaretFrame; }
865
  /**
866
   * Get the rectangle we're supposed to draw the caret into.
867
   */
868
0
  const nsRect& GetCaretRect() { return CurrentPresShellState()->mCaretRect; }
869
  /**
870
   * Get the caret associated with the current presshell.
871
   */
872
  nsCaret* GetCaret();
873
  /**
874
   * Notify the display list builder that we're entering a presshell.
875
   * aReferenceFrame should be a frame in the new presshell.
876
   * aPointerEventsNoneDoc should be set to true if the frame generating this
877
   * document is pointer-events:none.
878
   */
879
  void EnterPresShell(nsIFrame* aReferenceFrame,
880
                      bool aPointerEventsNoneDoc = false);
881
  /**
882
   * For print-preview documents, we sometimes need to build display items for
883
   * the same frames multiple times in the same presentation, with different
884
   * clipping. Between each such batch of items, call
885
   * ResetMarkedFramesForDisplayList to make sure that the results of
886
   * MarkFramesForDisplayList do not carry over between batches.
887
   */
888
  void ResetMarkedFramesForDisplayList(nsIFrame* aReferenceFrame);
889
  /**
890
   * Notify the display list builder that we're leaving a presshell.
891
   */
892
  void LeavePresShell(nsIFrame* aReferenceFrame,
893
                      nsDisplayList* aPaintedContents);
894
895
  void IncrementPresShellPaintCount(nsIPresShell* aPresShell);
896
897
  /**
898
   * Returns true if we're currently building a display list that's
899
   * directly or indirectly under an nsDisplayTransform.
900
   */
901
0
  bool IsInTransform() const { return mInTransform; }
902
  /**
903
   * Indicate whether or not we're directly or indirectly under and
904
   * nsDisplayTransform or SVG foreignObject.
905
   */
906
0
  void SetInTransform(bool aInTransform) { mInTransform = aInTransform; }
907
908
  /**
909
   * Returns true if we're currently building a display list that's
910
   * under an nsDisplayFilter.
911
   */
912
0
  bool IsInFilter() const { return mInFilter; }
913
914
0
  bool IsInPageSequence() const { return mInPageSequence; }
915
0
  void SetInPageSequence(bool aInPage) { mInPageSequence = aInPage; }
916
917
  /**
918
   * Return true if we're currently building a display list for a
919
   * nested presshell.
920
   */
921
0
  bool IsInSubdocument() { return mPresShellStates.Length() > 1; }
922
923
  void SetDisablePartialUpdates(bool aDisable)
924
0
  {
925
0
    mDisablePartialUpdates = aDisable;
926
0
  }
927
0
  bool DisablePartialUpdates() { return mDisablePartialUpdates; }
928
929
0
  void SetPartialBuildFailed(bool aFailed) { mPartialBuildFailed = aFailed; }
930
0
  bool PartialBuildFailed() { return mPartialBuildFailed; }
931
932
  /**
933
   * Return true if we're currently building a display list for the presshell
934
   * of a chrome document, or if we're building the display list for a popup.
935
   */
936
  bool IsInChromeDocumentOrPopup()
937
0
  {
938
0
    return mIsInChromePresContext || mIsBuildingForPopup;
939
0
  }
940
941
  /**
942
   * @return true if images have been set to decode synchronously.
943
   */
944
  bool ShouldSyncDecodeImages() { return mSyncDecodeImages; }
945
946
  /**
947
   * Indicates whether we should synchronously decode images. If true, we decode
948
   * and draw whatever image data has been loaded. If false, we just draw
949
   * whatever has already been decoded.
950
   */
951
  void SetSyncDecodeImages(bool aSyncDecodeImages)
952
0
  {
953
0
    mSyncDecodeImages = aSyncDecodeImages;
954
0
  }
955
956
  void FreeClipChains();
957
958
  /*
959
   * Frees the temporary display items created during merging.
960
   */
961
  void FreeTemporaryItems();
962
963
  /**
964
   * Helper method to generate background painting flags based on the
965
   * information available in the display list builder. Currently only
966
   * accounts for mSyncDecodeImages.
967
   */
968
  uint32_t GetBackgroundPaintFlags();
969
970
  /**
971
   * Subtracts aRegion from *aVisibleRegion. We avoid letting
972
   * aVisibleRegion become overcomplex by simplifying it if necessary.
973
   */
974
  void SubtractFromVisibleRegion(nsRegion* aVisibleRegion,
975
                                 const nsRegion& aRegion);
976
977
  /**
978
   * Mark the frames in aFrames to be displayed if they intersect aDirtyRect
979
   * (which is relative to aDirtyFrame). If the frames have placeholders
980
   * that might not be displayed, we mark the placeholders and their ancestors
981
   * to ensure that display list construction descends into them
982
   * anyway. nsDisplayListBuilder will take care of unmarking them when it is
983
   * destroyed.
984
   */
985
  void MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
986
                                const nsFrameList& aFrames);
987
  void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame);
988
  void MarkFrameForDisplayIfVisible(nsIFrame* aFrame, nsIFrame* aStopAtFrame);
989
  void AddFrameMarkedForDisplayIfVisible(nsIFrame* aFrame);
990
991
  void ClearFixedBackgroundDisplayData();
992
  /**
993
   * Mark all child frames that Preserve3D() as needing display.
994
   * Because these frames include transforms set on their parent, dirty rects
995
   * for intermediate frames may be empty, yet child frames could still be
996
   * visible.
997
   */
998
  void MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame);
999
1000
  /**
1001
   * Returns true if we need to descend into this frame when building
1002
   * the display list, even though it doesn't intersect the dirty
1003
   * rect, because it may have out-of-flows that do so.
1004
   */
1005
  bool ShouldDescendIntoFrame(nsIFrame* aFrame, bool aVisible) const
1006
0
  {
1007
0
    return (aFrame->GetStateBits() &
1008
0
            NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) ||
1009
0
           (aVisible && aFrame->ForceDescendIntoIfVisible()) ||
1010
0
           GetIncludeAllOutOfFlows();
1011
0
  }
1012
1013
  /**
1014
   * Returns the list of registered theme geometries.
1015
   */
1016
  nsTArray<ThemeGeometry> GetThemeGeometries() const
1017
0
  {
1018
0
    nsTArray<ThemeGeometry> geometries;
1019
0
1020
0
    for (auto iter = mThemeGeometries.ConstIter(); !iter.Done(); iter.Next()) {
1021
0
      geometries.AppendElements(*iter.Data());
1022
0
    }
1023
0
1024
0
    return geometries;
1025
0
  }
1026
1027
  /**
1028
   * Notifies the builder that a particular themed widget exists
1029
   * at the given rectangle within the currently built display list.
1030
   * For certain appearance values (currently only StyleAppearance::Toolbar and
1031
   * StyleAppearance::WindowTitlebar) this gets called during every display list
1032
   * construction, for every themed widget of the right type within the
1033
   * display list, except for themed widgets which are transformed or have
1034
   * effects applied to them (e.g. CSS opacity or filters).
1035
   *
1036
   * @param aWidgetType the -moz-appearance value for the themed widget
1037
   * @param aItem the item associated with the theme geometry
1038
   * @param aRect the device-pixel rect relative to the widget's displayRoot
1039
   * for the themed widget
1040
   */
1041
  void RegisterThemeGeometry(uint8_t aWidgetType,
1042
                             nsDisplayItem* aItem,
1043
                             const mozilla::LayoutDeviceIntRect& aRect)
1044
0
  {
1045
0
    if (!mIsPaintingToWindow) {
1046
0
      return;
1047
0
    }
1048
0
1049
0
    nsTArray<ThemeGeometry>* geometries = mThemeGeometries.LookupOrAdd(aItem);
1050
0
    geometries->AppendElement(ThemeGeometry(aWidgetType, aRect));
1051
0
  }
1052
1053
  /**
1054
   * Removes theme geometries associated with the given display item |aItem|.
1055
   */
1056
  void UnregisterThemeGeometry(nsDisplayItem* aItem)
1057
0
  {
1058
0
    mThemeGeometries.Remove(aItem);
1059
0
  }
1060
1061
  /**
1062
   * Adjusts mWindowDraggingRegion to take into account aFrame. If aFrame's
1063
   * -moz-window-dragging value is |drag|, its border box is added to the
1064
   * collected dragging region; if the value is |no-drag|, the border box is
1065
   * subtracted from the region; if the value is |default|, that frame does
1066
   * not influence the window dragging region.
1067
   */
1068
  void AdjustWindowDraggingRegion(nsIFrame* aFrame);
1069
1070
  LayoutDeviceIntRegion GetWindowDraggingRegion() const;
1071
1072
  void RemoveModifiedWindowRegions();
1073
  void ClearRetainedWindowRegions();
1074
1075
  /**
1076
   * Allocate memory in our arena. It will only be freed when this display list
1077
   * builder is destroyed. This memory holds nsDisplayItems. nsDisplayItem
1078
   * destructors are called as soon as the item is no longer used.
1079
   */
1080
  void* Allocate(size_t aSize, DisplayItemType aType);
1081
1082
  void Destroy(DisplayItemType aType, void* aPtr);
1083
1084
  /**
1085
   * Allocate a new ActiveScrolledRoot in the arena. Will be cleaned up
1086
   * automatically when the arena goes away.
1087
   */
1088
  ActiveScrolledRoot* AllocateActiveScrolledRoot(
1089
    const ActiveScrolledRoot* aParent,
1090
    nsIScrollableFrame* aScrollableFrame);
1091
1092
  /**
1093
   * Allocate a new DisplayItemClipChain object in the arena. Will be cleaned
1094
   * up automatically when the arena goes away.
1095
   */
1096
  const DisplayItemClipChain* AllocateDisplayItemClipChain(
1097
    const DisplayItemClip& aClip,
1098
    const ActiveScrolledRoot* aASR,
1099
    const DisplayItemClipChain* aParent);
1100
1101
  /**
1102
   * Intersect two clip chains, allocating the new clip chain items in this
1103
   * builder's arena. The result is parented to aAncestor, and no intersections
1104
   * happen past aAncestor's ASR.
1105
   * That means aAncestor has to be living in this builder's arena already.
1106
   * aLeafClip1 and aLeafClip2 only need to outlive the call to this function,
1107
   * their values are copied into the newly-allocated intersected clip chain
1108
   * and this function does not hold on to any pointers to them.
1109
   */
1110
  const DisplayItemClipChain* CreateClipChainIntersection(
1111
    const DisplayItemClipChain* aAncestor,
1112
    const DisplayItemClipChain* aLeafClip1,
1113
    const DisplayItemClipChain* aLeafClip2);
1114
1115
  /**
1116
   * Clone the supplied clip chain's chain items into this builder's arena.
1117
   */
1118
  const DisplayItemClipChain* CopyWholeChain(
1119
    const DisplayItemClipChain* aClipChain);
1120
1121
  /**
1122
   * Only used for containerful root scrolling. This is a workaround.
1123
   */
1124
  void SetActiveScrolledRootForRootScrollframe(const ActiveScrolledRoot* aASR)
1125
0
  {
1126
0
    mActiveScrolledRootForRootScrollframe = aASR;
1127
0
  }
1128
1129
  const ActiveScrolledRoot* ActiveScrolledRootForRootScrollframe() const
1130
0
  {
1131
0
    return mActiveScrolledRootForRootScrollframe;
1132
0
  }
1133
1134
  /**
1135
   * Transfer off main thread animations to the layer.  May be called
1136
   * with aBuilder and aItem both null, but only if the caller has
1137
   * already checked that off main thread animations should be sent to
1138
   * the layer.  When they are both null, the animations are added to
1139
   * the layer as pending animations.
1140
   */
1141
  static void AddAnimationsAndTransitionsToLayer(Layer* aLayer,
1142
                                                 nsDisplayListBuilder* aBuilder,
1143
                                                 nsDisplayItem* aItem,
1144
                                                 nsIFrame* aFrame,
1145
                                                 nsCSSPropertyID aProperty);
1146
1147
  /**
1148
   * Merges the display items in |aMergedItems| and returns a new temporary
1149
   * display item.
1150
   * The display items in |aMergedItems| have to be mergeable with each other.
1151
   */
1152
  nsDisplayItem* MergeItems(nsTArray<nsDisplayItem*>& aMergedItems);
1153
1154
  /**
1155
   * A helper class to temporarily set the value of
1156
   * mIsAtRootOfPseudoStackingContext, and temporarily
1157
   * set mCurrentFrame and related state. Also temporarily sets mDirtyRect.
1158
   * aDirtyRect is relative to aForChild.
1159
   */
1160
  class AutoBuildingDisplayList
1161
  {
1162
  public:
1163
    AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder,
1164
                            nsIFrame* aForChild,
1165
                            const nsRect& aVisibleRect,
1166
                            const nsRect& aDirtyRect,
1167
                            bool aIsRoot)
1168
      : mBuilder(aBuilder)
1169
      , mPrevFrame(aBuilder->mCurrentFrame)
1170
      , mPrevReferenceFrame(aBuilder->mCurrentReferenceFrame)
1171
      , mPrevCompositorHitTestInfo(aBuilder->mCompositorHitTestInfo)
1172
      , mPrevOffset(aBuilder->mCurrentOffsetToReferenceFrame)
1173
      , mPrevVisibleRect(aBuilder->mVisibleRect)
1174
      , mPrevDirtyRect(aBuilder->mDirtyRect)
1175
      , mPrevAGR(aBuilder->mCurrentAGR)
1176
      , mPrevIsAtRootOfPseudoStackingContext(
1177
          aBuilder->mIsAtRootOfPseudoStackingContext)
1178
      , mPrevAncestorHasApzAwareEventHandler(
1179
          aBuilder->mAncestorHasApzAwareEventHandler)
1180
      , mPrevBuildingInvisibleItems(aBuilder->mBuildingInvisibleItems)
1181
      , mPrevInInvalidSubtree(aBuilder->mInInvalidSubtree)
1182
0
    {
1183
0
      if (aForChild->IsTransformed()) {
1184
0
        aBuilder->mCurrentOffsetToReferenceFrame = nsPoint();
1185
0
        aBuilder->mCurrentReferenceFrame = aForChild;
1186
0
      } else if (aBuilder->mCurrentFrame == aForChild->GetParent()) {
1187
0
        aBuilder->mCurrentOffsetToReferenceFrame += aForChild->GetPosition();
1188
0
      } else {
1189
0
        aBuilder->mCurrentReferenceFrame = aBuilder->FindReferenceFrameFor(
1190
0
          aForChild, &aBuilder->mCurrentOffsetToReferenceFrame);
1191
0
      }
1192
0
      bool isAsync;
1193
0
      mCurrentAGRState = aBuilder->IsAnimatedGeometryRoot(aForChild, isAsync);
1194
0
      if (aBuilder->mCurrentFrame == aForChild->GetParent()) {
1195
0
        if (mCurrentAGRState == AGR_YES) {
1196
0
          aBuilder->mCurrentAGR = aBuilder->WrapAGRForFrame(
1197
0
            aForChild, isAsync, aBuilder->mCurrentAGR);
1198
0
        }
1199
0
      } else if (aForChild != aBuilder->mCurrentFrame) {
1200
0
        aBuilder->mCurrentAGR =
1201
0
          aBuilder->FindAnimatedGeometryRootFor(aForChild);
1202
0
      }
1203
0
      MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(
1204
0
        aBuilder->RootReferenceFrame(), *aBuilder->mCurrentAGR));
1205
0
      aBuilder->mInInvalidSubtree =
1206
0
        aBuilder->mInInvalidSubtree || aForChild->IsFrameModified();
1207
0
      aBuilder->mCurrentFrame = aForChild;
1208
0
      aBuilder->mVisibleRect = aVisibleRect;
1209
0
      aBuilder->mDirtyRect =
1210
0
        aBuilder->mInInvalidSubtree ? aVisibleRect : aDirtyRect;
1211
0
      aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
1212
0
    }
1213
1214
    void SetReferenceFrameAndCurrentOffset(const nsIFrame* aFrame,
1215
                                           const nsPoint& aOffset)
1216
0
    {
1217
0
      mBuilder->mCurrentReferenceFrame = aFrame;
1218
0
      mBuilder->mCurrentOffsetToReferenceFrame = aOffset;
1219
0
    }
1220
1221
0
    bool IsAnimatedGeometryRoot() const { return mCurrentAGRState == AGR_YES; }
1222
1223
    bool MaybeAnimatedGeometryRoot() const
1224
0
    {
1225
0
      return mCurrentAGRState == AGR_MAYBE;
1226
0
    }
1227
1228
    void RestoreBuildingInvisibleItemsValue()
1229
0
    {
1230
0
      mBuilder->mBuildingInvisibleItems = mPrevBuildingInvisibleItems;
1231
0
    }
1232
1233
    ~AutoBuildingDisplayList()
1234
0
    {
1235
0
      mBuilder->mCurrentFrame = mPrevFrame;
1236
0
      mBuilder->mCurrentReferenceFrame = mPrevReferenceFrame;
1237
0
      mBuilder->mCompositorHitTestInfo = mPrevCompositorHitTestInfo;
1238
0
      mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset;
1239
0
      mBuilder->mVisibleRect = mPrevVisibleRect;
1240
0
      mBuilder->mDirtyRect = mPrevDirtyRect;
1241
0
      mBuilder->mCurrentAGR = mPrevAGR;
1242
0
      mBuilder->mIsAtRootOfPseudoStackingContext =
1243
0
        mPrevIsAtRootOfPseudoStackingContext;
1244
0
      mBuilder->mAncestorHasApzAwareEventHandler =
1245
0
        mPrevAncestorHasApzAwareEventHandler;
1246
0
      mBuilder->mBuildingInvisibleItems = mPrevBuildingInvisibleItems;
1247
0
      mBuilder->mInInvalidSubtree = mPrevInInvalidSubtree;
1248
0
    }
1249
1250
  private:
1251
    nsDisplayListBuilder* mBuilder;
1252
    AGRState mCurrentAGRState;
1253
    const nsIFrame* mPrevFrame;
1254
    const nsIFrame* mPrevReferenceFrame;
1255
    nsDisplayCompositorHitTestInfo* mPrevCompositorHitTestInfo;
1256
    nsPoint mPrevOffset;
1257
    nsRect mPrevVisibleRect;
1258
    nsRect mPrevDirtyRect;
1259
    RefPtr<AnimatedGeometryRoot> mPrevAGR;
1260
    bool mPrevIsAtRootOfPseudoStackingContext;
1261
    bool mPrevAncestorHasApzAwareEventHandler;
1262
    bool mPrevBuildingInvisibleItems;
1263
    bool mPrevInInvalidSubtree;
1264
  };
1265
1266
  /**
1267
   * A helper class to temporarily set the value of mInTransform.
1268
   */
1269
  class AutoInTransformSetter
1270
  {
1271
  public:
1272
    AutoInTransformSetter(nsDisplayListBuilder* aBuilder, bool aInTransform)
1273
      : mBuilder(aBuilder)
1274
      , mOldValue(aBuilder->mInTransform)
1275
0
    {
1276
0
      aBuilder->mInTransform = aInTransform;
1277
0
    }
1278
1279
0
    ~AutoInTransformSetter() { mBuilder->mInTransform = mOldValue; }
1280
1281
  private:
1282
    nsDisplayListBuilder* mBuilder;
1283
    bool mOldValue;
1284
  };
1285
1286
  /**
1287
   * A helper class to temporarily set the value of mFilterASR and
1288
   * mInFilter.
1289
   */
1290
  class AutoEnterFilter
1291
  {
1292
  public:
1293
    AutoEnterFilter(nsDisplayListBuilder* aBuilder, bool aUsingFilter)
1294
      : mBuilder(aBuilder)
1295
      , mOldValue(aBuilder->mFilterASR)
1296
      , mOldInFilter(aBuilder->mInFilter)
1297
0
    {
1298
0
      if (!aBuilder->mFilterASR && aUsingFilter) {
1299
0
        aBuilder->mFilterASR = aBuilder->CurrentActiveScrolledRoot();
1300
0
        aBuilder->mInFilter = true;
1301
0
      }
1302
0
    }
1303
1304
    ~AutoEnterFilter()
1305
0
    {
1306
0
      mBuilder->mFilterASR = mOldValue;
1307
0
      mBuilder->mInFilter = mOldInFilter;
1308
0
    }
1309
1310
  private:
1311
    nsDisplayListBuilder* mBuilder;
1312
    const ActiveScrolledRoot* mOldValue;
1313
    bool mOldInFilter;
1314
  };
1315
1316
  /**
1317
   * A helper class to temporarily set the value of mCurrentScrollParentId.
1318
   */
1319
  class AutoCurrentScrollParentIdSetter
1320
  {
1321
  public:
1322
    AutoCurrentScrollParentIdSetter(nsDisplayListBuilder* aBuilder,
1323
                                    ViewID aScrollId)
1324
      : mBuilder(aBuilder)
1325
      , mOldValue(aBuilder->mCurrentScrollParentId)
1326
      , mOldForceLayer(aBuilder->mForceLayerForScrollParent)
1327
0
    {
1328
0
      // If this AutoCurrentScrollParentIdSetter has the same scrollId as the
1329
0
      // previous one on the stack, then that means the scrollframe that
1330
0
      // created this isn't actually scrollable and cannot participate in
1331
0
      // scroll handoff. We set mCanBeScrollParent to false to indicate this.
1332
0
      mCanBeScrollParent = (mOldValue != aScrollId);
1333
0
      aBuilder->mCurrentScrollParentId = aScrollId;
1334
0
      aBuilder->mForceLayerForScrollParent = false;
1335
0
    }
1336
1337
    bool ShouldForceLayerForScrollParent() const
1338
0
    {
1339
0
      // Only scrollframes participating in scroll handoff can be forced to
1340
0
      // layerize
1341
0
      return mCanBeScrollParent && mBuilder->mForceLayerForScrollParent;
1342
0
    }
1343
1344
    ~AutoCurrentScrollParentIdSetter()
1345
0
    {
1346
0
      mBuilder->mCurrentScrollParentId = mOldValue;
1347
0
      if (mCanBeScrollParent) {
1348
0
        // If this flag is set, caller code is responsible for having dealt
1349
0
        // with the current value of mBuilder->mForceLayerForScrollParent, so
1350
0
        // we can just restore the old value.
1351
0
        mBuilder->mForceLayerForScrollParent = mOldForceLayer;
1352
0
      } else {
1353
0
        // Otherwise we need to keep propagating the force-layerization flag
1354
0
        // upwards to the next ancestor scrollframe that does participate in
1355
0
        // scroll handoff.
1356
0
        mBuilder->mForceLayerForScrollParent |= mOldForceLayer;
1357
0
      }
1358
0
    }
1359
1360
  private:
1361
    nsDisplayListBuilder* mBuilder;
1362
    ViewID mOldValue;
1363
    bool mOldForceLayer;
1364
    bool mCanBeScrollParent;
1365
  };
1366
1367
  /**
1368
   * Used to update the current active scrolled root on the display list
1369
   * builder, and to create new active scrolled roots.
1370
   */
1371
  class AutoCurrentActiveScrolledRootSetter
1372
  {
1373
  public:
1374
    explicit AutoCurrentActiveScrolledRootSetter(nsDisplayListBuilder* aBuilder)
1375
      : mBuilder(aBuilder)
1376
      , mSavedActiveScrolledRoot(aBuilder->mCurrentActiveScrolledRoot)
1377
      , mContentClipASR(aBuilder->ClipState().GetContentClipASR())
1378
      , mDescendantsStartIndex(aBuilder->mActiveScrolledRoots.Length())
1379
      , mUsed(false)
1380
0
    {
1381
0
    }
1382
1383
    ~AutoCurrentActiveScrolledRootSetter()
1384
0
    {
1385
0
      mBuilder->mCurrentActiveScrolledRoot = mSavedActiveScrolledRoot;
1386
0
    }
1387
1388
    void SetCurrentActiveScrolledRoot(
1389
      const ActiveScrolledRoot* aActiveScrolledRoot);
1390
1391
    void EnterScrollFrame(nsIScrollableFrame* aScrollableFrame)
1392
0
    {
1393
0
      MOZ_ASSERT(!mUsed);
1394
0
      ActiveScrolledRoot* asr = mBuilder->AllocateActiveScrolledRoot(
1395
0
        mBuilder->mCurrentActiveScrolledRoot, aScrollableFrame);
1396
0
      mBuilder->mCurrentActiveScrolledRoot = asr;
1397
0
      mUsed = true;
1398
0
    }
1399
1400
    void InsertScrollFrame(nsIScrollableFrame* aScrollableFrame);
1401
1402
  private:
1403
    nsDisplayListBuilder* mBuilder;
1404
    /**
1405
     * The builder's mCurrentActiveScrolledRoot at construction time which
1406
     * needs to be restored at destruction time.
1407
     */
1408
    const ActiveScrolledRoot* mSavedActiveScrolledRoot;
1409
    /**
1410
     * If there's a content clip on the builder at construction time, then
1411
     * mContentClipASR is that content clip's ASR, otherwise null. The
1412
     * assumption is that the content clip doesn't get relaxed while this
1413
     * object is on the stack.
1414
     */
1415
    const ActiveScrolledRoot* mContentClipASR;
1416
    /**
1417
     * InsertScrollFrame needs to mutate existing ASRs (those that were
1418
     * created while this object was on the stack), and mDescendantsStartIndex
1419
     * makes it easier to skip ASRs that were created in the past.
1420
     */
1421
    size_t mDescendantsStartIndex;
1422
    /**
1423
     * Flag to make sure that only one of SetCurrentActiveScrolledRoot /
1424
     * EnterScrollFrame / InsertScrollFrame is called per instance of this
1425
     * class.
1426
     */
1427
    bool mUsed;
1428
  };
1429
1430
  /**
1431
   * Keeps track of the innermost ASR that can be used as the ASR for a
1432
   * container item that wraps all items that were created while this
1433
   * object was on the stack.
1434
   * The rule is: all child items of the container item need to have
1435
   * clipped bounds with respect to the container ASR.
1436
   */
1437
  class AutoContainerASRTracker
1438
  {
1439
  public:
1440
    explicit AutoContainerASRTracker(nsDisplayListBuilder* aBuilder)
1441
      : mBuilder(aBuilder)
1442
      , mSavedContainerASR(aBuilder->mCurrentContainerASR)
1443
0
    {
1444
0
      mBuilder->mCurrentContainerASR = ActiveScrolledRoot::PickDescendant(
1445
0
        mBuilder->ClipState().GetContentClipASR(),
1446
0
        mBuilder->mCurrentActiveScrolledRoot);
1447
0
    }
1448
1449
    const ActiveScrolledRoot* GetContainerASR()
1450
0
    {
1451
0
      return mBuilder->mCurrentContainerASR;
1452
0
    }
1453
1454
    ~AutoContainerASRTracker()
1455
0
    {
1456
0
      mBuilder->mCurrentContainerASR = ActiveScrolledRoot::PickAncestor(
1457
0
        mBuilder->mCurrentContainerASR, mSavedContainerASR);
1458
0
    }
1459
1460
  private:
1461
    nsDisplayListBuilder* mBuilder;
1462
    const ActiveScrolledRoot* mSavedContainerASR;
1463
  };
1464
1465
  /**
1466
   * A helper class to temporarily set the value of mCurrentScrollbarTarget
1467
   * and mCurrentScrollbarFlags.
1468
   */
1469
  class AutoCurrentScrollbarInfoSetter
1470
  {
1471
  public:
1472
    AutoCurrentScrollbarInfoSetter(
1473
      nsDisplayListBuilder* aBuilder,
1474
      ViewID aScrollTargetID,
1475
      const MaybeScrollDirection& aScrollbarDirection,
1476
      bool aWillHaveLayer)
1477
      : mBuilder(aBuilder)
1478
0
    {
1479
0
      aBuilder->mIsBuildingScrollbar = true;
1480
0
      aBuilder->mCurrentScrollbarTarget = aScrollTargetID;
1481
0
      aBuilder->mCurrentScrollbarDirection = aScrollbarDirection;
1482
0
      aBuilder->mCurrentScrollbarWillHaveLayer = aWillHaveLayer;
1483
0
    }
1484
1485
    ~AutoCurrentScrollbarInfoSetter()
1486
0
    {
1487
0
      // No need to restore old values because scrollbars cannot be nested.
1488
0
      mBuilder->mIsBuildingScrollbar = false;
1489
0
      mBuilder->mCurrentScrollbarTarget = FrameMetrics::NULL_SCROLL_ID;
1490
0
      mBuilder->mCurrentScrollbarDirection.reset();
1491
0
      mBuilder->mCurrentScrollbarWillHaveLayer = false;
1492
0
    }
1493
1494
  private:
1495
    nsDisplayListBuilder* mBuilder;
1496
  };
1497
1498
  /**
1499
   * A helper class to track current effective transform for items.
1500
   *
1501
   * For frames that is Combines3DTransformWithAncestors(), we need to
1502
   * apply all transforms of ancestors on the same preserves3D chain
1503
   * on the bounds of current frame to the coordination of the 3D
1504
   * context root.  The 3D context root computes it's bounds from
1505
   * these transformed bounds.
1506
   */
1507
  class AutoAccumulateTransform
1508
  {
1509
  public:
1510
    typedef mozilla::gfx::Matrix4x4 Matrix4x4;
1511
1512
    explicit AutoAccumulateTransform(nsDisplayListBuilder* aBuilder)
1513
      : mBuilder(aBuilder)
1514
      , mSavedTransform(aBuilder->mPreserves3DCtx.mAccumulatedTransform)
1515
0
    {
1516
0
    }
1517
1518
    ~AutoAccumulateTransform()
1519
0
    {
1520
0
      mBuilder->mPreserves3DCtx.mAccumulatedTransform = mSavedTransform;
1521
0
    }
1522
1523
    void Accumulate(const Matrix4x4& aTransform)
1524
0
    {
1525
0
      mBuilder->mPreserves3DCtx.mAccumulatedTransform =
1526
0
        aTransform * mBuilder->mPreserves3DCtx.mAccumulatedTransform;
1527
0
    }
1528
1529
    const Matrix4x4& GetCurrentTransform()
1530
0
    {
1531
0
      return mBuilder->mPreserves3DCtx.mAccumulatedTransform;
1532
0
    }
1533
1534
    void StartRoot()
1535
0
    {
1536
0
      mBuilder->mPreserves3DCtx.mAccumulatedTransform = Matrix4x4();
1537
0
    }
1538
1539
  private:
1540
    nsDisplayListBuilder* mBuilder;
1541
    Matrix4x4 mSavedTransform;
1542
  };
1543
1544
  /**
1545
   * A helper class to collect bounds rects of descendants.
1546
   *
1547
   * For a 3D context root, it's bounds is computed from the bounds of
1548
   * descendants.  If we transform bounds frame by frame applying
1549
   * transforms, the bounds may turn to empty for any singular
1550
   * transform on the path, but it is not empty for the accumulated
1551
   * transform.
1552
   */
1553
  class AutoAccumulateRect
1554
  {
1555
  public:
1556
    explicit AutoAccumulateRect(nsDisplayListBuilder* aBuilder)
1557
      : mBuilder(aBuilder)
1558
      , mSavedRect(aBuilder->mPreserves3DCtx.mAccumulatedRect)
1559
0
    {
1560
0
      aBuilder->mPreserves3DCtx.mAccumulatedRect = nsRect();
1561
0
      aBuilder->mPreserves3DCtx.mAccumulatedRectLevels++;
1562
0
    }
1563
1564
    ~AutoAccumulateRect()
1565
0
    {
1566
0
      mBuilder->mPreserves3DCtx.mAccumulatedRect = mSavedRect;
1567
0
      mBuilder->mPreserves3DCtx.mAccumulatedRectLevels--;
1568
0
    }
1569
1570
  private:
1571
    nsDisplayListBuilder* mBuilder;
1572
    nsRect mSavedRect;
1573
  };
1574
1575
  void AccumulateRect(const nsRect& aRect)
1576
0
  {
1577
0
    mPreserves3DCtx.mAccumulatedRect.UnionRect(mPreserves3DCtx.mAccumulatedRect,
1578
0
                                               aRect);
1579
0
  }
1580
1581
  const nsRect& GetAccumulatedRect()
1582
0
  {
1583
0
    return mPreserves3DCtx.mAccumulatedRect;
1584
0
  }
1585
1586
  /**
1587
   * The level is increased by one for items establishing 3D rendering
1588
   * context and starting a new accumulation.
1589
   */
1590
  int GetAccumulatedRectLevels()
1591
  {
1592
    return mPreserves3DCtx.mAccumulatedRectLevels;
1593
  }
1594
1595
  // Helpers for tables
1596
0
  nsDisplayTableItem* GetCurrentTableItem() { return mCurrentTableItem; }
1597
1598
  void SetCurrentTableItem(nsDisplayTableItem* aTableItem)
1599
0
  {
1600
0
    mCurrentTableItem = aTableItem;
1601
0
  }
1602
1603
  struct OutOfFlowDisplayData
1604
  {
1605
    OutOfFlowDisplayData(
1606
      const DisplayItemClipChain* aContainingBlockClipChain,
1607
      const DisplayItemClipChain* aCombinedClipChain,
1608
      const ActiveScrolledRoot* aContainingBlockActiveScrolledRoot,
1609
      const nsRect& aVisibleRect,
1610
      const nsRect& aDirtyRect)
1611
      : mContainingBlockClipChain(aContainingBlockClipChain)
1612
      , mCombinedClipChain(aCombinedClipChain)
1613
      , mContainingBlockActiveScrolledRoot(aContainingBlockActiveScrolledRoot)
1614
      , mVisibleRect(aVisibleRect)
1615
      , mDirtyRect(aDirtyRect)
1616
0
    {
1617
0
    }
1618
    const DisplayItemClipChain* mContainingBlockClipChain;
1619
    const DisplayItemClipChain*
1620
      mCombinedClipChain; // only necessary for the special case of top layer
1621
    const ActiveScrolledRoot* mContainingBlockActiveScrolledRoot;
1622
    nsRect mVisibleRect;
1623
    nsRect mDirtyRect;
1624
1625
    static nsRect ComputeVisibleRectForFrame(nsDisplayListBuilder* aBuilder,
1626
                                             nsIFrame* aFrame,
1627
                                             const nsRect& aVisibleRect,
1628
                                             const nsRect& aDirtyRect,
1629
                                             nsRect* aOutDirtyRect)
1630
0
    {
1631
0
      nsRect visible = aVisibleRect;
1632
0
      nsRect dirtyRectRelativeToDirtyFrame = aDirtyRect;
1633
0
1634
#ifdef MOZ_WIDGET_ANDROID
1635
      if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame) &&
1636
          aBuilder->IsPaintingToWindow()) {
1637
        // We want to ensure that fixed position elements are visible when
1638
        // being async scrolled, so we paint them at the size of the larger
1639
        // viewport.
1640
        dirtyRectRelativeToDirtyFrame =
1641
          nsRect(nsPoint(0, 0), aFrame->GetParent()->GetSize());
1642
1643
        nsIPresShell* ps = aFrame->PresShell();
1644
        if (ps->IsVisualViewportSizeSet() &&
1645
            dirtyRectRelativeToDirtyFrame.Size() <
1646
              ps->GetVisualViewportSize()) {
1647
          dirtyRectRelativeToDirtyFrame.SizeTo(ps->GetVisualViewportSize());
1648
        }
1649
1650
        visible = dirtyRectRelativeToDirtyFrame;
1651
      }
1652
#endif
1653
1654
0
      *aOutDirtyRect = dirtyRectRelativeToDirtyFrame - aFrame->GetPosition();
1655
0
      visible -= aFrame->GetPosition();
1656
0
1657
0
      nsRect overflowRect = aFrame->GetVisualOverflowRect();
1658
0
1659
0
      if (aFrame->IsTransformed() &&
1660
0
          mozilla::EffectCompositor::HasAnimationsForCompositor(
1661
0
            aFrame, eCSSProperty_transform)) {
1662
0
        /**
1663
0
         * Add a fuzz factor to the overflow rectangle so that elements only
1664
0
         * just out of view are pulled into the display list, so they can be
1665
0
         * prerendered if necessary.
1666
0
         */
1667
0
        overflowRect.Inflate(nsPresContext::CSSPixelsToAppUnits(32));
1668
0
      }
1669
0
1670
0
      visible.IntersectRect(visible, overflowRect);
1671
0
      aOutDirtyRect->IntersectRect(*aOutDirtyRect, overflowRect);
1672
0
1673
0
      return visible;
1674
0
    }
1675
1676
    nsRect GetVisibleRectForFrame(nsDisplayListBuilder* aBuilder,
1677
                                  nsIFrame* aFrame,
1678
                                  nsRect* aDirtyRect)
1679
0
    {
1680
0
      return ComputeVisibleRectForFrame(
1681
0
        aBuilder, aFrame, mVisibleRect, mDirtyRect, aDirtyRect);
1682
0
    }
1683
  };
1684
1685
  NS_DECLARE_FRAME_PROPERTY_DELETABLE(OutOfFlowDisplayDataProperty,
1686
                                      OutOfFlowDisplayData)
1687
1688
  struct DisplayListBuildingData
1689
  {
1690
    RefPtr<AnimatedGeometryRoot> mModifiedAGR = nullptr;
1691
    nsRect mDirtyRect;
1692
  };
1693
  NS_DECLARE_FRAME_PROPERTY_DELETABLE(DisplayListBuildingRect,
1694
                                      DisplayListBuildingData)
1695
1696
  NS_DECLARE_FRAME_PROPERTY_DELETABLE(DisplayListBuildingDisplayPortRect,
1697
                                      nsRect)
1698
1699
  static OutOfFlowDisplayData* GetOutOfFlowData(nsIFrame* aFrame)
1700
0
  {
1701
0
    if (!aFrame->GetParent()) {
1702
0
      return nullptr;
1703
0
    }
1704
0
    return aFrame->GetParent()->GetProperty(OutOfFlowDisplayDataProperty());
1705
0
  }
1706
1707
  nsPresContext* CurrentPresContext()
1708
0
  {
1709
0
    return CurrentPresShellState()->mPresShell->GetPresContext();
1710
0
  }
1711
1712
  OutOfFlowDisplayData* GetCurrentFixedBackgroundDisplayData()
1713
0
  {
1714
0
    auto& displayData = CurrentPresShellState()->mFixedBackgroundDisplayData;
1715
0
    return displayData ? displayData.ptr() : nullptr;
1716
0
  }
1717
1718
  /**
1719
   * Accumulates the bounds of box frames that have moz-appearance
1720
   * -moz-win-exclude-glass style. Used in setting glass margins on
1721
   * Windows.
1722
   *
1723
   * We set the window opaque region (from which glass margins are computed)
1724
   * to the intersection of the glass region specified here and the opaque
1725
   * region computed during painting. So the excluded glass region actually
1726
   * *limits* the extent of the opaque area reported to Windows. We limit it
1727
   * so that changes to the computed opaque region (which can vary based on
1728
   * region optimizations and the placement of UI elements) outside the
1729
   * -moz-win-exclude-glass area don't affect the glass margins reported to
1730
   * Windows; changing those margins willy-nilly can cause the Windows 7 glass
1731
   * haze effect to jump around disconcertingly.
1732
   */
1733
  void AddWindowExcludeGlassRegion(nsIFrame* aFrame, const nsRect& aBounds)
1734
0
  {
1735
0
    mWindowExcludeGlassRegion.Add(aFrame, aBounds);
1736
0
  }
1737
1738
  /**
1739
   * Returns the window exclude glass region.
1740
   */
1741
  nsRegion GetWindowExcludeGlassRegion() const
1742
0
  {
1743
0
    return mWindowExcludeGlassRegion.ToRegion();
1744
0
  }
1745
1746
  /**
1747
   * Accumulates opaque stuff into the window opaque region.
1748
   */
1749
  void AddWindowOpaqueRegion(const nsRegion& bounds)
1750
0
  {
1751
0
    mWindowOpaqueRegion.Or(mWindowOpaqueRegion, bounds);
1752
0
  }
1753
  /**
1754
   * Returns the window opaque region built so far. This may be incomplete
1755
   * since the opaque region is built during layer construction.
1756
   */
1757
0
  const nsRegion& GetWindowOpaqueRegion() { return mWindowOpaqueRegion; }
1758
1759
  /**
1760
   * Clears the window opaque region.
1761
   */
1762
0
  void ClearWindowOpaqueRegion() { mWindowOpaqueRegion.SetEmpty(); }
1763
1764
  void SetGlassDisplayItem(nsDisplayItem* aItem)
1765
0
  {
1766
0
    if (mGlassDisplayItem) {
1767
0
      // Web pages or extensions could trigger this by using
1768
0
      // -moz-appearance:win-borderless-glass etc on their own elements.
1769
0
      // Keep the first one, since that will be the background of the root
1770
0
      // window
1771
0
      NS_WARNING("Multiple glass backgrounds found?");
1772
0
    } else {
1773
0
      mGlassDisplayItem = aItem;
1774
0
    }
1775
0
  }
1776
1777
  bool NeedToForceTransparentSurfaceForItem(nsDisplayItem* aItem);
1778
1779
0
  void SetContainsPluginItem() { mContainsPluginItem = true; }
1780
0
  bool ContainsPluginItem() { return mContainsPluginItem; }
1781
1782
  /**
1783
   * mContainsBlendMode is true if we processed a display item that
1784
   * has a blend mode attached. We do this so we can insert a
1785
   * nsDisplayBlendContainer in the parent stacking context.
1786
   */
1787
  void SetContainsBlendMode(bool aContainsBlendMode)
1788
0
  {
1789
0
    mContainsBlendMode = aContainsBlendMode;
1790
0
  }
1791
0
  bool ContainsBlendMode() const { return mContainsBlendMode; }
1792
1793
0
  DisplayListClipState& ClipState() { return mClipState; }
1794
  const ActiveScrolledRoot* CurrentActiveScrolledRoot()
1795
0
  {
1796
0
    return mCurrentActiveScrolledRoot;
1797
0
  }
1798
  const ActiveScrolledRoot* CurrentAncestorASRStackingContextContents()
1799
  {
1800
    return mCurrentContainerASR;
1801
  }
1802
1803
  /**
1804
   * Add the current frame to the will-change budget if possible and
1805
   * remeber the outcome. Subsequent calls to IsInWillChangeBudget
1806
   * will return the same value as return here.
1807
   */
1808
  bool AddToWillChangeBudget(nsIFrame* aFrame, const nsSize& aSize);
1809
1810
  /**
1811
   * This will add the current frame to the will-change budget the first
1812
   * time it is seen. On subsequent calls this will return the same
1813
   * answer. This effectively implements a first-come, first-served
1814
   * allocation of the will-change budget.
1815
   */
1816
  bool IsInWillChangeBudget(nsIFrame* aFrame, const nsSize& aSize);
1817
1818
  void RemoveFromWillChangeBudget(nsIFrame* aFrame);
1819
1820
  void ClearWillChangeBudget();
1821
1822
  void EnterSVGEffectsContents(nsDisplayList* aHoistedItemsStorage);
1823
  void ExitSVGEffectsContents();
1824
1825
  /**
1826
   * Note: if changing the conditions under which scroll info layers
1827
   * are created, make a corresponding change to
1828
   * ScrollFrameWillBuildScrollInfoLayer() in nsSliderFrame.cpp.
1829
   */
1830
  bool ShouldBuildScrollInfoItemsForHoisting() const
1831
0
  {
1832
0
    return mSVGEffectsBuildingDepth > 0;
1833
0
  }
1834
1835
  void AppendNewScrollInfoItemForHoisting(
1836
    nsDisplayScrollInfoLayer* aScrollInfoItem);
1837
1838
  /**
1839
   * A helper class to install/restore nsDisplayListBuilder::mPreserves3DCtx.
1840
   *
1841
   * mPreserves3DCtx is used by class AutoAccumulateTransform &
1842
   * AutoAccumulateRect to passing data between frames in the 3D
1843
   * context.  If a frame create a new 3D context, it should restore
1844
   * the value of mPreserves3DCtx before returning back to the parent.
1845
   * This class do it for the users.
1846
   */
1847
  class AutoPreserves3DContext
1848
  {
1849
  public:
1850
    explicit AutoPreserves3DContext(nsDisplayListBuilder* aBuilder)
1851
      : mBuilder(aBuilder)
1852
      , mSavedCtx(aBuilder->mPreserves3DCtx)
1853
0
    {
1854
0
    }
1855
1856
0
    ~AutoPreserves3DContext() { mBuilder->mPreserves3DCtx = mSavedCtx; }
1857
1858
  private:
1859
    nsDisplayListBuilder* mBuilder;
1860
    Preserves3DContext mSavedCtx;
1861
  };
1862
1863
  const nsRect GetPreserves3DRect() const
1864
0
  {
1865
0
    return mPreserves3DCtx.mVisibleRect;
1866
0
  }
1867
1868
0
  void SavePreserves3DRect() { mPreserves3DCtx.mVisibleRect = mVisibleRect; }
1869
1870
0
  bool IsBuildingInvisibleItems() const { return mBuildingInvisibleItems; }
1871
1872
  void SetBuildingInvisibleItems(bool aBuildingInvisibleItems)
1873
0
  {
1874
0
    mBuildingInvisibleItems = aBuildingInvisibleItems;
1875
0
  }
1876
1877
  bool MarkFrameModifiedDuringBuilding(nsIFrame* aFrame)
1878
0
  {
1879
0
    if (!aFrame->IsFrameModified()) {
1880
0
      mModifiedFramesDuringBuilding.AppendElement(aFrame);
1881
0
      aFrame->SetFrameIsModified(true);
1882
0
      return true;
1883
0
    }
1884
0
    return false;
1885
0
  }
1886
1887
  bool MarkCurrentFrameModifiedDuringBuilding()
1888
  {
1889
    if (MarkFrameModifiedDuringBuilding(const_cast<nsIFrame*>(mCurrentFrame))) {
1890
      mInInvalidSubtree = true;
1891
      mDirtyRect = mVisibleRect;
1892
      return true;
1893
    }
1894
    return false;
1895
  }
1896
1897
  void RebuildAllItemsInCurrentSubtree()
1898
0
  {
1899
0
    mInInvalidSubtree = true;
1900
0
    mDirtyRect = mVisibleRect;
1901
0
  }
1902
1903
  /**
1904
   * This is a convenience function to ease the transition until AGRs and ASRs
1905
   * are unified.
1906
   */
1907
  AnimatedGeometryRoot* AnimatedGeometryRootForASR(
1908
    const ActiveScrolledRoot* aASR);
1909
1910
0
  bool HitTestIsForVisibility() const { return mHitTestIsForVisibility; }
1911
1912
  void SetHitTestIsForVisibility(bool aHitTestIsForVisibility)
1913
0
  {
1914
0
    mHitTestIsForVisibility = aHitTestIsForVisibility;
1915
0
  }
1916
1917
  /**
1918
   * Represents a region composed of frame/rect pairs.
1919
   * WeakFrames are used to track whether a rect still belongs to the region.
1920
   * Modified frames and rects are removed and re-added to the region if needed.
1921
   */
1922
  struct WeakFrameRegion
1923
  {
1924
    std::vector<WeakFrame> mFrames;
1925
    nsTArray<pixman_box32_t> mRects;
1926
1927
    void Add(nsIFrame* aFrame, const nsRect& aRect)
1928
0
    {
1929
0
      mFrames.emplace_back(aFrame);
1930
0
      mRects.AppendElement(nsRegion::RectToBox(aRect));
1931
0
    }
1932
1933
    void Add(nsIFrame* aFrame, const mozilla::gfx::IntRect& aRect)
1934
0
    {
1935
0
      mFrames.emplace_back(aFrame);
1936
0
      mRects.AppendElement(nsRegion::RectToBox(aRect));
1937
0
    }
1938
1939
    void Clear()
1940
0
    {
1941
0
      mFrames.clear();
1942
0
      mRects.Clear();
1943
0
    }
1944
1945
    typedef mozilla::gfx::ArrayView<pixman_box32_t> BoxArrayView;
1946
1947
0
    nsRegion ToRegion() const { return nsRegion(BoxArrayView(mRects)); }
1948
1949
    LayoutDeviceIntRegion ToLayoutDeviceIntRegion() const
1950
0
    {
1951
0
      return LayoutDeviceIntRegion(BoxArrayView(mRects));
1952
0
    }
1953
  };
1954
1955
private:
1956
  bool MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame);
1957
1958
  /**
1959
   * Returns whether a frame acts as an animated geometry root, optionally
1960
   * returning the next ancestor to check.
1961
   */
1962
  AGRState IsAnimatedGeometryRoot(nsIFrame* aFrame,
1963
                                  bool& aIsAsync,
1964
                                  nsIFrame** aParent = nullptr);
1965
1966
  /**
1967
   * Returns the nearest ancestor frame to aFrame that is considered to have
1968
   * (or will have) animated geometry. This can return aFrame.
1969
   */
1970
  nsIFrame* FindAnimatedGeometryRootFrameFor(nsIFrame* aFrame, bool& aIsAsync);
1971
1972
  /**
1973
   * Returns true if nsDisplayCompositorHitTestInfo item should be build for
1974
   * |aFrame|. Otherwise returns false. If |aBuildNew| is true, reusing the
1975
   * previous hit test info will not be considered.
1976
   */
1977
  bool ShouldBuildCompositorHitTestInfo(
1978
    const nsIFrame* aFrame,
1979
    const mozilla::gfx::CompositorHitTestInfo& aInfo,
1980
    const bool aBuildNew) const;
1981
1982
  friend class nsDisplayCanvasBackgroundImage;
1983
  friend class nsDisplayBackgroundImage;
1984
  friend class nsDisplayFixedPosition;
1985
  friend class nsDisplayPerspective;
1986
  AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsDisplayItem* aItem);
1987
1988
  friend class nsDisplayItem;
1989
  friend class nsDisplayOwnLayer;
1990
  friend struct RetainedDisplayListBuilder;
1991
  AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsIFrame* aFrame);
1992
1993
  AnimatedGeometryRoot* WrapAGRForFrame(
1994
    nsIFrame* aAnimatedGeometryRoot,
1995
    bool aIsAsync,
1996
    AnimatedGeometryRoot* aParent = nullptr);
1997
1998
  nsDataHashtable<nsPtrHashKey<nsIFrame>, RefPtr<AnimatedGeometryRoot>>
1999
    mFrameToAnimatedGeometryRootMap;
2000
2001
  /**
2002
   * Add the current frame to the AGR budget if possible and remember
2003
   * the outcome. Subsequent calls will return the same value as
2004
   * returned here.
2005
   */
2006
  bool AddToAGRBudget(nsIFrame* aFrame);
2007
2008
  struct PresShellState
2009
  {
2010
    nsIPresShell* mPresShell;
2011
#ifdef DEBUG
2012
    mozilla::Maybe<nsAutoLayoutPhase> mAutoLayoutPhase;
2013
#endif
2014
    nsIFrame* mCaretFrame;
2015
    nsRect mCaretRect;
2016
    mozilla::Maybe<OutOfFlowDisplayData> mFixedBackgroundDisplayData;
2017
    uint32_t mFirstFrameMarkedForDisplay;
2018
    uint32_t mFirstFrameWithOOFData;
2019
    bool mIsBackgroundOnly;
2020
    // This is a per-document flag turning off event handling for all content
2021
    // in the document, and is set when we enter a subdocument for a pointer-
2022
    // events:none frame.
2023
    bool mInsidePointerEventsNoneDoc;
2024
  };
2025
2026
  PresShellState* CurrentPresShellState()
2027
0
  {
2028
0
    NS_ASSERTION(mPresShellStates.Length() > 0,
2029
0
                 "Someone forgot to enter a presshell");
2030
0
    return &mPresShellStates[mPresShellStates.Length() - 1];
2031
0
  }
2032
2033
  struct DocumentWillChangeBudget
2034
  {
2035
    DocumentWillChangeBudget()
2036
      : mBudget(0)
2037
0
    {
2038
0
    }
2039
2040
    uint32_t mBudget;
2041
  };
2042
2043
  struct FrameWillChangeBudget
2044
  {
2045
    FrameWillChangeBudget()
2046
      : mPresContext(nullptr)
2047
      , mUsage(0)
2048
0
    {
2049
0
    }
2050
2051
    FrameWillChangeBudget(nsPresContext* aPresContext, uint32_t aUsage)
2052
      : mPresContext(aPresContext)
2053
      , mUsage(aUsage)
2054
0
    {
2055
0
    }
2056
2057
    nsPresContext* mPresContext;
2058
    uint32_t mUsage;
2059
  };
2060
2061
  nsIFrame* const mReferenceFrame;
2062
  nsIFrame* mIgnoreScrollFrame;
2063
  nsDisplayCompositorHitTestInfo* mCompositorHitTestInfo;
2064
2065
  nsPresArena mPool;
2066
2067
  RefPtr<mozilla::dom::Selection> mBoundingSelection;
2068
  AutoTArray<PresShellState, 8> mPresShellStates;
2069
  AutoTArray<nsIFrame*, 400> mFramesMarkedForDisplay;
2070
  AutoTArray<nsIFrame*, 40> mFramesMarkedForDisplayIfVisible;
2071
  AutoTArray<nsIFrame*, 20> mFramesWithOOFData;
2072
  nsClassHashtable<nsPtrHashKey<nsDisplayItem>, nsTArray<ThemeGeometry>>
2073
    mThemeGeometries;
2074
  nsDisplayTableItem* mCurrentTableItem;
2075
  DisplayListClipState mClipState;
2076
  const ActiveScrolledRoot* mCurrentActiveScrolledRoot;
2077
  const ActiveScrolledRoot* mCurrentContainerASR;
2078
  // mCurrentFrame is the frame that we're currently calling (or about to call)
2079
  // BuildDisplayList on.
2080
  const nsIFrame* mCurrentFrame;
2081
  // The reference frame for mCurrentFrame.
2082
  const nsIFrame* mCurrentReferenceFrame;
2083
  // The offset from mCurrentFrame to mCurrentReferenceFrame.
2084
  nsPoint mCurrentOffsetToReferenceFrame;
2085
2086
  RefPtr<AnimatedGeometryRoot> mRootAGR;
2087
  RefPtr<AnimatedGeometryRoot> mCurrentAGR;
2088
2089
  // will-change budget tracker
2090
  nsDataHashtable<nsPtrHashKey<nsPresContext>, DocumentWillChangeBudget>
2091
    mWillChangeBudget;
2092
2093
  // Any frame listed in this set is already counted in the budget
2094
  // and thus is in-budget.
2095
  nsDataHashtable<nsPtrHashKey<nsIFrame>, FrameWillChangeBudget>
2096
    mWillChangeBudgetSet;
2097
2098
  // Area of animated geometry root budget already allocated
2099
  uint32_t mUsedAGRBudget;
2100
  // Set of frames already counted in budget
2101
  nsTHashtable<nsPtrHashKey<nsIFrame>> mAGRBudgetSet;
2102
2103
  nsTArray<nsIFrame*> mModifiedFramesDuringBuilding;
2104
2105
  // Relative to mCurrentFrame.
2106
  nsRect mVisibleRect;
2107
  nsRect mDirtyRect;
2108
2109
  // Tracked regions used for retained display list.
2110
  WeakFrameRegion mWindowExcludeGlassRegion;
2111
  WeakFrameRegion mRetainedWindowDraggingRegion;
2112
  WeakFrameRegion mRetainedWindowNoDraggingRegion;
2113
2114
  // Optimized versions for non-retained display list.
2115
  LayoutDeviceIntRegion mWindowDraggingRegion;
2116
  LayoutDeviceIntRegion mWindowNoDraggingRegion;
2117
2118
  // Window opaque region is calculated during layer building.
2119
  nsRegion mWindowOpaqueRegion;
2120
2121
  // The display item for the Windows window glass background, if any
2122
  nsDisplayItem* mGlassDisplayItem;
2123
  // A temporary list that we append scroll info items to while building
2124
  // display items for the contents of frames with SVG effects.
2125
  // Only non-null when ShouldBuildScrollInfoItemsForHoisting() is true.
2126
  // This is a pointer and not a real nsDisplayList value because the
2127
  // nsDisplayList class is defined below this class, so we can't use it here.
2128
  nsDisplayList* mScrollInfoItemsForHoisting;
2129
  nsTArray<RefPtr<ActiveScrolledRoot>> mActiveScrolledRoots;
2130
  std::unordered_set<const DisplayItemClipChain*,
2131
                     DisplayItemClipChainHasher,
2132
                     DisplayItemClipChainEqualer>
2133
    mClipDeduplicator;
2134
  DisplayItemClipChain* mFirstClipChainToDestroy;
2135
  nsTArray<nsDisplayItem*> mTemporaryItems;
2136
  const ActiveScrolledRoot* mActiveScrolledRootForRootScrollframe;
2137
  nsDisplayListBuilderMode mMode;
2138
  ViewID mCurrentScrollParentId;
2139
  ViewID mCurrentScrollbarTarget;
2140
  MaybeScrollDirection mCurrentScrollbarDirection;
2141
  Preserves3DContext mPreserves3DCtx;
2142
  int32_t mSVGEffectsBuildingDepth;
2143
  // When we are inside a filter, the current ASR at the time we entered the
2144
  // filter. Otherwise nullptr.
2145
  const ActiveScrolledRoot* mFilterASR;
2146
  bool mContainsBlendMode;
2147
  bool mIsBuildingScrollbar;
2148
  bool mCurrentScrollbarWillHaveLayer;
2149
  bool mBuildCaret;
2150
  bool mRetainingDisplayList;
2151
  bool mPartialUpdate;
2152
  bool mIgnoreSuppression;
2153
  bool mIsAtRootOfPseudoStackingContext;
2154
  bool mIncludeAllOutOfFlows;
2155
  bool mDescendIntoSubdocuments;
2156
  bool mSelectedFramesOnly;
2157
  bool mAllowMergingAndFlattening;
2158
  bool mWillComputePluginGeometry;
2159
  // True when we're building a display list that's directly or indirectly
2160
  // under an nsDisplayTransform
2161
  bool mInTransform;
2162
  bool mInFilter;
2163
  bool mInPageSequence;
2164
  bool mIsInChromePresContext;
2165
  bool mSyncDecodeImages;
2166
  bool mIsPaintingToWindow;
2167
  bool mIsCompositingCheap;
2168
  bool mContainsPluginItem;
2169
  bool mAncestorHasApzAwareEventHandler;
2170
  // True when the first async-scrollable scroll frame for which we build a
2171
  // display list has a display port. An async-scrollable scroll frame is one
2172
  // which WantsAsyncScroll().
2173
  bool mHaveScrollableDisplayPort;
2174
  bool mWindowDraggingAllowed;
2175
  bool mIsBuildingForPopup;
2176
  bool mForceLayerForScrollParent;
2177
  bool mAsyncPanZoomEnabled;
2178
  bool mBuildingInvisibleItems;
2179
  bool mHitTestIsForVisibility;
2180
  bool mIsBuilding;
2181
  bool mInInvalidSubtree;
2182
  bool mBuildCompositorHitTestInfo;
2183
  bool mLessEventRegionItems;
2184
  bool mDisablePartialUpdates;
2185
  bool mPartialBuildFailed;
2186
};
2187
2188
class nsDisplayItem;
2189
class nsDisplayList;
2190
class RetainedDisplayList;
2191
/**
2192
 * nsDisplayItems are put in singly-linked lists rooted in an nsDisplayList.
2193
 * nsDisplayItemLink holds the link. The lists are linked from lowest to
2194
 * highest in z-order.
2195
 */
2196
class nsDisplayItemLink
2197
{
2198
  // This is never instantiated directly, so no need to count constructors and
2199
  // destructors.
2200
protected:
2201
  nsDisplayItemLink()
2202
    : mAbove(nullptr)
2203
0
  {
2204
0
  }
2205
  nsDisplayItemLink(const nsDisplayItemLink&)
2206
    : mAbove(nullptr)
2207
  {
2208
  }
2209
  nsDisplayItem* mAbove;
2210
2211
  friend class nsDisplayList;
2212
};
2213
2214
class nsDisplayWrapList;
2215
2216
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
2217
void
2218
AssertUniqueItem(nsDisplayItem* aItem);
2219
#endif
2220
2221
template<typename T, typename... Args>
2222
MOZ_ALWAYS_INLINE T*
2223
MakeDisplayItem(nsDisplayListBuilder* aBuilder, Args&&... aArgs)
2224
0
{
2225
0
  T* item = new (aBuilder) T(aBuilder, std::forward<Args>(aArgs)...);
2226
0
2227
0
  const mozilla::SmallPointerArray<mozilla::DisplayItemData>& array =
2228
0
    item->Frame()->DisplayItemData();
2229
0
  for (uint32_t i = 0; i < array.Length(); i++) {
2230
0
    mozilla::DisplayItemData* did = array.ElementAt(i);
2231
0
    if (did->GetDisplayItemKey() == item->GetPerFrameKey()) {
2232
0
      if (did->GetLayer()->AsPaintedLayer()) {
2233
0
        if (!did->HasMergedFrames()) {
2234
0
          item->SetDisplayItemData(did, did->GetLayer()->Manager());
2235
0
        }
2236
0
        break;
2237
0
      }
2238
0
    }
2239
0
  }
2240
0
2241
0
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
2242
0
  if (aBuilder->IsRetainingDisplayList() && !aBuilder->IsInPageSequence() &&
2243
0
      aBuilder->IsBuilding()) {
2244
0
    AssertUniqueItem(item);
2245
0
  }
2246
0
#endif
2247
0
2248
0
  return item;
2249
0
}
Unexecuted instantiation: nsDisplayOpacity* MakeDisplayItem<nsDisplayOpacity, nsDisplayOpacity const&>(nsDisplayListBuilder*, nsDisplayOpacity const&)
Unexecuted instantiation: nsDisplayBlendMode* MakeDisplayItem<nsDisplayBlendMode, nsDisplayBlendMode const&>(nsDisplayListBuilder*, nsDisplayBlendMode const&)
Unexecuted instantiation: nsDisplayTableBlendMode* MakeDisplayItem<nsDisplayTableBlendMode, nsDisplayTableBlendMode const&>(nsDisplayListBuilder*, nsDisplayTableBlendMode const&)
Unexecuted instantiation: nsDisplayBlendContainer* MakeDisplayItem<nsDisplayBlendContainer, nsDisplayBlendContainer const&>(nsDisplayListBuilder*, nsDisplayBlendContainer const&)
Unexecuted instantiation: nsDisplayTableBlendContainer* MakeDisplayItem<nsDisplayTableBlendContainer, nsDisplayTableBlendContainer const&>(nsDisplayListBuilder*, nsDisplayTableBlendContainer const&)
Unexecuted instantiation: nsDisplayStickyPosition* MakeDisplayItem<nsDisplayStickyPosition, nsDisplayStickyPosition const&>(nsDisplayListBuilder*, nsDisplayStickyPosition const&)
Unexecuted instantiation: nsDisplayFixedPosition* MakeDisplayItem<nsDisplayFixedPosition, nsDisplayFixedPosition const&>(nsDisplayListBuilder*, nsDisplayFixedPosition const&)
Unexecuted instantiation: nsDisplayTableFixedPosition* MakeDisplayItem<nsDisplayTableFixedPosition, nsDisplayTableFixedPosition const&>(nsDisplayListBuilder*, nsDisplayTableFixedPosition const&)
Unexecuted instantiation: nsDisplayMask* MakeDisplayItem<nsDisplayMask, nsDisplayMask const&>(nsDisplayListBuilder*, nsDisplayMask const&)
Unexecuted instantiation: nsDisplayFilter* MakeDisplayItem<nsDisplayFilter, nsDisplayFilter const&>(nsDisplayListBuilder*, nsDisplayFilter const&)
Unexecuted instantiation: nsDisplaySolidColor* MakeDisplayItem<nsDisplaySolidColor, nsIFrame*&, nsRect const&, unsigned int>(nsDisplayListBuilder*, nsIFrame*&, nsRect const&, unsigned int&&)
Unexecuted instantiation: nsDisplaySolidColor* MakeDisplayItem<nsDisplaySolidColor, nsIFrame*&, nsRect const&, unsigned int&>(nsDisplayListBuilder*, nsIFrame*&, nsRect const&, unsigned int&)
Unexecuted instantiation: nsDisplayTransform* MakeDisplayItem<nsDisplayTransform, nsIFrame*&, nsDisplayList*, nsRect>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&&, nsRect&&)
Unexecuted instantiation: nsDisplayGeneric* MakeDisplayItem<nsDisplayGeneric, nsPluginFrame*, void (&)(nsIFrame*, gfxContext*, nsRect const&, nsPoint), char const (&) [12], DisplayItemType>(nsDisplayListBuilder*, nsPluginFrame*&&, void (&)(nsIFrame*, gfxContext*, nsRect const&, nsPoint), char const (&) [12], DisplayItemType&&)
Unexecuted instantiation: nsDisplayPluginReadback* MakeDisplayItem<nsDisplayPluginReadback, nsPluginFrame*>(nsDisplayListBuilder*, nsPluginFrame*&&)
Unexecuted instantiation: nsDisplayPlugin* MakeDisplayItem<nsDisplayPlugin, nsPluginFrame*>(nsDisplayListBuilder*, nsPluginFrame*&&)
Unexecuted instantiation: nsDisplayTransform* MakeDisplayItem<nsDisplayTransform, nsIFrame*&, nsDisplayList*&, nsRect const&, mozilla::gfx::Matrix4x4Typed<mozilla::gfx::UnknownUnits, mozilla::gfx::UnknownUnits>, int&>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&, nsRect const&, mozilla::gfx::Matrix4x4Typed<mozilla::gfx::UnknownUnits, mozilla::gfx::UnknownUnits>&&, int&)
Unexecuted instantiation: nsDisplayWrapList* MakeDisplayItem<nsDisplayWrapList, nsIFrame*&, nsDisplayList*&, mozilla::ActiveScrolledRoot const*&, bool>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&, mozilla::ActiveScrolledRoot const*&, bool&&)
Unexecuted instantiation: mozilla::css::nsDisplayTextOverflowMarker* MakeDisplayItem<mozilla::css::nsDisplayTextOverflowMarker, nsIFrame*&, nsRect&, int, nsStyleTextOverflowSide const*&, unsigned int&, int>(nsDisplayListBuilder*, nsIFrame*&, nsRect&, int&&, nsStyleTextOverflowSide const*&, unsigned int&, int&&)
Unexecuted instantiation: nsDisplayWrapList* MakeDisplayItem<nsDisplayWrapList, mozilla::ViewportFrame*, nsDisplayList*>(nsDisplayListBuilder*, mozilla::ViewportFrame*&&, nsDisplayList*&&)
Unexecuted instantiation: nsDisplayBullet* MakeDisplayItem<nsDisplayBullet, nsBulletFrame*>(nsDisplayListBuilder*, nsBulletFrame*&&)
Unexecuted instantiation: nsDisplayCanvasBackgroundColor* MakeDisplayItem<nsDisplayCanvasBackgroundColor, nsCanvasFrame*>(nsDisplayListBuilder*, nsCanvasFrame*&&)
Unexecuted instantiation: nsDisplayCanvasThemedBackground* MakeDisplayItem<nsDisplayCanvasThemedBackground, nsCanvasFrame*>(nsDisplayListBuilder*, nsCanvasFrame*&&)
Unexecuted instantiation: nsDisplayCanvasBackgroundImage* MakeDisplayItem<nsDisplayCanvasBackgroundImage, nsDisplayBackgroundImage::InitData&>(nsDisplayListBuilder*, nsDisplayBackgroundImage::InitData&)
Unexecuted instantiation: nsDisplayBlendMode* MakeDisplayItem<nsDisplayBlendMode, nsCanvasFrame*, nsDisplayList*, unsigned char const&, mozilla::ActiveScrolledRoot const*&, unsigned int>(nsDisplayListBuilder*, nsCanvasFrame*&&, nsDisplayList*&&, unsigned char const&, mozilla::ActiveScrolledRoot const*&, unsigned int&&)
Unexecuted instantiation: nsDisplayCanvasFocus* MakeDisplayItem<nsDisplayCanvasFocus, nsCanvasFrame*>(nsDisplayListBuilder*, nsCanvasFrame*&&)
Unexecuted instantiation: nsDisplayColumnRule* MakeDisplayItem<nsDisplayColumnRule, nsColumnSetFrame*>(nsDisplayListBuilder*, nsColumnSetFrame*&&)
Unexecuted instantiation: nsDisplaySelectionOverlay* MakeDisplayItem<nsDisplaySelectionOverlay, nsFrame*, short&>(nsDisplayListBuilder*, nsFrame*&&, short&)
Unexecuted instantiation: nsDisplayOutline* MakeDisplayItem<nsDisplayOutline, nsFrame*>(nsDisplayListBuilder*, nsFrame*&&)
Unexecuted instantiation: nsDisplayCaret* MakeDisplayItem<nsDisplayCaret, nsIFrame*>(nsDisplayListBuilder*, nsIFrame*&&)
Unexecuted instantiation: nsDisplayBoxShadowOuter* MakeDisplayItem<nsDisplayBoxShadowOuter, nsFrame*>(nsDisplayListBuilder*, nsFrame*&&)
Unexecuted instantiation: nsDisplayBoxShadowInner* MakeDisplayItem<nsDisplayBoxShadowInner, nsFrame*>(nsDisplayListBuilder*, nsFrame*&&)
Unexecuted instantiation: nsDisplayBorder* MakeDisplayItem<nsDisplayBorder, nsFrame*>(nsDisplayListBuilder*, nsFrame*&&)
Unexecuted instantiation: nsDisplaySolidColor* MakeDisplayItem<nsDisplaySolidColor, nsIFrame*, nsRect, unsigned int, bool>(nsDisplayListBuilder*, nsIFrame*&&, nsRect&&, unsigned int&&, bool&&)
Unexecuted instantiation: nsDisplayFilter* MakeDisplayItem<nsDisplayFilter, nsIFrame*, nsDisplayList*, bool&>(nsDisplayListBuilder*, nsIFrame*&&, nsDisplayList*&&, bool&)
Unexecuted instantiation: nsDisplayMask* MakeDisplayItem<nsDisplayMask, nsIFrame*, nsDisplayList*, bool, mozilla::ActiveScrolledRoot const*&>(nsDisplayListBuilder*, nsIFrame*&&, nsDisplayList*&&, bool&&, mozilla::ActiveScrolledRoot const*&)
Unexecuted instantiation: nsDisplayOpacity* MakeDisplayItem<nsDisplayOpacity, nsIFrame*, nsDisplayList*, mozilla::ActiveScrolledRoot const*&, bool&, bool&>(nsDisplayListBuilder*, nsIFrame*&&, nsDisplayList*&&, mozilla::ActiveScrolledRoot const*&, bool&, bool&)
Unexecuted instantiation: nsDisplayTransform* MakeDisplayItem<nsDisplayTransform, nsIFrame*, nsDisplayList*, nsRect&, int, bool&>(nsDisplayListBuilder*, nsIFrame*&&, nsDisplayList*&&, nsRect&, int&&, bool&)
Unexecuted instantiation: nsDisplayPerspective* MakeDisplayItem<nsDisplayPerspective, nsIFrame*, nsDisplayList*>(nsDisplayListBuilder*, nsIFrame*&&, nsDisplayList*&&)
Unexecuted instantiation: nsDisplayOwnLayer* MakeDisplayItem<nsDisplayOwnLayer, nsIFrame*, nsDisplayList*, mozilla::ActiveScrolledRoot const*, nsDisplayOwnLayerFlags, mozilla::layers::ScrollbarData, bool>(nsDisplayListBuilder*, nsIFrame*&&, nsDisplayList*&&, mozilla::ActiveScrolledRoot const*&&, nsDisplayOwnLayerFlags&&, mozilla::layers::ScrollbarData&&, bool&&)
Unexecuted instantiation: nsDisplayFixedPosition* MakeDisplayItem<nsDisplayFixedPosition, nsIFrame*, nsDisplayList*, mozilla::ActiveScrolledRoot const*&, mozilla::ActiveScrolledRoot const*&>(nsDisplayListBuilder*, nsIFrame*&&, nsDisplayList*&&, mozilla::ActiveScrolledRoot const*&, mozilla::ActiveScrolledRoot const*&)
Unexecuted instantiation: nsDisplayStickyPosition* MakeDisplayItem<nsDisplayStickyPosition, nsIFrame*, nsDisplayList*, mozilla::ActiveScrolledRoot const*&, mozilla::ActiveScrolledRoot const*>(nsDisplayListBuilder*, nsIFrame*&&, nsDisplayList*&&, mozilla::ActiveScrolledRoot const*&, mozilla::ActiveScrolledRoot const*&&)
Unexecuted instantiation: nsDisplayBlendMode* MakeDisplayItem<nsDisplayBlendMode, nsIFrame*, nsDisplayList*, unsigned char const&, mozilla::ActiveScrolledRoot const*&>(nsDisplayListBuilder*, nsIFrame*&&, nsDisplayList*&&, unsigned char const&, mozilla::ActiveScrolledRoot const*&)
Unexecuted instantiation: nsDisplayOwnLayer* MakeDisplayItem<nsDisplayOwnLayer, nsIFrame*, nsDisplayList*&, mozilla::ActiveScrolledRoot const*>(nsDisplayListBuilder*, nsIFrame*&&, nsDisplayList*&, mozilla::ActiveScrolledRoot const*&&)
Unexecuted instantiation: nsDisplayOwnLayer* MakeDisplayItem<nsDisplayOwnLayer, nsIFrame*&, nsDisplayList*&, mozilla::ActiveScrolledRoot const*&, nsDisplayOwnLayerFlags, mozilla::layers::ScrollbarData&>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&, mozilla::ActiveScrolledRoot const*&, nsDisplayOwnLayerFlags&&, mozilla::layers::ScrollbarData&)
Unexecuted instantiation: nsDisplayWrapList* MakeDisplayItem<nsDisplayWrapList, nsIFrame*&, nsDisplayList*&, mozilla::ActiveScrolledRoot const*&, bool, int>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&, mozilla::ActiveScrolledRoot const*&, bool&&, int&&)
Unexecuted instantiation: nsDisplayEventReceiver* MakeDisplayItem<nsDisplayEventReceiver, nsHTMLFramesetFrame*>(nsDisplayListBuilder*, nsHTMLFramesetFrame*&&)
Unexecuted instantiation: nsDisplayFramesetBorder* MakeDisplayItem<nsDisplayFramesetBorder, nsHTMLFramesetBorderFrame*>(nsDisplayListBuilder*, nsHTMLFramesetBorderFrame*&&)
Unexecuted instantiation: nsDisplayFramesetBlank* MakeDisplayItem<nsDisplayFramesetBlank, nsHTMLFramesetBlankFrame*>(nsDisplayListBuilder*, nsHTMLFramesetBlankFrame*&&)
Unexecuted instantiation: nsDisplayCompositorHitTestInfo* MakeDisplayItem<nsDisplayCompositorHitTestInfo, nsIFrame*&, mozilla::gfx::CompositorHitTestInfo&, int>(nsDisplayListBuilder*, nsIFrame*&, mozilla::gfx::CompositorHitTestInfo&, int&&)
Unexecuted instantiation: nsDisplaySolidColor* MakeDisplayItem<nsDisplaySolidColor, nsContainerFrame*&, nsRect, unsigned int, bool>(nsDisplayListBuilder*, nsContainerFrame*&, nsRect&&, unsigned int&&, bool&&)
Unexecuted instantiation: nsDisplayCompositorHitTestInfo* MakeDisplayItem<nsDisplayCompositorHitTestInfo, nsIFrame*&, mozilla::gfx::CompositorHitTestInfo&, int, mozilla::Maybe<nsRect> >(nsDisplayListBuilder*, nsIFrame*&, mozilla::gfx::CompositorHitTestInfo&, int&&, mozilla::Maybe<nsRect>&&)
Unexecuted instantiation: nsDisplayScrollInfoLayer* MakeDisplayItem<nsDisplayScrollInfoLayer, nsIFrame*&, nsContainerFrame*&>(nsDisplayListBuilder*, nsIFrame*&, nsContainerFrame*&)
Unexecuted instantiation: nsDisplayCanvas* MakeDisplayItem<nsDisplayCanvas, nsHTMLCanvasFrame*>(nsDisplayListBuilder*, nsHTMLCanvasFrame*&&)
Unexecuted instantiation: nsDisplayAltFeedback* MakeDisplayItem<nsDisplayAltFeedback, nsImageFrame*>(nsDisplayListBuilder*, nsImageFrame*&&)
Unexecuted instantiation: nsDisplayImage* MakeDisplayItem<nsDisplayImage, nsImageFrame*, nsCOMPtr<imgIContainer>&, nsCOMPtr<imgIContainer>&>(nsDisplayListBuilder*, nsImageFrame*&&, nsCOMPtr<imgIContainer>&, nsCOMPtr<imgIContainer>&)
Unexecuted instantiation: nsDisplayTransform* MakeDisplayItem<nsDisplayTransform, nsIFrame*&, nsDisplayList*, nsRect, mozilla::gfx::Matrix4x4Typed<mozilla::gfx::UnknownUnits, mozilla::gfx::UnknownUnits> (&)(nsIFrame*, float)>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&&, nsRect&&, mozilla::gfx::Matrix4x4Typed<mozilla::gfx::UnknownUnits, mozilla::gfx::UnknownUnits> (&)(nsIFrame*, float))
Unexecuted instantiation: nsDisplayHeaderFooter* MakeDisplayItem<nsDisplayHeaderFooter, nsPageFrame*>(nsDisplayListBuilder*, nsPageFrame*&&)
Unexecuted instantiation: nsDisplayOwnLayer* MakeDisplayItem<nsDisplayOwnLayer, nsIFrame*&, nsDisplayList*, mozilla::ActiveScrolledRoot const*>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&&, mozilla::ActiveScrolledRoot const*&&)
Unexecuted instantiation: nsDisplayTransform* MakeDisplayItem<nsDisplayTransform, nsSimplePageSequenceFrame*, nsDisplayList*, nsRect, mozilla::gfx::Matrix4x4Typed<mozilla::gfx::UnknownUnits, mozilla::gfx::UnknownUnits> (&)(nsIFrame*, float)>(nsDisplayListBuilder*, nsSimplePageSequenceFrame*&&, nsDisplayList*&&, nsRect&&, mozilla::gfx::Matrix4x4Typed<mozilla::gfx::UnknownUnits, mozilla::gfx::UnknownUnits> (&)(nsIFrame*, float))
Unexecuted instantiation: nsDisplayZoom* MakeDisplayItem<nsDisplayZoom, nsIFrame*&, nsSubDocumentFrame*, nsDisplayList*, int&, int&, nsDisplayOwnLayerFlags&>(nsDisplayListBuilder*, nsIFrame*&, nsSubDocumentFrame*&&, nsDisplayList*&&, int&, int&, nsDisplayOwnLayerFlags&)
Unexecuted instantiation: nsDisplayResolution* MakeDisplayItem<nsDisplayResolution, nsIFrame*&, nsSubDocumentFrame*, nsDisplayList*, nsDisplayOwnLayerFlags&>(nsDisplayListBuilder*, nsIFrame*&, nsSubDocumentFrame*&&, nsDisplayList*&&, nsDisplayOwnLayerFlags&)
Unexecuted instantiation: nsDisplaySubDocument* MakeDisplayItem<nsDisplaySubDocument, nsIFrame*, nsSubDocumentFrame*, nsDisplayList*, nsDisplayOwnLayerFlags&>(nsDisplayListBuilder*, nsIFrame*&&, nsSubDocumentFrame*&&, nsDisplayList*&&, nsDisplayOwnLayerFlags&)
Unexecuted instantiation: nsDisplayText* MakeDisplayItem<nsDisplayText, nsTextFrame*, mozilla::Maybe<bool>&>(nsDisplayListBuilder*, nsTextFrame*&&, mozilla::Maybe<bool>&)
Unexecuted instantiation: nsDisplayVideo* MakeDisplayItem<nsDisplayVideo, nsVideoFrame*>(nsDisplayListBuilder*, nsVideoFrame*&&)
Unexecuted instantiation: nsDisplayButtonBoxShadowOuter* MakeDisplayItem<nsDisplayButtonBoxShadowOuter, nsButtonFrameRenderer*>(nsDisplayListBuilder*, nsButtonFrameRenderer*&&)
Unexecuted instantiation: nsDisplayButtonBorder* MakeDisplayItem<nsDisplayButtonBorder, nsButtonFrameRenderer*>(nsDisplayListBuilder*, nsButtonFrameRenderer*&&)
Unexecuted instantiation: nsDisplayButtonForeground* MakeDisplayItem<nsDisplayButtonForeground, nsButtonFrameRenderer*>(nsDisplayListBuilder*, nsButtonFrameRenderer*&&)
Unexecuted instantiation: nsDisplayComboboxFocus* MakeDisplayItem<nsDisplayComboboxFocus, nsComboboxControlFrame*>(nsDisplayListBuilder*, nsComboboxControlFrame*&&)
Unexecuted instantiation: nsDisplayBoxShadowOuter* MakeDisplayItem<nsDisplayBoxShadowOuter, nsFieldSetFrame*>(nsDisplayListBuilder*, nsFieldSetFrame*&&)
Unexecuted instantiation: nsDisplayFieldSetBorder* MakeDisplayItem<nsDisplayFieldSetBorder, nsFieldSetFrame*>(nsDisplayListBuilder*, nsFieldSetFrame*&&)
Unexecuted instantiation: nsDisplaySolidColor* MakeDisplayItem<nsDisplaySolidColor, nsListControlFrame*, nsRect, unsigned int&>(nsDisplayListBuilder*, nsListControlFrame*&&, nsRect&&, unsigned int&)
Unexecuted instantiation: nsDisplayRangeFocusRing* MakeDisplayItem<nsDisplayRangeFocusRing, nsRangeFrame*>(nsDisplayListBuilder*, nsRangeFrame*&&)
Unexecuted instantiation: nsDisplayOptionEventGrabber* MakeDisplayItem<nsDisplayOptionEventGrabber, nsIFrame*&, nsDisplayList*&>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&)
Unexecuted instantiation: nsDisplayOptionEventGrabber* MakeDisplayItem<nsDisplayOptionEventGrabber, nsIFrame*, nsDisplayItem*&>(nsDisplayListBuilder*, nsIFrame*&&, nsDisplayItem*&)
Unexecuted instantiation: nsDisplayListFocus* MakeDisplayItem<nsDisplayListFocus, nsSelectsAreaFrame*>(nsDisplayListBuilder*, nsSelectsAreaFrame*&&)
Unexecuted instantiation: nsDisplayBorder* MakeDisplayItem<nsDisplayBorder, nsTableCellFrame*>(nsDisplayListBuilder*, nsTableCellFrame*&&)
Unexecuted instantiation: nsDisplayBoxShadowOuter* MakeDisplayItem<nsDisplayBoxShadowOuter, nsTableCellFrame*>(nsDisplayListBuilder*, nsTableCellFrame*&&)
Unexecuted instantiation: nsDisplayBoxShadowInner* MakeDisplayItem<nsDisplayBoxShadowInner, nsTableCellFrame*>(nsDisplayListBuilder*, nsTableCellFrame*&&)
Unexecuted instantiation: nsDisplayTableCellSelection* MakeDisplayItem<nsDisplayTableCellSelection, nsTableCellFrame*>(nsDisplayListBuilder*, nsTableCellFrame*&&)
Unexecuted instantiation: nsDisplayBoxShadowOuter* MakeDisplayItem<nsDisplayBoxShadowOuter, nsFrame*&>(nsDisplayListBuilder*, nsFrame*&)
Unexecuted instantiation: nsDisplayBoxShadowInner* MakeDisplayItem<nsDisplayBoxShadowInner, nsFrame*&>(nsDisplayListBuilder*, nsFrame*&)
Unexecuted instantiation: nsDisplayTableBorderCollapse* MakeDisplayItem<nsDisplayTableBorderCollapse, nsTableFrame*&>(nsDisplayListBuilder*, nsTableFrame*&)
Unexecuted instantiation: nsDisplayBorder* MakeDisplayItem<nsDisplayBorder, nsTableFrame*&>(nsDisplayListBuilder*, nsTableFrame*&)
Unexecuted instantiation: nsDisplaySVGGeometry* MakeDisplayItem<nsDisplaySVGGeometry, mozilla::SVGGeometryFrame*>(nsDisplayListBuilder*, mozilla::SVGGeometryFrame*&&)
Unexecuted instantiation: nsDisplaySVGText* MakeDisplayItem<nsDisplaySVGText, SVGTextFrame*>(nsDisplayListBuilder*, SVGTextFrame*&&)
Unexecuted instantiation: nsDisplayForeignObject* MakeDisplayItem<nsDisplayForeignObject, nsSVGForeignObjectFrame*, nsDisplayList*>(nsDisplayListBuilder*, nsSVGForeignObjectFrame*&&, nsDisplayList*&&)
Unexecuted instantiation: nsDisplayOuterSVG* MakeDisplayItem<nsDisplayOuterSVG, nsSVGOuterSVGFrame*>(nsDisplayListBuilder*, nsSVGOuterSVGFrame*&&)
Unexecuted instantiation: nsDisplaySVGWrapper* MakeDisplayItem<nsDisplaySVGWrapper, nsSVGOuterSVGAnonChildFrame*, nsDisplayList*>(nsDisplayListBuilder*, nsSVGOuterSVGAnonChildFrame*&&, nsDisplayList*&&)
Unexecuted instantiation: nsDisplayXULEventRedirector* MakeDisplayItem<nsDisplayXULEventRedirector, nsIFrame*&, nsDisplayList*&, nsIFrame*&>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&, nsIFrame*&)
Unexecuted instantiation: nsDisplayXULEventRedirector* MakeDisplayItem<nsDisplayXULEventRedirector, nsIFrame*, nsDisplayItem*&, nsIFrame*&>(nsDisplayListBuilder*, nsIFrame*&&, nsDisplayItem*&, nsIFrame*&)
Unexecuted instantiation: nsDisplayOwnLayer* MakeDisplayItem<nsDisplayOwnLayer, nsBoxFrame*, nsDisplayList*, mozilla::ActiveScrolledRoot const*&, nsDisplayOwnLayerFlags, mozilla::layers::ScrollbarData, bool, bool>(nsDisplayListBuilder*, nsBoxFrame*&&, nsDisplayList*&&, mozilla::ActiveScrolledRoot const*&, nsDisplayOwnLayerFlags&&, mozilla::layers::ScrollbarData&&, bool&&, bool&&)
Unexecuted instantiation: nsDisplayXULGroupBorder* MakeDisplayItem<nsDisplayXULGroupBorder, nsGroupBoxFrame*>(nsDisplayListBuilder*, nsGroupBoxFrame*&&)
Unexecuted instantiation: nsDisplayXULImage* MakeDisplayItem<nsDisplayXULImage, nsImageBoxFrame*>(nsDisplayListBuilder*, nsImageBoxFrame*&&)
Unexecuted instantiation: nsDisplayEventReceiver* MakeDisplayItem<nsDisplayEventReceiver, nsLeafBoxFrame*>(nsDisplayListBuilder*, nsLeafBoxFrame*&&)
Unexecuted instantiation: nsDisplayEventReceiver* MakeDisplayItem<nsDisplayEventReceiver, nsSliderFrame*>(nsDisplayListBuilder*, nsSliderFrame*&&)
Unexecuted instantiation: nsDisplayOwnLayer* MakeDisplayItem<nsDisplayOwnLayer, nsSliderFrame*, nsDisplayList*, mozilla::ActiveScrolledRoot const*&, nsDisplayOwnLayerFlags, mozilla::layers::ScrollbarData>(nsDisplayListBuilder*, nsSliderFrame*&&, nsDisplayList*&&, mozilla::ActiveScrolledRoot const*&, nsDisplayOwnLayerFlags&&, mozilla::layers::ScrollbarData&&)
Unexecuted instantiation: nsDisplayEventReceiver* MakeDisplayItem<nsDisplayEventReceiver, nsSplitterFrame*>(nsDisplayListBuilder*, nsSplitterFrame*&&)
Unexecuted instantiation: nsDisplayXULTextBox* MakeDisplayItem<nsDisplayXULTextBox, nsTextBoxFrame*>(nsDisplayListBuilder*, nsTextBoxFrame*&&)
Unexecuted instantiation: nsDisplayTreeBody* MakeDisplayItem<nsDisplayTreeBody, nsTreeBodyFrame*>(nsDisplayListBuilder*, nsTreeBodyFrame*&&)
Unexecuted instantiation: nsDisplayXULTreeColSplitterTarget* MakeDisplayItem<nsDisplayXULTreeColSplitterTarget, nsTreeColFrame*>(nsDisplayListBuilder*, nsTreeColFrame*&&)
Unexecuted instantiation: nsDisplayMathMLSelectionRect* MakeDisplayItem<nsDisplayMathMLSelectionRect, nsIFrame*&, nsRect const&>(nsDisplayListBuilder*, nsIFrame*&, nsRect const&)
Unexecuted instantiation: nsDisplayMathMLCharForeground* MakeDisplayItem<nsDisplayMathMLCharForeground, nsIFrame*&, nsMathMLChar*, unsigned int&, bool>(nsDisplayListBuilder*, nsIFrame*&, nsMathMLChar*&&, unsigned int&, bool&&)
Unexecuted instantiation: nsDisplayMathMLError* MakeDisplayItem<nsDisplayMathMLError, nsMathMLContainerFrame*>(nsDisplayListBuilder*, nsMathMLContainerFrame*&&)
Unexecuted instantiation: nsDisplayMathMLBar* MakeDisplayItem<nsDisplayMathMLBar, nsIFrame*&, nsRect const&, unsigned int&>(nsDisplayListBuilder*, nsIFrame*&, nsRect const&, unsigned int&)
Unexecuted instantiation: nsDisplayNotation* MakeDisplayItem<nsDisplayNotation, nsIFrame*&, nsRect const&, int&, nsMencloseNotation&>(nsDisplayListBuilder*, nsIFrame*&, nsRect const&, int&, nsMencloseNotation&)
Unexecuted instantiation: nsDisplayMathMLSlash* MakeDisplayItem<nsDisplayMathMLSlash, nsIFrame*&, nsRect const&, int&, unsigned char const&>(nsDisplayListBuilder*, nsIFrame*&, nsRect const&, int&, unsigned char const&)
Unexecuted instantiation: nsDisplaymtdBorder* MakeDisplayItem<nsDisplaymtdBorder, nsMathMLmtdFrame*>(nsDisplayListBuilder*, nsMathMLmtdFrame*&&)
Unexecuted instantiation: nsDisplaySolidColorRegion* MakeDisplayItem<nsDisplaySolidColorRegion, nsIFrame*&, nsRegion&, unsigned int&>(nsDisplayListBuilder*, nsIFrame*&, nsRegion&, unsigned int&)
Unexecuted instantiation: nsDisplayCompositorHitTestInfo* MakeDisplayItem<nsDisplayCompositorHitTestInfo, nsIFrame*&, mozilla::gfx::CompositorHitTestInfo&>(nsDisplayListBuilder*, nsIFrame*&, mozilla::gfx::CompositorHitTestInfo&)
Unexecuted instantiation: nsDisplayTableBackgroundColor* MakeDisplayItem<nsDisplayTableBackgroundColor, nsIFrame*&, nsRect&, mozilla::ComputedStyle*&, unsigned int, nsIFrame*&>(nsDisplayListBuilder*, nsIFrame*&, nsRect&, mozilla::ComputedStyle*&, unsigned int&&, nsIFrame*&)
Unexecuted instantiation: nsDisplayBackgroundColor* MakeDisplayItem<nsDisplayBackgroundColor, nsIFrame*&, nsRect&, mozilla::ComputedStyle*&, unsigned int>(nsDisplayListBuilder*, nsIFrame*&, nsRect&, mozilla::ComputedStyle*&, unsigned int&&)
Unexecuted instantiation: nsDisplayClearBackground* MakeDisplayItem<nsDisplayClearBackground, nsIFrame*&>(nsDisplayListBuilder*, nsIFrame*&)
Unexecuted instantiation: nsDisplayTableThemedBackground* MakeDisplayItem<nsDisplayTableThemedBackground, nsIFrame*&, nsRect&, nsIFrame*&>(nsDisplayListBuilder*, nsIFrame*&, nsRect&, nsIFrame*&)
Unexecuted instantiation: nsDisplayThemedBackground* MakeDisplayItem<nsDisplayThemedBackground, nsIFrame*&, nsRect&>(nsDisplayListBuilder*, nsIFrame*&, nsRect&)
Unexecuted instantiation: nsDisplayTableBackgroundImage* MakeDisplayItem<nsDisplayTableBackgroundImage, nsDisplayBackgroundImage::InitData&, nsIFrame*&>(nsDisplayListBuilder*, nsDisplayBackgroundImage::InitData&, nsIFrame*&)
Unexecuted instantiation: nsDisplayBackgroundImage* MakeDisplayItem<nsDisplayBackgroundImage, nsDisplayBackgroundImage::InitData&>(nsDisplayListBuilder*, nsDisplayBackgroundImage::InitData&)
Unexecuted instantiation: nsDisplayTableBlendMode* MakeDisplayItem<nsDisplayTableBlendMode, nsIFrame*&, nsDisplayList*, unsigned char const&, mozilla::ActiveScrolledRoot const*&, unsigned int, nsIFrame*&>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&&, unsigned char const&, mozilla::ActiveScrolledRoot const*&, unsigned int&&, nsIFrame*&)
Unexecuted instantiation: nsDisplayBlendMode* MakeDisplayItem<nsDisplayBlendMode, nsIFrame*&, nsDisplayList*, unsigned char const&, mozilla::ActiveScrolledRoot const*&, unsigned int>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&&, unsigned char const&, mozilla::ActiveScrolledRoot const*&, unsigned int&&)
Unexecuted instantiation: nsDisplayWrapList* MakeDisplayItem<nsDisplayWrapList, nsDisplayWrapList const&>(nsDisplayListBuilder*, nsDisplayWrapList const&)
Unexecuted instantiation: nsDisplayBlendContainer* MakeDisplayItem<nsDisplayBlendContainer, nsIFrame*&, nsDisplayList*&, mozilla::ActiveScrolledRoot const*&, bool>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&, mozilla::ActiveScrolledRoot const*&, bool&&)
Unexecuted instantiation: nsDisplayTableBlendContainer* MakeDisplayItem<nsDisplayTableBlendContainer, nsIFrame*&, nsDisplayList*&, mozilla::ActiveScrolledRoot const*&, bool, nsIFrame*&>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&, mozilla::ActiveScrolledRoot const*&, bool&&, nsIFrame*&)
Unexecuted instantiation: nsDisplayFixedPosition* MakeDisplayItem<nsDisplayFixedPosition, nsIFrame*&, nsDisplayList*, unsigned int>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&&, unsigned int&&)
Unexecuted instantiation: nsDisplayTableFixedPosition* MakeDisplayItem<nsDisplayTableFixedPosition, nsIFrame*&, nsDisplayList*, unsigned int, nsIFrame*&>(nsDisplayListBuilder*, nsIFrame*&, nsDisplayList*&&, unsigned int&&, nsIFrame*&)
2250
2251
/**
2252
 * This is the unit of rendering and event testing. Each instance of this
2253
 * class represents an entity that can be drawn on the screen, e.g., a
2254
 * frame's CSS background, or a frame's text string.
2255
 *
2256
 * nsDisplayItems can be containers --- i.e., they can perform hit testing
2257
 * and painting by recursively traversing a list of child items.
2258
 *
2259
 * These are arena-allocated during display list construction. A typical
2260
 * subclass would just have a frame pointer, so its object would be just three
2261
 * pointers (vtable, next-item, frame).
2262
 *
2263
 * Display items belong to a list at all times (except temporarily as they
2264
 * move from one list to another).
2265
 */
2266
class nsDisplayItem : public nsDisplayItemLink
2267
{
2268
public:
2269
  typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
2270
  typedef mozilla::DisplayItemClip DisplayItemClip;
2271
  typedef mozilla::DisplayItemClipChain DisplayItemClipChain;
2272
  typedef mozilla::ActiveScrolledRoot ActiveScrolledRoot;
2273
  typedef mozilla::layers::FrameMetrics FrameMetrics;
2274
  typedef mozilla::layers::ScrollMetadata ScrollMetadata;
2275
  typedef mozilla::layers::FrameMetrics::ViewID ViewID;
2276
  typedef mozilla::layers::Layer Layer;
2277
  typedef mozilla::layers::LayerManager LayerManager;
2278
  typedef mozilla::layers::StackingContextHelper StackingContextHelper;
2279
  typedef mozilla::layers::WebRenderCommand WebRenderCommand;
2280
  typedef mozilla::layers::WebRenderParentCommand WebRenderParentCommand;
2281
  typedef mozilla::LayerState LayerState;
2282
  typedef mozilla::image::imgDrawingParams imgDrawingParams;
2283
  typedef mozilla::image::ImgDrawResult ImgDrawResult;
2284
  typedef class mozilla::gfx::DrawTarget DrawTarget;
2285
2286
  // This is never instantiated directly (it has pure virtual methods), so no
2287
  // need to count constructors and destructors.
2288
  nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
2289
  nsDisplayItem(nsDisplayListBuilder* aBuilder,
2290
                nsIFrame* aFrame,
2291
                const ActiveScrolledRoot* aActiveScrolledRoot,
2292
                bool aAnonymous = false);
2293
2294
  /**
2295
   * This constructor is only used in rare cases when we need to construct
2296
   * temporary items.
2297
   */
2298
  explicit nsDisplayItem(nsIFrame* aFrame)
2299
    : mFrame(aFrame)
2300
    , mClipChain(nullptr)
2301
    , mClip(nullptr)
2302
    , mActiveScrolledRoot(nullptr)
2303
    , mReferenceFrame(nullptr)
2304
    , mAnimatedGeometryRoot(nullptr)
2305
    , mForceNotVisible(false)
2306
    , mDisableSubpixelAA(false)
2307
    , mReusedItem(false)
2308
    , mBackfaceHidden(mFrame->In3DContextAndBackfaceIsHidden())
2309
    , mPaintRectValid(false)
2310
#ifdef MOZ_DUMP_PAINTING
2311
    , mPainted(false)
2312
#endif
2313
0
  {
2314
0
    MOZ_COUNT_CTOR(nsDisplayItem);
2315
0
  }
2316
2317
  nsDisplayItem() = delete;
2318
2319
protected:
2320
  virtual ~nsDisplayItem()
2321
0
  {
2322
0
    MOZ_COUNT_DTOR(nsDisplayItem);
2323
0
    SetDisplayItemData(nullptr, nullptr);
2324
0
    if (mFrame) {
2325
0
      mFrame->RemoveDisplayItem(this);
2326
0
    }
2327
0
  }
2328
2329
public:
2330
  virtual void Destroy(nsDisplayListBuilder* aBuilder)
2331
0
  {
2332
0
    DisplayItemType type = GetType();
2333
0
    this->~nsDisplayItem();
2334
0
    aBuilder->Destroy(type, this);
2335
0
  }
2336
2337
  virtual void RestoreState()
2338
0
  {
2339
0
    mClipChain = mState.mClipChain;
2340
0
    mClip = mState.mClip;
2341
0
    mDisableSubpixelAA = false;
2342
0
  }
2343
2344
  virtual void RemoveFrame(nsIFrame* aFrame)
2345
0
  {
2346
0
    if (mFrame && aFrame == mFrame) {
2347
0
      MOZ_ASSERT(!mFrame->HasDisplayItem(this));
2348
0
      mFrame = nullptr;
2349
0
      SetDisplayItemData(nullptr, nullptr);
2350
0
    }
2351
0
  }
2352
2353
  /**
2354
   * Downcasts this item to nsDisplayWrapList, if possible.
2355
   */
2356
0
  virtual const nsDisplayWrapList* AsDisplayWrapList() const { return nullptr; }
2357
0
  virtual nsDisplayWrapList* AsDisplayWrapList() { return nullptr; }
2358
2359
  /**
2360
   * Create a clone of this item.
2361
   */
2362
  virtual nsDisplayItem* Clone(nsDisplayListBuilder* aBuilder) const
2363
0
  {
2364
0
    return nullptr;
2365
0
  }
2366
2367
  nsDisplayItem(const nsDisplayItem&) = delete;
2368
  /**
2369
   * The custom copy-constructor is implemented to prevent copying the saved
2370
   * state of the item.
2371
   * This is currently only used when creating temporary items for merging.
2372
   */
2373
  nsDisplayItem(nsDisplayListBuilder* aBuilder, const nsDisplayItem& aOther)
2374
    : mFrame(aOther.mFrame)
2375
    , mClipChain(aOther.mClipChain)
2376
    , mClip(aOther.mClip)
2377
    , mActiveScrolledRoot(aOther.mActiveScrolledRoot)
2378
    , mReferenceFrame(aOther.mReferenceFrame)
2379
    , mAnimatedGeometryRoot(aOther.mAnimatedGeometryRoot)
2380
    , mToReferenceFrame(aOther.mToReferenceFrame)
2381
    , mBuildingRect(aOther.mBuildingRect)
2382
    , mPaintRect(aOther.mPaintRect)
2383
    , mForceNotVisible(aOther.mForceNotVisible)
2384
    , mDisableSubpixelAA(aOther.mDisableSubpixelAA)
2385
    , mReusedItem(false)
2386
    , mBackfaceHidden(mFrame->In3DContextAndBackfaceIsHidden())
2387
    , mPaintRectValid(false)
2388
#ifdef MOZ_DUMP_PAINTING
2389
    , mPainted(false)
2390
#endif
2391
0
  {
2392
0
    MOZ_COUNT_CTOR(nsDisplayItem);
2393
0
  }
2394
2395
  struct HitTestState
2396
  {
2397
    explicit HitTestState()
2398
      : mInPreserves3D(false)
2399
0
    {
2400
0
    }
2401
2402
    ~HitTestState()
2403
0
    {
2404
0
      NS_ASSERTION(mItemBuffer.Length() == 0,
2405
0
                   "mItemBuffer should have been cleared");
2406
0
    }
2407
2408
    // Handling transform items for preserve 3D frames.
2409
    bool mInPreserves3D;
2410
    AutoTArray<nsDisplayItem*, 100> mItemBuffer;
2411
  };
2412
2413
  /**
2414
   * Some consecutive items should be rendered together as a unit, e.g.,
2415
   * outlines for the same element. For this, we need a way for items to
2416
   * identify their type. We use the type for other purposes too.
2417
   */
2418
  virtual DisplayItemType GetType() const = 0;
2419
  /**
2420
   * Pairing this with the GetUnderlyingFrame() pointer gives a key that
2421
   * uniquely identifies this display item in the display item tree.
2422
   * XXX check nsOptionEventGrabberWrapper/nsXULEventRedirectorWrapper
2423
   */
2424
0
  virtual uint32_t GetPerFrameKey() const { return uint32_t(GetType()); }
2425
2426
0
  uint8_t GetFlags() { return GetDisplayItemFlagsForType(GetType()); }
2427
2428
  /**
2429
   * This is called after we've constructed a display list for event handling.
2430
   * When this is called, we've already ensured that aRect intersects the
2431
   * item's bounds and that clipping has been taking into account.
2432
   *
2433
   * @param aRect the point or rect being tested, relative to the reference
2434
   * frame. If the width and height are both 1 app unit, it indicates we're
2435
   * hit testing a point, not a rect.
2436
   * @param aState must point to a HitTestState. If you don't have one,
2437
   * just create one with the default constructor and pass it in.
2438
   * @param aOutFrames each item appends the frame(s) in this display item that
2439
   * the rect is considered over (if any) to aOutFrames.
2440
   */
2441
  virtual void HitTest(nsDisplayListBuilder* aBuilder,
2442
                       const nsRect& aRect,
2443
                       HitTestState* aState,
2444
                       nsTArray<nsIFrame*>* aOutFrames)
2445
0
  {
2446
0
  }
2447
  /**
2448
   * @return the frame that this display item is based on. This is used to sort
2449
   * items by z-index and content order and for some other uses. Never
2450
   * returns null.
2451
   */
2452
  inline nsIFrame* Frame() const
2453
  {
2454
    MOZ_ASSERT(mFrame, "Trying to use display item after deletion!");
2455
    return mFrame;
2456
  }
2457
2458
  /**
2459
   * @return the nsIFrame that provides the style data, and should
2460
   * be checked when deciding if this display item can be reused.
2461
   */
2462
0
  virtual nsIFrame* FrameForInvalidation() const { return mFrame; }
2463
2464
0
  virtual bool HasDeletedFrame() const { return !mFrame; }
2465
2466
0
  virtual nsIFrame* StyleFrame() const { return mFrame; }
2467
2468
  /**
2469
   * Compute the used z-index of our frame; returns zero for elements to which
2470
   * z-index does not apply, and for z-index:auto.
2471
   * @note This can be overridden, @see nsDisplayWrapList::SetOverrideZIndex.
2472
   */
2473
  virtual int32_t ZIndex() const;
2474
  /**
2475
   * The default bounds is the frame border rect.
2476
   * @param aSnap *aSnap is set to true if the returned rect will be
2477
   * snapped to nearest device pixel edges during actual drawing.
2478
   * It might be set to false and snap anyway, so code computing the set of
2479
   * pixels affected by this display item needs to round outwards to pixel
2480
   * boundaries when *aSnap is set to false.
2481
   * This does not take the item's clipping into account.
2482
   * @return a rectangle relative to aBuilder->ReferenceFrame() that
2483
   * contains the area drawn by this display item
2484
   */
2485
  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const
2486
0
  {
2487
0
    *aSnap = false;
2488
0
    return nsRect(ToReferenceFrame(), Frame()->GetSize());
2489
0
  }
2490
2491
  virtual nsRegion GetTightBounds(nsDisplayListBuilder* aBuilder,
2492
                                  bool* aSnap) const
2493
0
  {
2494
0
    *aSnap = false;
2495
0
    return nsRegion();
2496
0
  }
2497
2498
  /**
2499
   * Returns true if nothing will be rendered inside aRect, false if uncertain.
2500
   * aRect is assumed to be contained in this item's bounds.
2501
   */
2502
0
  virtual bool IsInvisibleInRect(const nsRect& aRect) const { return false; }
2503
2504
  /**
2505
   * Returns the result of GetBounds intersected with the item's clip.
2506
   * The intersection is approximate since rounded corners are not taking into
2507
   * account.
2508
   */
2509
  nsRect GetClippedBounds(nsDisplayListBuilder* aBuilder) const;
2510
2511
  nsRect GetBorderRect() const
2512
0
  {
2513
0
    return nsRect(ToReferenceFrame(), Frame()->GetSize());
2514
0
  }
2515
2516
  nsRect GetPaddingRect() const
2517
0
  {
2518
0
    return Frame()->GetPaddingRectRelativeToSelf() + ToReferenceFrame();
2519
0
  }
2520
2521
  nsRect GetContentRect() const
2522
  {
2523
    return Frame()->GetContentRectRelativeToSelf() + ToReferenceFrame();
2524
  }
2525
2526
  /**
2527
   * Checks if the frame(s) owning this display item have been marked as
2528
   * invalid, and needing repainting.
2529
   */
2530
  virtual bool IsInvalid(nsRect& aRect) const
2531
0
  {
2532
0
    bool result = mFrame ? mFrame->IsInvalid(aRect) : false;
2533
0
    aRect += ToReferenceFrame();
2534
0
    return result;
2535
0
  }
2536
2537
  /**
2538
   * Creates and initializes an nsDisplayItemGeometry object that retains the
2539
   * current areas covered by this display item. These need to retain enough
2540
   * information such that they can be compared against a future nsDisplayItem
2541
   * of the same type, and determine if repainting needs to happen.
2542
   *
2543
   * Subclasses wishing to store more information need to override both this
2544
   * and ComputeInvalidationRegion, as well as implementing an
2545
   * nsDisplayItemGeometry subclass.
2546
   *
2547
   * The default implementation tracks both the display item bounds, and the
2548
   * frame's border rect.
2549
   */
2550
  virtual nsDisplayItemGeometry* AllocateGeometry(
2551
    nsDisplayListBuilder* aBuilder)
2552
0
  {
2553
0
    return new nsDisplayItemGenericGeometry(this, aBuilder);
2554
0
  }
2555
2556
  /**
2557
   * Compares an nsDisplayItemGeometry object from a previous paint against the
2558
   * current item. Computes if the geometry of the item has changed, and the
2559
   * invalidation area required for correct repainting.
2560
   *
2561
   * The existing geometry will have been created from a display item with a
2562
   * matching GetPerFrameKey()/mFrame pair to the current item.
2563
   *
2564
   * The default implementation compares the display item bounds, and the
2565
   * frame's border rect, and invalidates the entire bounds if either rect
2566
   * changes.
2567
   *
2568
   * @param aGeometry The geometry of the matching display item from the
2569
   * previous paint.
2570
   * @param aInvalidRegion Output param, the region to invalidate, or
2571
   * unchanged if none.
2572
   */
2573
  virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
2574
                                         const nsDisplayItemGeometry* aGeometry,
2575
                                         nsRegion* aInvalidRegion) const
2576
0
  {
2577
0
    const nsDisplayItemGenericGeometry* geometry =
2578
0
      static_cast<const nsDisplayItemGenericGeometry*>(aGeometry);
2579
0
    bool snap;
2580
0
    if (!geometry->mBounds.IsEqualInterior(GetBounds(aBuilder, &snap)) ||
2581
0
        !geometry->mBorderRect.IsEqualInterior(GetBorderRect())) {
2582
0
      aInvalidRegion->Or(GetBounds(aBuilder, &snap), geometry->mBounds);
2583
0
    }
2584
0
  }
2585
2586
  /**
2587
   * An alternative default implementation of ComputeInvalidationRegion,
2588
   * that instead invalidates only the changed area between the two items.
2589
   */
2590
  void ComputeInvalidationRegionDifference(
2591
    nsDisplayListBuilder* aBuilder,
2592
    const nsDisplayItemBoundsGeometry* aGeometry,
2593
    nsRegion* aInvalidRegion) const
2594
0
  {
2595
0
    bool snap;
2596
0
    nsRect bounds = GetBounds(aBuilder, &snap);
2597
0
2598
0
    if (!aGeometry->mBounds.IsEqualInterior(bounds)) {
2599
0
      nscoord radii[8];
2600
0
      if (aGeometry->mHasRoundedCorners || Frame()->GetBorderRadii(radii)) {
2601
0
        aInvalidRegion->Or(aGeometry->mBounds, bounds);
2602
0
      } else {
2603
0
        aInvalidRegion->Xor(aGeometry->mBounds, bounds);
2604
0
      }
2605
0
    }
2606
0
  }
2607
2608
  /**
2609
   * This function is called when an item's list of children has been omdified
2610
   * by RetaineDisplayListBuilder.
2611
   */
2612
0
  virtual void InvalidateCachedChildInfo() {}
2613
2614
  /**
2615
   * @param aSnap set to true if the edges of the rectangles of the opaque
2616
   * region would be snapped to device pixels when drawing
2617
   * @return a region of the item that is opaque --- that is, every pixel
2618
   * that is visible is painted with an opaque
2619
   * color. This is useful for determining when one piece
2620
   * of content completely obscures another so that we can do occlusion
2621
   * culling.
2622
   * This does not take clipping into account.
2623
   */
2624
  virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
2625
                                   bool* aSnap) const
2626
0
  {
2627
0
    *aSnap = false;
2628
0
    return nsRegion();
2629
0
  }
2630
  /**
2631
   * @return Some(nscolor) if the item is guaranteed to paint every pixel in its
2632
   * bounds with the same (possibly translucent) color
2633
   */
2634
  virtual mozilla::Maybe<nscolor> IsUniform(
2635
    nsDisplayListBuilder* aBuilder) const
2636
0
  {
2637
0
    return mozilla::Nothing();
2638
0
  }
2639
2640
  /**
2641
   * @return true if the contents of this item are rendered fixed relative
2642
   * to the nearest viewport.
2643
   */
2644
  virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) const
2645
0
  {
2646
0
    return false;
2647
0
  }
2648
2649
0
  virtual bool ClearsBackground() const { return false; }
2650
2651
  /**
2652
   * Returns true if all layers that can be active should be forced to be
2653
   * active. Requires setting the pref layers.force-active=true.
2654
   */
2655
  static bool ForceActiveLayers();
2656
2657
  /**
2658
   * @return LAYER_NONE if BuildLayer will return null. In this case
2659
   * there is no layer for the item, and Paint should be called instead
2660
   * to paint the content using Thebes.
2661
   * Return LAYER_INACTIVE if there is a layer --- BuildLayer will
2662
   * not return null (unless there's an error) --- but the layer contents
2663
   * are not changing frequently. In this case it makes sense to composite
2664
   * the layer into a PaintedLayer with other content, so we don't have to
2665
   * recomposite it every time we paint.
2666
   * Note: GetLayerState is only allowed to return LAYER_INACTIVE if all
2667
   * descendant display items returned LAYER_INACTIVE or LAYER_NONE. Also,
2668
   * all descendant display item frames must have an active scrolled root
2669
   * that's either the same as this item's frame's active scrolled root, or
2670
   * a descendant of this item's frame. This ensures that the entire
2671
   * set of display items can be collapsed onto a single PaintedLayer.
2672
   * Return LAYER_ACTIVE if the layer is active, that is, its contents are
2673
   * changing frequently. In this case it makes sense to keep the layer
2674
   * as a separate buffer in VRAM and composite it into the destination
2675
   * every time we paint.
2676
   *
2677
   * Users of GetLayerState should check ForceActiveLayers() and if it returns
2678
   * true, change a returned value of LAYER_INACTIVE to LAYER_ACTIVE.
2679
   */
2680
  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
2681
                                   LayerManager* aManager,
2682
                                   const ContainerLayerParameters& aParameters)
2683
0
  {
2684
0
    return mozilla::LAYER_NONE;
2685
0
  }
2686
2687
  /**
2688
   * Return true to indicate the layer should be constructed even if it's
2689
   * completely invisible.
2690
   */
2691
  virtual bool ShouldBuildLayerEvenIfInvisible(
2692
    nsDisplayListBuilder* aBuilder) const
2693
0
  {
2694
0
    return false;
2695
0
  }
2696
2697
  /**
2698
   * Returns true if this item supports PaintWithClip, where the clipping
2699
   * is used directly as the primitive geometry instead of needing an explicit
2700
   * clip.
2701
   */
2702
0
  virtual bool CanPaintWithClip(const DisplayItemClip& aClip) { return false; }
2703
2704
  /**
2705
   * Actually paint this item to some rendering context.
2706
   * Content outside mVisibleRect need not be painted.
2707
   * aCtx must be set up as for nsDisplayList::Paint.
2708
   */
2709
0
  virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {}
2710
2711
  /**
2712
   * Same as Paint, except provides a clip to use the geometry to draw with.
2713
   * Must not be called unless CanPaintWithClip returned true.
2714
   */
2715
  virtual void PaintWithClip(nsDisplayListBuilder* aBuilder,
2716
                             gfxContext* aCtx,
2717
                             const DisplayItemClip& aClip)
2718
0
  {
2719
0
  }
2720
2721
#ifdef MOZ_DUMP_PAINTING
2722
  /**
2723
   * Mark this display item as being painted via
2724
   * FrameLayerBuilder::DrawPaintedLayer.
2725
   */
2726
  bool Painted() const { return mPainted; }
2727
2728
  /**
2729
   * Check if this display item has been painted.
2730
   */
2731
  void SetPainted() { mPainted = true; }
2732
#endif
2733
2734
  /**
2735
   * Get the layer drawn by this display item. Call this only if
2736
   * GetLayerState() returns something other than LAYER_NONE.
2737
   * If GetLayerState returned LAYER_NONE then Paint will be called
2738
   * instead.
2739
   * This is called while aManager is in the construction phase.
2740
   *
2741
   * The caller (nsDisplayList) is responsible for setting the visible
2742
   * region of the layer.
2743
   *
2744
   * @param aContainerParameters should be passed to
2745
   * FrameLayerBuilder::BuildContainerLayerFor if a ContainerLayer is
2746
   * constructed.
2747
   */
2748
  virtual already_AddRefed<Layer> BuildLayer(
2749
    nsDisplayListBuilder* aBuilder,
2750
    LayerManager* aManager,
2751
    const ContainerLayerParameters& aContainerParameters)
2752
0
  {
2753
0
    return nullptr;
2754
0
  }
2755
2756
  /**
2757
   * Function to create the WebRenderCommands.
2758
   * We should check if the layer state is
2759
   * active first and have an early return if the layer state is
2760
   * not active.
2761
   *
2762
   * @return true if successfully creating webrender commands.
2763
   */
2764
  virtual bool CreateWebRenderCommands(
2765
    mozilla::wr::DisplayListBuilder& aBuilder,
2766
    mozilla::wr::IpcResourceUpdateQueue& aResources,
2767
    const StackingContextHelper& aSc,
2768
    mozilla::layers::WebRenderLayerManager* aManager,
2769
    nsDisplayListBuilder* aDisplayListBuilder)
2770
0
  {
2771
0
    return false;
2772
0
  }
2773
2774
  /**
2775
   * Updates the provided aLayerData with any APZ-relevant scroll data
2776
   * that is specific to this display item. This is stuff that would normally
2777
   * be put on the layer during BuildLayer, but this is only called in
2778
   * layers-free webrender mode, where we don't have layers.
2779
   *
2780
   * This function returns true if and only if it has APZ-relevant scroll data
2781
   * to provide. Note that the arguments passed in may be nullptr, in which case
2782
   * the function should still return true if and only if it has APZ-relevant
2783
   * scroll data, but obviously in this case it can't actually put the
2784
   * data onto aLayerData, because there isn't one.
2785
   *
2786
   * This function assumes that aData and aLayerData will either both be null,
2787
   * or will both be non-null. The caller is responsible for enforcing this.
2788
   */
2789
  virtual bool UpdateScrollData(
2790
    mozilla::layers::WebRenderScrollData* aData,
2791
    mozilla::layers::WebRenderLayerScrollData* aLayerData)
2792
0
  {
2793
0
    return false;
2794
0
  }
2795
2796
  /**
2797
   * On entry, aVisibleRegion contains the region (relative to ReferenceFrame())
2798
   * which may be visible. If the display item opaquely covers an area, it
2799
   * can remove that area from aVisibleRegion before returning.
2800
   * nsDisplayList::ComputeVisibility automatically subtracts the region
2801
   * returned by GetOpaqueRegion, and automatically removes items whose bounds
2802
   * do not intersect the visible area, so implementations of
2803
   * nsDisplayItem::ComputeVisibility do not need to do these things.
2804
   * nsDisplayList::ComputeVisibility will already have set mVisibleRect on
2805
   * this item to the intersection of *aVisibleRegion and this item's bounds.
2806
   * We rely on that, so this should only be called by
2807
   * nsDisplayList::ComputeVisibility or nsDisplayItem::RecomputeVisibility.
2808
   * aAllowVisibleRegionExpansion is a rect where we are allowed to
2809
   * expand the visible region and is only used for making sure the
2810
   * background behind a plugin is visible.
2811
   * This method needs to be idempotent.
2812
   *
2813
   * @return true if the item is visible, false if no part of the item
2814
   * is visible.
2815
   */
2816
  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
2817
                                 nsRegion* aVisibleRegion);
2818
2819
  /**
2820
   * Checks if the given display item can be merged with this item.
2821
   * @return true if the merging is possible, otherwise false.
2822
   */
2823
0
  virtual bool CanMerge(const nsDisplayItem* aItem) const { return false; }
2824
2825
  /**
2826
   * Try to merge with the other item (which is below us in the display
2827
   * list). This gets used by nsDisplayClip to coalesce clipping operations
2828
   * (optimization), by nsDisplayOpacity to merge rendering for the same
2829
   * content element into a single opacity group (correctness), and will be
2830
   * used by nsDisplayOutline to merge multiple outlines for the same element
2831
   * (also for correctness).
2832
   */
2833
0
  virtual void Merge(const nsDisplayItem* aItem) {}
2834
2835
  /**
2836
   * Merges the given display list to this item.
2837
   */
2838
  virtual void MergeDisplayListFromItem(nsDisplayListBuilder* aBuilder,
2839
                                        const nsDisplayItem* aItem)
2840
0
  {
2841
0
  }
2842
2843
  /**
2844
   * Appends the underlying frames of all display items that have been
2845
   * merged into this one (excluding  this item's own underlying frame)
2846
   * to aFrames.
2847
   */
2848
0
  virtual void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) const {}
2849
2850
0
  virtual bool HasMergedFrames() const { return false; }
2851
2852
  /**
2853
   * During the visibility computation and after TryMerge, display lists may
2854
   * return true here to flatten themselves away, removing them. This
2855
   * flattening is distinctly different from FlattenTo, which occurs before
2856
   * items are merged together.
2857
   */
2858
  virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
2859
0
  {
2860
0
    return false;
2861
0
  }
2862
2863
  /**
2864
   * Returns true if this item needs to have its geometry updated, despite
2865
   * returning empty invalidation region.
2866
   */
2867
0
  virtual bool NeedsGeometryUpdates() const { return false; }
2868
2869
  /**
2870
   * Some items such as those calling into the native themed widget machinery
2871
   * have to be painted on the content process. In this case it is best to avoid
2872
   * allocating layers that serializes and forwards the work to the compositor.
2873
   */
2874
0
  virtual bool MustPaintOnContentSide() const { return false; }
2875
2876
  /**
2877
   * If this has a child list where the children are in the same coordinate
2878
   * system as this item (i.e., they have the same reference frame),
2879
   * return the list.
2880
   */
2881
  virtual RetainedDisplayList* GetSameCoordinateSystemChildren() const
2882
0
  {
2883
0
    return nullptr;
2884
0
  }
2885
2886
0
  virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) {}
2887
  /**
2888
   * Do UpdateBounds() for items with frames establishing or extending
2889
   * 3D rendering context.
2890
   *
2891
   * This function is called by UpdateBoundsFor3D() of
2892
   * nsDisplayTransform(), and it is called by
2893
   * BuildDisplayListForStackingContext() on transform items
2894
   * establishing 3D rendering context.
2895
   *
2896
   * The bounds of a transform item with the frame establishing 3D
2897
   * rendering context should be computed by calling
2898
   * DoUpdateBoundsPreserves3D() on all descendants that participate
2899
   * the same 3d rendering context.
2900
   */
2901
0
  virtual void DoUpdateBoundsPreserves3D(nsDisplayListBuilder* aBuilder) {}
2902
2903
  /**
2904
   * If this has a child list, return it, even if the children are in
2905
   * a different coordinate system to this item.
2906
   */
2907
0
  virtual RetainedDisplayList* GetChildren() const { return nullptr; }
2908
2909
  /**
2910
   * Returns the building rectangle used by nsDisplayListBuilder when
2911
   * this item was constructed.
2912
   */
2913
  const nsRect& GetBuildingRect() const { return mBuildingRect; }
2914
2915
  void SetBuildingRect(const nsRect& aBuildingRect)
2916
0
  {
2917
0
    if (aBuildingRect == mBuildingRect) {
2918
0
      // Avoid unnecessary paint rect recompution when the
2919
0
      // building rect is staying the same.
2920
0
      return;
2921
0
    }
2922
0
    mPaintRect = mBuildingRect = aBuildingRect;
2923
0
    mPaintRectValid = false;
2924
0
  }
2925
2926
  void SetPaintRect(const nsRect& aPaintRect)
2927
  {
2928
    mPaintRect = aPaintRect;
2929
    mPaintRectValid = true;
2930
  }
2931
0
  bool HasPaintRect() const { return mPaintRectValid; }
2932
2933
  /**
2934
   * Returns the building rect for the children, relative to their
2935
   * reference frame. Can be different from mBuildingRect for
2936
   * nsDisplayTransform, since the reference frame for the children is different
2937
   * from the reference frame for the item itself.
2938
   */
2939
  virtual const nsRect& GetBuildingRectForChildren() const
2940
0
  {
2941
0
    return mBuildingRect;
2942
0
  }
2943
2944
  /**
2945
   * Stores the given opacity value to be applied when drawing. It is an error
2946
   * to call this if CanApplyOpacity returned false.
2947
   */
2948
  virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
2949
                            float aOpacity,
2950
                            const DisplayItemClipChain* aClip)
2951
0
  {
2952
0
    NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity not supported on this type");
2953
0
  }
2954
  /**
2955
   * Returns true if this display item would return true from ApplyOpacity
2956
   * without actually applying the opacity. Otherwise returns false.
2957
   */
2958
0
  virtual bool CanApplyOpacity() const { return false; }
2959
2960
0
  bool ForceNotVisible() const { return mForceNotVisible; }
2961
2962
  /**
2963
   * For debugging and stuff
2964
   */
2965
  virtual const char* Name() const = 0;
2966
2967
0
  virtual void WriteDebugInfo(std::stringstream& aStream) {}
2968
2969
  nsDisplayItem* GetAbove() { return mAbove; }
2970
2971
  /**
2972
   * Like ComputeVisibility, but does the work that nsDisplayList
2973
   * does per-item:
2974
   * -- Intersects GetBounds with aVisibleRegion and puts the result
2975
   * in mVisibleRect
2976
   * -- Subtracts bounds from aVisibleRegion if the item is opaque
2977
   */
2978
  bool RecomputeVisibility(nsDisplayListBuilder* aBuilder,
2979
                           nsRegion* aVisibleRegion);
2980
2981
  /**
2982
   * Returns the result of aBuilder->ToReferenceFrame(GetUnderlyingFrame())
2983
   */
2984
  const nsPoint& ToReferenceFrame() const
2985
0
  {
2986
0
    NS_ASSERTION(mFrame, "No frame?");
2987
0
    return mToReferenceFrame;
2988
0
  }
2989
  /**
2990
   * @return the root of the display list's frame (sub)tree, whose origin
2991
   * establishes the coordinate system for the display list
2992
   */
2993
  const nsIFrame* ReferenceFrame() const { return mReferenceFrame; }
2994
2995
  /**
2996
   * Returns the reference frame for display item children of this item.
2997
   */
2998
  virtual const nsIFrame* ReferenceFrameForChildren() const
2999
0
  {
3000
0
    return mReferenceFrame;
3001
0
  }
3002
3003
  AnimatedGeometryRoot* GetAnimatedGeometryRoot() const
3004
0
  {
3005
0
    MOZ_ASSERT(mAnimatedGeometryRoot,
3006
0
               "Must have cached AGR before accessing it!");
3007
0
    return mAnimatedGeometryRoot;
3008
0
  }
3009
3010
  virtual struct AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata()
3011
    const
3012
0
  {
3013
0
    return GetAnimatedGeometryRoot();
3014
0
  }
3015
3016
  /**
3017
   * Checks if this display item (or any children) contains content that might
3018
   * be rendered with component alpha (e.g. subpixel antialiasing). Returns the
3019
   * bounds of the area that needs component alpha, or an empty rect if nothing
3020
   * in the item does.
3021
   */
3022
  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const
3023
0
  {
3024
0
    return nsRect();
3025
0
  }
3026
3027
  /**
3028
   * Disable usage of component alpha. Currently only relevant for items that
3029
   * have text.
3030
   */
3031
0
  void DisableComponentAlpha() { mDisableSubpixelAA = true; }
3032
3033
0
  bool IsSubpixelAADisabled() const { return mDisableSubpixelAA; }
3034
3035
  /**
3036
   * Check if we can add async animations to the layer for this display item.
3037
   */
3038
  virtual bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder)
3039
0
  {
3040
0
    return false;
3041
0
  }
3042
3043
0
  virtual bool SupportsOptimizingToImage() const { return false; }
3044
3045
  const DisplayItemClip& GetClip() const
3046
  {
3047
    return mClip ? *mClip : DisplayItemClip::NoClip();
3048
  }
3049
  void IntersectClip(nsDisplayListBuilder* aBuilder,
3050
                     const DisplayItemClipChain* aOther,
3051
                     bool aStore);
3052
3053
  virtual void SetActiveScrolledRoot(
3054
    const ActiveScrolledRoot* aActiveScrolledRoot)
3055
0
  {
3056
0
    mActiveScrolledRoot = aActiveScrolledRoot;
3057
0
  }
3058
  const ActiveScrolledRoot* GetActiveScrolledRoot() const
3059
  {
3060
    return mActiveScrolledRoot;
3061
  }
3062
3063
  virtual void SetClipChain(const DisplayItemClipChain* aClipChain,
3064
                            bool aStore);
3065
  const DisplayItemClipChain* GetClipChain() const { return mClipChain; }
3066
3067
  /**
3068
   * Intersect all clips in our clip chain up to (and including) aASR and set
3069
   * set the intersection as this item's clip.
3070
   */
3071
  void FuseClipChainUpTo(nsDisplayListBuilder* aBuilder,
3072
                         const ActiveScrolledRoot* aASR);
3073
3074
  bool BackfaceIsHidden() const { return mFrame->BackfaceIsHidden(); }
3075
3076
0
  bool In3DContextAndBackfaceIsHidden() { return mBackfaceHidden; }
3077
3078
  bool HasDifferentFrame(const nsDisplayItem* aOther) const
3079
0
  {
3080
0
    return mFrame != aOther->mFrame;
3081
0
  }
3082
3083
  bool HasSameTypeAndClip(const nsDisplayItem* aOther) const
3084
0
  {
3085
0
    return GetPerFrameKey() == aOther->GetPerFrameKey() &&
3086
0
           GetClipChain() == aOther->GetClipChain();
3087
0
  }
3088
3089
  bool HasSameContent(const nsDisplayItem* aOther) const
3090
0
  {
3091
0
    return mFrame->GetContent() == aOther->Frame()->GetContent();
3092
0
  }
3093
3094
0
  bool IsReused() const { return mReusedItem; }
3095
3096
0
  void SetReused(bool aReused) { mReusedItem = aReused; }
3097
3098
0
  virtual bool CanBeReused() const { return true; }
3099
3100
0
  virtual nsIFrame* GetDependentFrame() { return nullptr; }
3101
3102
  virtual mozilla::Maybe<nsRect> GetClipWithRespectToASR(
3103
    nsDisplayListBuilder* aBuilder,
3104
    const ActiveScrolledRoot* aASR) const;
3105
3106
  void SetDisplayItemData(mozilla::DisplayItemData* aDID,
3107
                          mozilla::layers::LayerManager* aLayerManager)
3108
0
  {
3109
0
    if (mDisplayItemData) {
3110
0
      MOZ_ASSERT(!mDisplayItemData->GetItem() ||
3111
0
                 mDisplayItemData->GetItem() == this);
3112
0
      mDisplayItemData->SetItem(nullptr);
3113
0
    }
3114
0
    if (aDID) {
3115
0
      if (aDID->GetItem()) {
3116
0
        aDID->GetItem()->SetDisplayItemData(nullptr, nullptr);
3117
0
      }
3118
0
      aDID->SetItem(this);
3119
0
    }
3120
0
    mDisplayItemData = aDID;
3121
0
    mDisplayItemDataLayerManager = aLayerManager;
3122
0
  }
3123
3124
0
  mozilla::DisplayItemData* GetDisplayItemData() { return mDisplayItemData; }
3125
  mozilla::layers::LayerManager* GetDisplayItemDataLayerManager()
3126
0
  {
3127
0
    return mDisplayItemDataLayerManager;
3128
0
  }
3129
3130
  // Set the nsDisplayList that this item belongs to, and what
3131
  // index it is within that list. Temporary state for merging
3132
  // used by RetainedDisplayListBuilder.
3133
  void SetOldListIndex(nsDisplayList* aList,
3134
                       OldListIndex aIndex,
3135
                       uint32_t aListKey,
3136
                       uint32_t aNestingDepth)
3137
0
  {
3138
0
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
3139
0
    mOldListKey = aListKey;
3140
0
    mOldNestingDepth = aNestingDepth;
3141
0
#endif
3142
0
    mOldList = reinterpret_cast<uintptr_t>(aList);
3143
0
    mOldListIndex = aIndex;
3144
0
  }
3145
  bool GetOldListIndex(nsDisplayList* aList,
3146
                       uint32_t aListKey,
3147
                       OldListIndex* aOutIndex)
3148
0
  {
3149
0
    if (mOldList != reinterpret_cast<uintptr_t>(aList)) {
3150
0
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
3151
0
      MOZ_CRASH_UNSAFE_PRINTF("Item found was in the wrong list! type %d "
3152
0
                              "(outer type was %d at depth %d, now is %d)",
3153
0
                              GetPerFrameKey(),
3154
0
                              mOldListKey,
3155
0
                              mOldNestingDepth,
3156
0
                              aListKey);
3157
0
#endif
3158
0
      return false;
3159
0
    }
3160
0
    *aOutIndex = mOldListIndex;
3161
0
    return true;
3162
0
  }
3163
3164
  const nsRect& GetPaintRect() const { return mPaintRect; }
3165
3166
protected:
3167
  typedef bool (*PrefFunc)(void);
3168
  bool ShouldUseAdvancedLayer(LayerManager* aManager, PrefFunc aFunc) const;
3169
  bool CanUseAdvancedLayer(LayerManager* aManager) const;
3170
3171
  nsIFrame* mFrame;
3172
  RefPtr<const DisplayItemClipChain> mClipChain;
3173
  const DisplayItemClip* mClip;
3174
  RefPtr<const ActiveScrolledRoot> mActiveScrolledRoot;
3175
  // Result of FindReferenceFrameFor(mFrame), if mFrame is non-null
3176
  const nsIFrame* mReferenceFrame;
3177
  RefPtr<struct AnimatedGeometryRoot> mAnimatedGeometryRoot;
3178
  // Result of ToReferenceFrame(mFrame), if mFrame is non-null
3179
  nsPoint mToReferenceFrame;
3180
  mozilla::DisplayItemData* mDisplayItemData = nullptr;
3181
  mozilla::layers::LayerManager* mDisplayItemDataLayerManager = nullptr;
3182
3183
private:
3184
  // This is the rectangle that nsDisplayListBuilder was using as the visible
3185
  // rect to decide which items to construct.
3186
  nsRect mBuildingRect;
3187
3188
  // nsDisplayList::ComputeVisibility sets this to the visible region
3189
  // of the item by intersecting the visible region with the bounds
3190
  // of the item. Paint implementations can use this to limit their drawing.
3191
  // Guaranteed to be contained in GetBounds().
3192
  nsRect mPaintRect;
3193
3194
protected:
3195
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
3196
public:
3197
  uint32_t mOldListKey = 0;
3198
  uint32_t mOldNestingDepth = 0;
3199
  bool mMergedItem = false;
3200
  bool mPreProcessedItem = false;
3201
3202
protected:
3203
#endif
3204
  OldListIndex mOldListIndex;
3205
  uintptr_t mOldList = 0;
3206
3207
  bool mForceNotVisible;
3208
  bool mDisableSubpixelAA;
3209
  bool mReusedItem;
3210
  bool mBackfaceHidden;
3211
  bool mPaintRectValid;
3212
#ifdef MOZ_DUMP_PAINTING
3213
  // True if this frame has been painted.
3214
  bool mPainted;
3215
#endif
3216
3217
  struct
3218
  {
3219
    RefPtr<const DisplayItemClipChain> mClipChain;
3220
    const DisplayItemClip* mClip;
3221
  } mState;
3222
};
3223
3224
/**
3225
 * Manages a singly-linked list of display list items.
3226
 *
3227
 * mSentinel is the sentinel list value, the first value in the null-terminated
3228
 * linked list of items. mTop is the last item in the list (whose 'above'
3229
 * pointer is null). This class has no virtual methods. So list objects are just
3230
 * two pointers.
3231
 *
3232
 * Stepping upward through this list is very fast. Stepping downward is very
3233
 * slow so we don't support it. The methods that need to step downward
3234
 * (HitTest(), ComputeVisibility()) internally build a temporary array of all
3235
 * the items while they do the downward traversal, so overall they're still
3236
 * linear time. We have optimized for efficient AppendToTop() of both
3237
 * items and lists, with minimal codesize. AppendToBottom() is efficient too.
3238
 */
3239
class nsDisplayList
3240
{
3241
public:
3242
  typedef mozilla::ActiveScrolledRoot ActiveScrolledRoot;
3243
  typedef mozilla::layers::Layer Layer;
3244
  typedef mozilla::layers::LayerManager LayerManager;
3245
  typedef mozilla::layers::PaintedLayer PaintedLayer;
3246
3247
  /**
3248
   * Create an empty list.
3249
   */
3250
  nsDisplayList()
3251
    : mLength(0)
3252
    , mIsOpaque(false)
3253
    , mForceTransparentSurface(false)
3254
0
  {
3255
0
    mTop = &mSentinel;
3256
0
    mSentinel.mAbove = nullptr;
3257
0
  }
3258
3259
  virtual ~nsDisplayList()
3260
0
  {
3261
0
    if (mSentinel.mAbove) {
3262
0
      NS_WARNING("Nonempty list left over?");
3263
0
    }
3264
0
  }
3265
3266
  nsDisplayList(nsDisplayList&& aOther)
3267
0
  {
3268
0
    mIsOpaque = aOther.mIsOpaque;
3269
0
    mForceTransparentSurface = aOther.mForceTransparentSurface;
3270
0
3271
0
    if (aOther.mSentinel.mAbove) {
3272
0
      AppendToTop(&aOther);
3273
0
    } else {
3274
0
      mTop = &mSentinel;
3275
0
      mLength = 0;
3276
0
    }
3277
0
  }
3278
3279
  nsDisplayList& operator=(nsDisplayList&& aOther)
3280
  {
3281
    if (this != &aOther) {
3282
      if (aOther.mSentinel.mAbove) {
3283
        nsDisplayList tmp;
3284
        tmp.AppendToTop(&aOther);
3285
        aOther.AppendToTop(this);
3286
        AppendToTop(&tmp);
3287
      } else {
3288
        mTop = &mSentinel;
3289
        mLength = 0;
3290
      }
3291
      mIsOpaque = aOther.mIsOpaque;
3292
      mForceTransparentSurface = aOther.mForceTransparentSurface;
3293
    }
3294
    return *this;
3295
  }
3296
3297
  nsDisplayList(const nsDisplayList&) = delete;
3298
  nsDisplayList& operator=(const nsDisplayList& aOther) = delete;
3299
3300
  /**
3301
   * Append an item to the top of the list. The item must not currently
3302
   * be in a list and cannot be null.
3303
   */
3304
  void AppendToTop(nsDisplayItem* aItem)
3305
0
  {
3306
0
    MOZ_ASSERT(aItem, "No item to append!");
3307
0
    MOZ_ASSERT(!aItem->mAbove, "Already in a list!");
3308
0
    mTop->mAbove = aItem;
3309
0
    mTop = aItem;
3310
0
    mLength++;
3311
0
  }
3312
3313
  /**
3314
   * Append a new item to the bottom of the list. The item must be non-null
3315
   * and not already in a list.
3316
   */
3317
  void AppendToBottom(nsDisplayItem* aItem)
3318
0
  {
3319
0
    MOZ_ASSERT(aItem, "No item to append!");
3320
0
    MOZ_ASSERT(!aItem->mAbove, "Already in a list!");
3321
0
    aItem->mAbove = mSentinel.mAbove;
3322
0
    mSentinel.mAbove = aItem;
3323
0
    if (mTop == &mSentinel) {
3324
0
      mTop = aItem;
3325
0
    }
3326
0
    mLength++;
3327
0
  }
3328
3329
  /**
3330
   * Removes all items from aList and appends them to the top of this list
3331
   */
3332
  void AppendToTop(nsDisplayList* aList)
3333
0
  {
3334
0
    if (aList->mSentinel.mAbove) {
3335
0
      mTop->mAbove = aList->mSentinel.mAbove;
3336
0
      mTop = aList->mTop;
3337
0
      aList->mTop = &aList->mSentinel;
3338
0
      aList->mSentinel.mAbove = nullptr;
3339
0
      mLength += aList->mLength;
3340
0
      aList->mLength = 0;
3341
0
    }
3342
0
  }
3343
3344
  /**
3345
   * Removes all items from aList and prepends them to the bottom of this list
3346
   */
3347
  void AppendToBottom(nsDisplayList* aList)
3348
  {
3349
    if (aList->mSentinel.mAbove) {
3350
      aList->mTop->mAbove = mSentinel.mAbove;
3351
      mSentinel.mAbove = aList->mSentinel.mAbove;
3352
      if (mTop == &mSentinel) {
3353
        mTop = aList->mTop;
3354
      }
3355
3356
      aList->mTop = &aList->mSentinel;
3357
      aList->mSentinel.mAbove = nullptr;
3358
      mLength += aList->mLength;
3359
      aList->mLength = 0;
3360
    }
3361
  }
3362
3363
  /**
3364
   * Remove an item from the bottom of the list and return it.
3365
   */
3366
  nsDisplayItem* RemoveBottom();
3367
3368
  /**
3369
   * Remove all items from the list and call their destructors.
3370
   */
3371
  virtual void DeleteAll(nsDisplayListBuilder* aBuilder);
3372
3373
  /**
3374
   * @return the item at the top of the list, or null if the list is empty
3375
   */
3376
  nsDisplayItem* GetTop() const
3377
0
  {
3378
0
    return mTop != &mSentinel ? static_cast<nsDisplayItem*>(mTop) : nullptr;
3379
0
  }
3380
  /**
3381
   * @return the item at the bottom of the list, or null if the list is empty
3382
   */
3383
  nsDisplayItem* GetBottom() const { return mSentinel.mAbove; }
3384
0
  bool IsEmpty() const { return mTop == &mSentinel; }
3385
3386
  /**
3387
   * @return the number of items in the list
3388
   */
3389
0
  uint32_t Count() const { return mLength; }
3390
  /**
3391
   * Stable sort the list by the z-order of GetUnderlyingFrame() on
3392
   * each item. 'auto' is counted as zero.
3393
   * It is assumed that the list is already in content document order.
3394
   */
3395
  void SortByZOrder();
3396
  /**
3397
   * Stable sort the list by the tree order of the content of
3398
   * GetUnderlyingFrame() on each item. z-index is ignored.
3399
   * @param aCommonAncestor a common ancestor of all the content elements
3400
   * associated with the display items, for speeding up tree order
3401
   * checks, or nullptr if not known; it's only a hint, if it is not an
3402
   * ancestor of some elements, then we lose performance but not correctness
3403
   */
3404
  void SortByContentOrder(nsIContent* aCommonAncestor);
3405
3406
  /**
3407
   * Sort the display list using a stable sort. Take care, because some of the
3408
   * items might be nsDisplayLists themselves.
3409
   * aComparator(Item item1, Item item2) should return true if item1 should go
3410
   * before item2.
3411
   * We sort the items into increasing order.
3412
   */
3413
  template<typename Item, typename Comparator>
3414
  void Sort(const Comparator& aComparator)
3415
0
  {
3416
0
    // Some casual local browsing testing suggests that a local preallocated
3417
0
    // array of 20 items should be able to avoid a lot of dynamic allocations
3418
0
    // here.
3419
0
    AutoTArray<Item, 20> items;
3420
0
3421
0
    while (nsDisplayItem* item = RemoveBottom()) {
3422
0
      items.AppendElement(Item(item));
3423
0
    }
3424
0
3425
0
    std::stable_sort(items.begin(), items.end(), aComparator);
3426
0
3427
0
    for (Item& item : items) {
3428
0
      AppendToTop(item);
3429
0
    }
3430
0
  }
Unexecuted instantiation: void nsDisplayList::Sort<ZSortItem, ZOrderComparator>(ZOrderComparator const&)
Unexecuted instantiation: void nsDisplayList::Sort<nsDisplayItem*, ContentComparator>(ContentComparator const&)
3431
3432
  /**
3433
   * Compute visiblity for the items in the list.
3434
   * We put this logic here so it can be shared by top-level
3435
   * painting and also display items that maintain child lists.
3436
   * This is also a good place to put ComputeVisibility-related logic
3437
   * that must be applied to every display item. In particular, this
3438
   * sets mVisibleRect on each display item.
3439
   * This sets mIsOpaque if the entire visible area of this list has
3440
   * been removed from aVisibleRegion when we return.
3441
   * This does not remove any items from the list, so we can recompute
3442
   * visiblity with different regions later (see
3443
   * FrameLayerBuilder::DrawPaintedLayer).
3444
   * This method needs to be idempotent.
3445
   *
3446
   * @param aVisibleRegion the area that is visible, relative to the
3447
   * reference frame; on return, this contains the area visible under the list.
3448
   * I.e., opaque contents of this list are subtracted from aVisibleRegion.
3449
   * @param aListVisibleBounds must be equal to the bounds of the intersection
3450
   * of aVisibleRegion and GetBounds() for this list.
3451
   * @return true if any item in the list is visible.
3452
   */
3453
  bool ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
3454
                                   nsRegion* aVisibleRegion,
3455
                                   const nsRect& aListVisibleBounds);
3456
3457
  /**
3458
   * As ComputeVisibilityForSublist, but computes visibility for a root
3459
   * list (a list that does not belong to an nsDisplayItem).
3460
   * This method needs to be idempotent.
3461
   *
3462
   * @param aVisibleRegion the area that is visible
3463
   */
3464
  bool ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
3465
                                nsRegion* aVisibleRegion);
3466
3467
  /**
3468
   * Returns true if the visible region output from ComputeVisiblity was
3469
   * empty, i.e. everything visible in this list is opaque.
3470
   */
3471
0
  bool IsOpaque() const { return mIsOpaque; }
3472
3473
  /**
3474
   * Returns true if any display item requires the surface to be transparent.
3475
   */
3476
0
  bool NeedsTransparentSurface() const { return mForceTransparentSurface; }
3477
  /**
3478
   * Paint the list to the rendering context. We assume that (0,0) in aCtx
3479
   * corresponds to the origin of the reference frame. For best results,
3480
   * aCtx's current transform should make (0,0) pixel-aligned. The
3481
   * rectangle in aDirtyRect is painted, which *must* be contained in the
3482
   * dirty rect used to construct the display list.
3483
   *
3484
   * If aFlags contains PAINT_USE_WIDGET_LAYERS and
3485
   * ShouldUseWidgetLayerManager() is set, then we will paint using
3486
   * the reference frame's widget's layer manager (and ctx may be null),
3487
   * otherwise we will use a temporary BasicLayerManager and ctx must
3488
   * not be null.
3489
   *
3490
   * If PAINT_EXISTING_TRANSACTION is set, the reference frame's widget's
3491
   * layer manager has already had BeginTransaction() called on it and
3492
   * we should not call it again.
3493
   *
3494
   * If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to
3495
   * compressed mode to avoid short cut optimizations.
3496
   *
3497
   * This must only be called on the root display list of the display list
3498
   * tree.
3499
   *
3500
   * We return the layer manager used for painting --- mainly so that
3501
   * callers can dump its layer tree if necessary.
3502
   */
3503
  enum
3504
  {
3505
    PAINT_DEFAULT = 0,
3506
    PAINT_USE_WIDGET_LAYERS = 0x01,
3507
    PAINT_EXISTING_TRANSACTION = 0x04,
3508
    PAINT_NO_COMPOSITE = 0x08,
3509
    PAINT_COMPRESSED = 0x10,
3510
    PAINT_IDENTICAL_DISPLAY_LIST = 0x20
3511
  };
3512
  already_AddRefed<LayerManager> PaintRoot(nsDisplayListBuilder* aBuilder,
3513
                                           gfxContext* aCtx,
3514
                                           uint32_t aFlags);
3515
3516
  mozilla::FrameLayerBuilder* BuildLayers(nsDisplayListBuilder* aBuilder,
3517
                                          LayerManager* aLayerManager,
3518
                                          uint32_t aFlags,
3519
                                          bool aIsWidgetTransaction);
3520
  /**
3521
   * Get the bounds. Takes the union of the bounds of all children.
3522
   * The result is not cached.
3523
   */
3524
  nsRect GetBounds(nsDisplayListBuilder* aBuilder) const;
3525
3526
  /**
3527
   * Get this list's bounds, respecting clips relative to aASR. The result is
3528
   * the union of each item's clipped bounds with respect to aASR. That means
3529
   * that if an item can move asynchronously with an ASR that is a descendant
3530
   * of aASR, then the clipped bounds with respect to aASR will be the clip of
3531
   * that item for aASR, because the item can move anywhere inside that clip.
3532
   * If there is an item in this list which is not bounded with respect to
3533
   * aASR (i.e. which does not have "finite bounds" with respect to aASR),
3534
   * then this method trigger an assertion failure.
3535
   * The optional aBuildingRect out argument can be set to non-null if the
3536
   * caller is also interested to know the building rect.  This can be used
3537
   * to get the visible rect efficiently without traversing the display list
3538
   * twice.
3539
   */
3540
  nsRect GetClippedBoundsWithRespectToASR(
3541
    nsDisplayListBuilder* aBuilder,
3542
    const ActiveScrolledRoot* aASR,
3543
    nsRect* aBuildingRect = nullptr) const;
3544
3545
  /**
3546
   * Find the topmost display item that returns a non-null frame, and return
3547
   * the frame.
3548
   */
3549
  void HitTest(nsDisplayListBuilder* aBuilder,
3550
               const nsRect& aRect,
3551
               nsDisplayItem::HitTestState* aState,
3552
               nsTArray<nsIFrame*>* aOutFrames) const;
3553
  /**
3554
   * Compute the union of the visible rects of the items in the list. The
3555
   * result is not cached.
3556
   */
3557
  nsRect GetBuildingRect() const;
3558
3559
0
  void SetIsOpaque() { mIsOpaque = true; }
3560
3561
0
  void SetNeedsTransparentSurface() { mForceTransparentSurface = true; }
3562
3563
  void RestoreState()
3564
0
  {
3565
0
    mIsOpaque = false;
3566
0
    mForceTransparentSurface = false;
3567
0
  }
3568
3569
private:
3570
  nsDisplayItemLink mSentinel;
3571
  nsDisplayItemLink* mTop;
3572
3573
  uint32_t mLength;
3574
3575
  // This is set to true by FrameLayerBuilder if the final visible region
3576
  // is empty (i.e. everything that was visible is covered by some
3577
  // opaque content in this list).
3578
  bool mIsOpaque;
3579
  // This is set to true by FrameLayerBuilder if any display item in this
3580
  // list needs to force the surface containing this list to be transparent.
3581
  bool mForceTransparentSurface;
3582
};
3583
3584
/**
3585
 * This is passed as a parameter to nsIFrame::BuildDisplayList. That method
3586
 * will put any generated items onto the appropriate list given here. It's
3587
 * basically just a collection with one list for each separate stacking layer.
3588
 * The lists themselves are external to this object and thus can be shared
3589
 * with others. Some of the list pointers may even refer to the same list.
3590
 */
3591
class nsDisplayListSet
3592
{
3593
public:
3594
  /**
3595
   * @return a list where one should place the border and/or background for
3596
   * this frame (everything from steps 1 and 2 of CSS 2.1 appendix E)
3597
   */
3598
0
  nsDisplayList* BorderBackground() const { return mBorderBackground; }
3599
  /**
3600
   * @return a list where one should place the borders and/or backgrounds for
3601
   * block-level in-flow descendants (step 4 of CSS 2.1 appendix E)
3602
   */
3603
  nsDisplayList* BlockBorderBackgrounds() const
3604
0
  {
3605
0
    return mBlockBorderBackgrounds;
3606
0
  }
3607
  /**
3608
   * @return a list where one should place descendant floats (step 5 of
3609
   * CSS 2.1 appendix E)
3610
   */
3611
0
  nsDisplayList* Floats() const { return mFloats; }
3612
  /**
3613
   * @return a list where one should place the (pseudo) stacking contexts
3614
   * for descendants of this frame (everything from steps 3, 7 and 8
3615
   * of CSS 2.1 appendix E)
3616
   */
3617
0
  nsDisplayList* PositionedDescendants() const { return mPositioned; }
3618
  /**
3619
   * @return a list where one should place the outlines
3620
   * for this frame and its descendants (step 9 of CSS 2.1 appendix E)
3621
   */
3622
0
  nsDisplayList* Outlines() const { return mOutlines; }
3623
  /**
3624
   * @return a list where one should place all other content
3625
   */
3626
0
  nsDisplayList* Content() const { return mContent; }
3627
3628
  void DeleteAll(nsDisplayListBuilder* aBuilder)
3629
  {
3630
    BorderBackground()->DeleteAll(aBuilder);
3631
    BlockBorderBackgrounds()->DeleteAll(aBuilder);
3632
    Floats()->DeleteAll(aBuilder);
3633
    PositionedDescendants()->DeleteAll(aBuilder);
3634
    Outlines()->DeleteAll(aBuilder);
3635
    Content()->DeleteAll(aBuilder);
3636
  }
3637
3638
  nsDisplayListSet(nsDisplayList* aBorderBackground,
3639
                   nsDisplayList* aBlockBorderBackgrounds,
3640
                   nsDisplayList* aFloats,
3641
                   nsDisplayList* aContent,
3642
                   nsDisplayList* aPositionedDescendants,
3643
                   nsDisplayList* aOutlines)
3644
    : mBorderBackground(aBorderBackground)
3645
    , mBlockBorderBackgrounds(aBlockBorderBackgrounds)
3646
    , mFloats(aFloats)
3647
    , mContent(aContent)
3648
    , mPositioned(aPositionedDescendants)
3649
    , mOutlines(aOutlines)
3650
0
  {
3651
0
  }
3652
3653
  /**
3654
   * A copy constructor that lets the caller override the BorderBackground
3655
   * list.
3656
   */
3657
  nsDisplayListSet(const nsDisplayListSet& aLists,
3658
                   nsDisplayList* aBorderBackground)
3659
    : mBorderBackground(aBorderBackground)
3660
    , mBlockBorderBackgrounds(aLists.BlockBorderBackgrounds())
3661
    , mFloats(aLists.Floats())
3662
    , mContent(aLists.Content())
3663
    , mPositioned(aLists.PositionedDescendants())
3664
    , mOutlines(aLists.Outlines())
3665
0
  {
3666
0
  }
3667
3668
  /**
3669
   * Move all display items in our lists to top of the corresponding lists in
3670
   * the destination.
3671
   */
3672
  void MoveTo(const nsDisplayListSet& aDestination) const;
3673
3674
private:
3675
  // This class is only used on stack, so we don't have to worry about leaking
3676
  // it.  Don't let us be heap-allocated!
3677
  void* operator new(size_t sz) CPP_THROW_NEW;
3678
3679
protected:
3680
  nsDisplayList* mBorderBackground;
3681
  nsDisplayList* mBlockBorderBackgrounds;
3682
  nsDisplayList* mFloats;
3683
  nsDisplayList* mContent;
3684
  nsDisplayList* mPositioned;
3685
  nsDisplayList* mOutlines;
3686
};
3687
3688
/**
3689
 * A specialization of nsDisplayListSet where the lists are actually internal
3690
 * to the object, and all distinct.
3691
 */
3692
struct nsDisplayListCollection : public nsDisplayListSet
3693
{
3694
  explicit nsDisplayListCollection(nsDisplayListBuilder* aBuilder)
3695
    : nsDisplayListSet(&mLists[0],
3696
                       &mLists[1],
3697
                       &mLists[2],
3698
                       &mLists[3],
3699
                       &mLists[4],
3700
                       &mLists[5])
3701
0
  {
3702
0
  }
3703
3704
  explicit nsDisplayListCollection(nsDisplayListBuilder* aBuilder,
3705
                                   nsDisplayList* aBorderBackground)
3706
    : nsDisplayListSet(aBorderBackground,
3707
                       &mLists[1],
3708
                       &mLists[2],
3709
                       &mLists[3],
3710
                       &mLists[4],
3711
                       &mLists[5])
3712
  {
3713
  }
3714
3715
  /**
3716
   * Sort all lists by content order.
3717
   */
3718
  void SortAllByContentOrder(nsIContent* aCommonAncestor)
3719
  {
3720
    for (auto& mList : mLists) {
3721
      mList.SortByContentOrder(aCommonAncestor);
3722
    }
3723
  }
3724
3725
private:
3726
  // This class is only used on stack, so we don't have to worry about leaking
3727
  // it.  Don't let us be heap-allocated!
3728
  void* operator new(size_t sz) CPP_THROW_NEW;
3729
3730
  nsDisplayList mLists[6];
3731
};
3732
3733
/**
3734
 * A display list that also retains the partial build
3735
 * information (in the form of a DAG) used to create it.
3736
 *
3737
 * Display lists built from a partial list aren't necessarily
3738
 * in the same order as a full build, and the DAG retains
3739
 * the information needing to interpret the current
3740
 * order correctly.
3741
 */
3742
class RetainedDisplayList : public nsDisplayList
3743
{
3744
public:
3745
0
  RetainedDisplayList() = default;
3746
  RetainedDisplayList(RetainedDisplayList&& aOther)
3747
  {
3748
    AppendToTop(&aOther);
3749
    mDAG = std::move(aOther.mDAG);
3750
  }
3751
3752
  ~RetainedDisplayList() override
3753
0
  {
3754
0
    MOZ_ASSERT(mOldItems.IsEmpty(), "Must empty list before destroying");
3755
0
  }
3756
3757
  RetainedDisplayList& operator=(RetainedDisplayList&& aOther)
3758
0
  {
3759
0
    MOZ_ASSERT(!Count(), "Can only move into an empty list!");
3760
0
    MOZ_ASSERT(mOldItems.IsEmpty(), "Can only move into an empty list!");
3761
0
    AppendToTop(&aOther);
3762
0
    mDAG = std::move(aOther.mDAG);
3763
0
    return *this;
3764
0
  }
3765
3766
  void DeleteAll(nsDisplayListBuilder* aBuilder) override
3767
0
  {
3768
0
    for (OldItemInfo& i : mOldItems) {
3769
0
      if (i.mItem) {
3770
0
        i.mItem->Destroy(aBuilder);
3771
0
      }
3772
0
    }
3773
0
    mOldItems.Clear();
3774
0
    mDAG.Clear();
3775
0
    nsDisplayList::DeleteAll(aBuilder);
3776
0
  }
3777
3778
  DirectedAcyclicGraph<MergedListUnits> mDAG;
3779
3780
  // Temporary state initialized during the preprocess pass
3781
  // of RetainedDisplayListBuilder and then used during merging.
3782
  nsTArray<OldItemInfo> mOldItems;
3783
};
3784
3785
class FlattenedDisplayItemIterator
3786
{
3787
public:
3788
  FlattenedDisplayItemIterator(nsDisplayListBuilder* aBuilder,
3789
                               nsDisplayList* aList,
3790
                               const bool aResolveFlattening = true)
3791
    : mBuilder(aBuilder)
3792
    , mNext(aList->GetBottom())
3793
  {
3794
    if (aResolveFlattening) {
3795
      // This is done conditionally in case subclass overrides
3796
      // ShouldFlattenNextItem().
3797
      ResolveFlattening();
3798
    }
3799
  }
3800
3801
  virtual ~FlattenedDisplayItemIterator() { MOZ_ASSERT(!HasNext()); }
3802
3803
  nsDisplayItem* GetNext()
3804
  {
3805
    nsDisplayItem* next = mNext;
3806
3807
    // Advance mNext to the following item
3808
    if (next) {
3809
      mNext = mNext->GetAbove();
3810
      ResolveFlattening();
3811
    }
3812
    return next;
3813
  }
3814
3815
0
  bool HasNext() const { return mNext || !mStack.IsEmpty(); }
3816
3817
  nsDisplayItem* PeekNext() { return mNext; }
3818
3819
protected:
3820
  bool AtEndOfNestedList() const { return !mNext && mStack.Length() > 0; }
3821
3822
  virtual bool ShouldFlattenNextItem()
3823
  {
3824
    return mNext && mNext->ShouldFlattenAway(mBuilder);
3825
  }
3826
3827
  void ResolveFlattening()
3828
  {
3829
    // Handle the case where we reach the end of a nested list, or the current
3830
    // item should start a new nested list. Repeat this until we find an actual
3831
    // item, or the very end of the outer list.
3832
    while (AtEndOfNestedList() || ShouldFlattenNextItem()) {
3833
      if (AtEndOfNestedList()) {
3834
        // Pop the last item off the stack.
3835
        mNext = mStack.LastElement();
3836
        EndNested(mNext);
3837
        mStack.RemoveElementAt(mStack.Length() - 1);
3838
        // We stored the item that was flattened, so advance to the next.
3839
        mNext = mNext->GetAbove();
3840
      } else {
3841
        // This item wants to be flattened. Store the current item on the stack,
3842
        // and use the first item in the child list instead.
3843
        mStack.AppendElement(mNext);
3844
        StartNested(mNext);
3845
3846
        nsDisplayList* childItems =
3847
          mNext->GetType() != DisplayItemType::TYPE_TRANSFORM
3848
            ? mNext->GetSameCoordinateSystemChildren()
3849
            : mNext->GetChildren();
3850
3851
        mNext = childItems->GetBottom();
3852
      }
3853
    }
3854
  }
3855
3856
  virtual void EndNested(nsDisplayItem* aItem) {}
3857
  virtual void StartNested(nsDisplayItem* aItem) {}
3858
3859
  nsDisplayListBuilder* mBuilder;
3860
  nsDisplayItem* mNext;
3861
  AutoTArray<nsDisplayItem*, 10> mStack;
3862
};
3863
3864
class nsDisplayImageContainer : public nsDisplayItem
3865
{
3866
public:
3867
  typedef mozilla::LayerIntPoint LayerIntPoint;
3868
  typedef mozilla::LayoutDeviceRect LayoutDeviceRect;
3869
  typedef mozilla::layers::ImageContainer ImageContainer;
3870
  typedef mozilla::layers::ImageLayer ImageLayer;
3871
3872
  nsDisplayImageContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
3873
    : nsDisplayItem(aBuilder, aFrame)
3874
0
  {
3875
0
  }
3876
3877
  /**
3878
   * @return true if this display item can be optimized into an image layer.
3879
   * It is an error to call GetContainer() unless you've called
3880
   * CanOptimizeToImageLayer() first and it returned true.
3881
   */
3882
  virtual bool CanOptimizeToImageLayer(LayerManager* aManager,
3883
                                       nsDisplayListBuilder* aBuilder);
3884
3885
  already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
3886
                                                nsDisplayListBuilder* aBuilder);
3887
  void ConfigureLayer(ImageLayer* aLayer,
3888
                      const ContainerLayerParameters& aParameters);
3889
3890
  virtual void UpdateDrawResult(mozilla::image::ImgDrawResult aResult) = 0;
3891
  virtual already_AddRefed<imgIContainer> GetImage() = 0;
3892
  virtual nsRect GetDestRect() const = 0;
3893
3894
0
  bool SupportsOptimizingToImage() const override { return true; }
3895
};
3896
3897
/**
3898
 * Use this class to implement not-very-frequently-used display items
3899
 * that are not opaque, do not receive events, and are bounded by a frame's
3900
 * border-rect.
3901
 *
3902
 * This should not be used for display items which are created frequently,
3903
 * because each item is one or two pointers bigger than an item from a
3904
 * custom display item class could be, and fractionally slower. However it does
3905
 * save code size. We use this for infrequently-used item types.
3906
 */
3907
class nsDisplayGeneric : public nsDisplayItem
3908
{
3909
public:
3910
  typedef void (*PaintCallback)(nsIFrame* aFrame,
3911
                                DrawTarget* aDrawTarget,
3912
                                const nsRect& aDirtyRect,
3913
                                nsPoint aFramePt);
3914
3915
  // XXX: should be removed eventually
3916
  typedef void (*OldPaintCallback)(nsIFrame* aFrame,
3917
                                   gfxContext* aCtx,
3918
                                   const nsRect& aDirtyRect,
3919
                                   nsPoint aFramePt);
3920
3921
  nsDisplayGeneric(nsDisplayListBuilder* aBuilder,
3922
                   nsIFrame* aFrame,
3923
                   PaintCallback aPaint,
3924
                   const char* aName,
3925
                   DisplayItemType aType)
3926
    : nsDisplayItem(aBuilder, aFrame)
3927
    , mPaint(aPaint)
3928
    , mOldPaint(nullptr)
3929
    , mName(aName)
3930
    , mType(aType)
3931
  {
3932
    MOZ_COUNT_CTOR(nsDisplayGeneric);
3933
  }
3934
3935
  // XXX: should be removed eventually
3936
  nsDisplayGeneric(nsDisplayListBuilder* aBuilder,
3937
                   nsIFrame* aFrame,
3938
                   OldPaintCallback aOldPaint,
3939
                   const char* aName,
3940
                   DisplayItemType aType)
3941
    : nsDisplayItem(aBuilder, aFrame)
3942
    , mPaint(nullptr)
3943
    , mOldPaint(aOldPaint)
3944
    , mName(aName)
3945
    , mType(aType)
3946
0
  {
3947
0
    MOZ_COUNT_CTOR(nsDisplayGeneric);
3948
0
  }
3949
3950
#ifdef NS_BUILD_REFCNT_LOGGING
3951
  ~nsDisplayGeneric() override { MOZ_COUNT_DTOR(nsDisplayGeneric); }
3952
#endif
3953
3954
  void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override
3955
0
  {
3956
0
    MOZ_ASSERT(!!mPaint != !!mOldPaint);
3957
0
    if (mPaint) {
3958
0
      mPaint(mFrame, aCtx->GetDrawTarget(), GetPaintRect(), ToReferenceFrame());
3959
0
    } else {
3960
0
      mOldPaint(mFrame, aCtx, GetPaintRect(), ToReferenceFrame());
3961
0
    }
3962
0
  }
3963
3964
0
  const char* Name() const override { return mName; }
3965
0
  DisplayItemType GetType() const override { return mType; }
3966
3967
  // This override is needed because GetType() for nsDisplayGeneric subclasses
3968
  // does not match TYPE_GENERIC that was used to allocate the object.
3969
  void Destroy(nsDisplayListBuilder* aBuilder) override
3970
0
  {
3971
0
    this->~nsDisplayGeneric();
3972
0
    aBuilder->Destroy(DisplayItemType::TYPE_GENERIC, this);
3973
0
  }
3974
3975
protected:
3976
  void* operator new(size_t aSize, nsDisplayListBuilder* aBuilder)
3977
0
  {
3978
0
    return aBuilder->Allocate(aSize, DisplayItemType::TYPE_GENERIC);
3979
0
  }
3980
  template<typename T, typename... Args>
3981
  friend T* MakeDisplayItem(nsDisplayListBuilder* aBuilder, Args&&... aArgs);
3982
3983
  PaintCallback mPaint;
3984
  OldPaintCallback mOldPaint; // XXX: should be removed eventually
3985
  const char* mName;
3986
  DisplayItemType mType;
3987
};
3988
3989
#if defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF)
3990
/**
3991
 * This class implements painting of reflow counts.  Ideally, we would simply
3992
 * make all the frame names be those returned by nsFrame::GetFrameName
3993
 * (except that tosses in the content tag name!)  and support only one color
3994
 * and eliminate this class altogether in favor of nsDisplayGeneric, but for
3995
 * the time being we can't pass args to a PaintCallback, so just have a
3996
 * separate class to do the right thing.  Sadly, this alsmo means we need to
3997
 * hack all leaf frame classes to handle this.
3998
 *
3999
 * XXXbz the color thing is a bit of a mess, but 0 basically means "not set"
4000
 * here...  I could switch it all to nscolor, but why bother?
4001
 */
4002
class nsDisplayReflowCount : public nsDisplayItem
4003
{
4004
public:
4005
  nsDisplayReflowCount(nsDisplayListBuilder* aBuilder,
4006
                       nsIFrame* aFrame,
4007
                       const char* aFrameName,
4008
                       uint32_t aColor = 0)
4009
    : nsDisplayItem(aBuilder, aFrame)
4010
    , mFrameName(aFrameName)
4011
    , mColor(aColor)
4012
  {
4013
    MOZ_COUNT_CTOR(nsDisplayReflowCount);
4014
  }
4015
4016
#ifdef NS_BUILD_REFCNT_LOGGING
4017
  ~nsDisplayReflowCount() override { MOZ_COUNT_DTOR(nsDisplayReflowCount); }
4018
#endif
4019
4020
  NS_DISPLAY_DECL_NAME("nsDisplayReflowCount", TYPE_REFLOW_COUNT)
4021
4022
  void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override
4023
  {
4024
    mFrame->PresShell()->PaintCount(mFrameName,
4025
                                    aCtx,
4026
                                    mFrame->PresContext(),
4027
                                    mFrame,
4028
                                    ToReferenceFrame(),
4029
                                    mColor);
4030
  }
4031
4032
protected:
4033
  const char* mFrameName;
4034
  nscolor mColor;
4035
};
4036
4037
#define DO_GLOBAL_REFLOW_COUNT_DSP(_name)                                      \
4038
  PR_BEGIN_MACRO                                                               \
4039
  if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() &&      \
4040
      PresShell()->IsPaintingFrameCounts()) {                                  \
4041
    aLists.Outlines()->AppendToTop(                                            \
4042
      MakeDisplayItem<nsDisplayReflowCount>(aBuilder, this, _name));           \
4043
  }                                                                            \
4044
  PR_END_MACRO
4045
4046
#define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color)                        \
4047
  PR_BEGIN_MACRO                                                               \
4048
  if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() &&      \
4049
      PresShell()->IsPaintingFrameCounts()) {                                  \
4050
    aLists.Outlines()->AppendToTop(                                            \
4051
      MakeDisplayItem<nsDisplayReflowCount>(aBuilder, this, _name, _color));   \
4052
  }                                                                            \
4053
  PR_END_MACRO
4054
4055
/*
4056
  Macro to be used for classes that don't actually implement BuildDisplayList
4057
 */
4058
#define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super)                        \
4059
  void BuildDisplayList(nsDisplayListBuilder* aBuilder,                        \
4060
                        const nsRect& aDirtyRect,                              \
4061
                        const nsDisplayListSet& aLists)                        \
4062
  {                                                                            \
4063
    DO_GLOBAL_REFLOW_COUNT_DSP(#_class);                                       \
4064
    _super::BuildDisplayList(aBuilder, aDirtyRect, aLists);                    \
4065
  }
4066
4067
#else // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF
4068
4069
#define DO_GLOBAL_REFLOW_COUNT_DSP(_name)
4070
#define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color)
4071
#define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super)
4072
4073
#endif // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF
4074
4075
class nsDisplayCaret : public nsDisplayItem
4076
{
4077
public:
4078
  nsDisplayCaret(nsDisplayListBuilder* aBuilder, nsIFrame* aCaretFrame);
4079
4080
#ifdef NS_BUILD_REFCNT_LOGGING
4081
  ~nsDisplayCaret() override;
4082
#endif
4083
4084
  NS_DISPLAY_DECL_NAME("Caret", TYPE_CARET)
4085
4086
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
4087
  void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
4088
  bool CreateWebRenderCommands(
4089
    mozilla::wr::DisplayListBuilder& aBuilder,
4090
    mozilla::wr::IpcResourceUpdateQueue& aResources,
4091
    const StackingContextHelper& aSc,
4092
    mozilla::layers::WebRenderLayerManager* aManager,
4093
    nsDisplayListBuilder* aDisplayListBuilder) override;
4094
4095
protected:
4096
  RefPtr<nsCaret> mCaret;
4097
  nsRect mBounds;
4098
};
4099
4100
/**
4101
 * The standard display item to paint the CSS borders of a frame.
4102
 */
4103
class nsDisplayBorder : public nsDisplayItem
4104
{
4105
public:
4106
  nsDisplayBorder(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
4107
4108
#ifdef NS_BUILD_REFCNT_LOGGING
4109
  ~nsDisplayBorder() override { MOZ_COUNT_DTOR(nsDisplayBorder); }
4110
#endif
4111
4112
  NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER)
4113
4114
  bool IsInvisibleInRect(const nsRect& aRect) const override;
4115
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
4116
  LayerState GetLayerState(
4117
    nsDisplayListBuilder* aBuilder,
4118
    LayerManager* aManager,
4119
    const ContainerLayerParameters& aParameters) override;
4120
  bool CreateWebRenderCommands(
4121
    mozilla::wr::DisplayListBuilder& aBuilder,
4122
    mozilla::wr::IpcResourceUpdateQueue& aResources,
4123
    const StackingContextHelper& aSc,
4124
    mozilla::layers::WebRenderLayerManager* aManager,
4125
    nsDisplayListBuilder* aDisplayListBuilder) override;
4126
  void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
4127
  nsDisplayItemGeometry* AllocateGeometry(
4128
    nsDisplayListBuilder* aBuilder) override;
4129
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
4130
                                 const nsDisplayItemGeometry* aGeometry,
4131
                                 nsRegion* aInvalidRegion) const override;
4132
4133
  nsRegion GetTightBounds(nsDisplayListBuilder* aBuilder,
4134
                          bool* aSnap) const override
4135
0
  {
4136
0
    *aSnap = true;
4137
0
    return CalculateBounds<nsRegion>(*mFrame->StyleBorder());
4138
0
  }
4139
4140
protected:
4141
  template<typename T>
4142
  T CalculateBounds(const nsStyleBorder& aStyleBorder) const
4143
0
  {
4144
0
    nsRect borderBounds(ToReferenceFrame(), mFrame->GetSize());
4145
0
    if (aStyleBorder.IsBorderImageLoaded()) {
4146
0
      borderBounds.Inflate(aStyleBorder.GetImageOutset());
4147
0
      return borderBounds;
4148
0
    }
4149
0
4150
0
    nsMargin border = aStyleBorder.GetComputedBorder();
4151
0
    T result;
4152
0
    if (border.top > 0) {
4153
0
      result = nsRect(
4154
0
        borderBounds.X(), borderBounds.Y(), borderBounds.Width(), border.top);
4155
0
    }
4156
0
    if (border.right > 0) {
4157
0
      result.OrWith(nsRect(borderBounds.XMost() - border.right,
4158
0
                           borderBounds.Y(),
4159
0
                           border.right,
4160
0
                           borderBounds.Height()));
4161
0
    }
4162
0
    if (border.bottom > 0) {
4163
0
      result.OrWith(nsRect(borderBounds.X(),
4164
0
                           borderBounds.YMost() - border.bottom,
4165
0
                           borderBounds.Width(),
4166
0
                           border.bottom));
4167
0
    }
4168
0
    if (border.left > 0) {
4169
0
      result.OrWith(nsRect(borderBounds.X(),
4170
0
                           borderBounds.Y(),
4171
0
                           border.left,
4172
0
                           borderBounds.Height()));
4173
0
    }
4174
0
4175
0
    nscoord radii[8];
4176
0
    if (mFrame->GetBorderRadii(radii)) {
4177
0
      if (border.left > 0 || border.top > 0) {
4178
0
        nsSize cornerSize(radii[mozilla::eCornerTopLeftX],
4179
0
                          radii[mozilla::eCornerTopLeftY]);
4180
0
        result.OrWith(nsRect(borderBounds.TopLeft(), cornerSize));
4181
0
      }
4182
0
      if (border.top > 0 || border.right > 0) {
4183
0
        nsSize cornerSize(radii[mozilla::eCornerTopRightX],
4184
0
                          radii[mozilla::eCornerTopRightY]);
4185
0
        result.OrWith(nsRect(
4186
0
          borderBounds.TopRight() - nsPoint(cornerSize.width, 0), cornerSize));
4187
0
      }
4188
0
      if (border.right > 0 || border.bottom > 0) {
4189
0
        nsSize cornerSize(radii[mozilla::eCornerBottomRightX],
4190
0
                          radii[mozilla::eCornerBottomRightY]);
4191
0
        result.OrWith(nsRect(borderBounds.BottomRight() -
4192
0
                               nsPoint(cornerSize.width, cornerSize.height),
4193
0
                             cornerSize));
4194
0
      }
4195
0
      if (border.bottom > 0 || border.left > 0) {
4196
0
        nsSize cornerSize(radii[mozilla::eCornerBottomLeftX],
4197
0
                          radii[mozilla::eCornerBottomLeftY]);
4198
0
        result.OrWith(
4199
0
          nsRect(borderBounds.BottomLeft() - nsPoint(0, cornerSize.height),
4200
0
                 cornerSize));
4201
0
      }
4202
0
    }
4203
0
    return result;
4204
0
  }
Unexecuted instantiation: nsRegion nsDisplayBorder::CalculateBounds<nsRegion>(nsStyleBorder const&) const
Unexecuted instantiation: nsRect nsDisplayBorder::CalculateBounds<nsRect>(nsStyleBorder const&) const
4205
4206
  nsRect mBounds;
4207
};
4208
4209
/**
4210
 * A simple display item that just renders a solid color across the
4211
 * specified bounds. For canvas frames (in the CSS sense) we split off the
4212
 * drawing of the background color into this class (from nsDisplayBackground
4213
 * via nsDisplayCanvasBackground). This is done so that we can always draw a
4214
 * background color to avoid ugly flashes of white when we can't draw a full
4215
 * frame tree (ie when a page is loading). The bounds can differ from the
4216
 * frame's bounds -- this is needed when a frame/iframe is loading and there
4217
 * is not yet a frame tree to go in the frame/iframe so we use the subdoc
4218
 * frame of the parent document as a standin.
4219
 */
4220
class nsDisplaySolidColorBase : public nsDisplayItem
4221
{
4222
public:
4223
  nsDisplaySolidColorBase(nsDisplayListBuilder* aBuilder,
4224
                          nsIFrame* aFrame,
4225
                          nscolor aColor)
4226
    : nsDisplayItem(aBuilder, aFrame)
4227
    , mColor(aColor)
4228
0
  {
4229
0
  }
4230
4231
  nsDisplayItemGeometry* AllocateGeometry(
4232
    nsDisplayListBuilder* aBuilder) override
4233
0
  {
4234
0
    return new nsDisplaySolidColorGeometry(this, aBuilder, mColor);
4235
0
  }
4236
4237
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
4238
                                 const nsDisplayItemGeometry* aGeometry,
4239
                                 nsRegion* aInvalidRegion) const override
4240
0
  {
4241
0
    const nsDisplaySolidColorGeometry* geometry =
4242
0
      static_cast<const nsDisplaySolidColorGeometry*>(aGeometry);
4243
0
    if (mColor != geometry->mColor) {
4244
0
      bool dummy;
4245
0
      aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &dummy));
4246
0
      return;
4247
0
    }
4248
0
    ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
4249
0
  }
4250
4251
  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
4252
                           bool* aSnap) const override
4253
0
  {
4254
0
    *aSnap = false;
4255
0
    nsRegion result;
4256
0
    if (NS_GET_A(mColor) == 255) {
4257
0
      result = GetBounds(aBuilder, aSnap);
4258
0
    }
4259
0
    return result;
4260
0
  }
4261
4262
  mozilla::Maybe<nscolor> IsUniform(
4263
    nsDisplayListBuilder* aBuilder) const override
4264
0
  {
4265
0
    return mozilla::Some(mColor);
4266
0
  }
4267
4268
protected:
4269
  nscolor mColor;
4270
};
4271
4272
class nsDisplaySolidColor : public nsDisplaySolidColorBase
4273
{
4274
public:
4275
  nsDisplaySolidColor(nsDisplayListBuilder* aBuilder,
4276
                      nsIFrame* aFrame,
4277
                      const nsRect& aBounds,
4278
                      nscolor aColor,
4279
                      bool aCanBeReused = true)
4280
    : nsDisplaySolidColorBase(aBuilder, aFrame, aColor)
4281
    , mBounds(aBounds)
4282
    , mCanBeReused(aCanBeReused)
4283
0
  {
4284
0
    NS_ASSERTION(NS_GET_A(aColor) > 0,
4285
0
                 "Don't create invisible nsDisplaySolidColors!");
4286
0
    MOZ_COUNT_CTOR(nsDisplaySolidColor);
4287
0
  }
4288
4289
#ifdef NS_BUILD_REFCNT_LOGGING
4290
  ~nsDisplaySolidColor() override { MOZ_COUNT_DTOR(nsDisplaySolidColor); }
4291
#endif
4292
4293
  NS_DISPLAY_DECL_NAME("SolidColor", TYPE_SOLID_COLOR)
4294
4295
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
4296
  LayerState GetLayerState(
4297
    nsDisplayListBuilder* aBuilder,
4298
    LayerManager* aManager,
4299
    const ContainerLayerParameters& aParameters) override;
4300
  already_AddRefed<Layer> BuildLayer(
4301
    nsDisplayListBuilder* aBuilder,
4302
    LayerManager* aManager,
4303
    const ContainerLayerParameters& aContainerParameters) override;
4304
  void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
4305
  void WriteDebugInfo(std::stringstream& aStream) override;
4306
  bool CreateWebRenderCommands(
4307
    mozilla::wr::DisplayListBuilder& aBuilder,
4308
    mozilla::wr::IpcResourceUpdateQueue& aResources,
4309
    const StackingContextHelper& aSc,
4310
    mozilla::layers::WebRenderLayerManager* aManager,
4311
    nsDisplayListBuilder* aDisplayListBuilder) override;
4312
0
  bool CanBeReused() const override { return mCanBeReused; }
4313
4314
  int32_t ZIndex() const override
4315
0
  {
4316
0
    if (mOverrideZIndex) {
4317
0
      return mOverrideZIndex.value();
4318
0
    }
4319
0
    return nsDisplaySolidColorBase::ZIndex();
4320
0
  }
4321
4322
  void SetOverrideZIndex(int32_t aZIndex)
4323
0
  {
4324
0
    mOverrideZIndex = mozilla::Some(aZIndex);
4325
0
  }
4326
4327
private:
4328
  nsRect mBounds;
4329
  bool mCanBeReused;
4330
  mozilla::Maybe<int32_t> mOverrideZIndex;
4331
};
4332
4333
/**
4334
 * A display item that renders a solid color over a region. This is not
4335
 * exposed through CSS, its only purpose is efficient invalidation of
4336
 * the find bar highlighter dimmer.
4337
 */
4338
class nsDisplaySolidColorRegion : public nsDisplayItem
4339
{
4340
  typedef mozilla::gfx::Color Color;
4341
4342
public:
4343
  nsDisplaySolidColorRegion(nsDisplayListBuilder* aBuilder,
4344
                            nsIFrame* aFrame,
4345
                            const nsRegion& aRegion,
4346
                            nscolor aColor)
4347
    : nsDisplayItem(aBuilder, aFrame)
4348
    , mRegion(aRegion)
4349
    , mColor(Color::FromABGR(aColor))
4350
0
  {
4351
0
    NS_ASSERTION(NS_GET_A(aColor) > 0,
4352
0
                 "Don't create invisible nsDisplaySolidColorRegions!");
4353
0
    MOZ_COUNT_CTOR(nsDisplaySolidColorRegion);
4354
0
  }
4355
4356
#ifdef NS_BUILD_REFCNT_LOGGING
4357
  ~nsDisplaySolidColorRegion() override
4358
  {
4359
    MOZ_COUNT_DTOR(nsDisplaySolidColorRegion);
4360
  }
4361
#endif
4362
4363
  NS_DISPLAY_DECL_NAME("SolidColorRegion", TYPE_SOLID_COLOR_REGION)
4364
4365
  nsDisplayItemGeometry* AllocateGeometry(
4366
    nsDisplayListBuilder* aBuilder) override
4367
0
  {
4368
0
    return new nsDisplaySolidColorRegionGeometry(
4369
0
      this, aBuilder, mRegion, mColor);
4370
0
  }
4371
4372
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
4373
                                 const nsDisplayItemGeometry* aGeometry,
4374
                                 nsRegion* aInvalidRegion) const override
4375
0
  {
4376
0
    const nsDisplaySolidColorRegionGeometry* geometry =
4377
0
      static_cast<const nsDisplaySolidColorRegionGeometry*>(aGeometry);
4378
0
    if (mColor == geometry->mColor) {
4379
0
      aInvalidRegion->Xor(geometry->mRegion, mRegion);
4380
0
    } else {
4381
0
      aInvalidRegion->Or(geometry->mRegion.GetBounds(), mRegion.GetBounds());
4382
0
    }
4383
0
  }
4384
4385
  bool CreateWebRenderCommands(
4386
    mozilla::wr::DisplayListBuilder& aBuilder,
4387
    mozilla::wr::IpcResourceUpdateQueue& aResources,
4388
    const StackingContextHelper& aSc,
4389
    mozilla::layers::WebRenderLayerManager* aManager,
4390
    nsDisplayListBuilder* aDisplayListBuilder) override;
4391
4392
protected:
4393
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
4394
  void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
4395
  void WriteDebugInfo(std::stringstream& aStream) override;
4396
4397
private:
4398
  nsRegion mRegion;
4399
  Color mColor;
4400
};
4401
4402
/**
4403
 * A display item to paint one background-image for a frame. Each background
4404
 * image layer gets its own nsDisplayBackgroundImage.
4405
 */
4406
class nsDisplayBackgroundImage : public nsDisplayImageContainer
4407
{
4408
public:
4409
  typedef mozilla::StyleGeometryBox StyleGeometryBox;
4410
4411
  struct InitData
4412
  {
4413
    nsDisplayListBuilder* builder;
4414
    nsIFrame* frame;
4415
    mozilla::ComputedStyle* backgroundStyle;
4416
    nsCOMPtr<imgIContainer> image;
4417
    nsRect backgroundRect;
4418
    nsRect fillArea;
4419
    nsRect destArea;
4420
    uint32_t layer;
4421
    bool isRasterImage;
4422
    bool shouldFixToViewport;
4423
  };
4424
4425
  /**
4426
   * aLayer signifies which background layer this item represents.
4427
   * aIsThemed should be the value of aFrame->IsThemed.
4428
   * aBackgroundStyle should be the result of
4429
   * nsCSSRendering::FindBackground, or null if FindBackground returned false.
4430
   * aBackgroundRect is relative to aFrame.
4431
   */
4432
  static InitData GetInitData(nsDisplayListBuilder* aBuilder,
4433
                              nsIFrame* aFrame,
4434
                              uint32_t aLayer,
4435
                              const nsRect& aBackgroundRect,
4436
                              mozilla::ComputedStyle* aBackgroundStyle);
4437
4438
  explicit nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilder,
4439
                                    const InitData& aInitData,
4440
                                    nsIFrame* aFrameForBounds = nullptr);
4441
  ~nsDisplayBackgroundImage() override;
4442
4443
  NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)
4444
4445
  // This will create and append new items for all the layers of the
4446
  // background. Returns whether we appended a themed background.
4447
  // aAllowWillPaintBorderOptimization should usually be left at true, unless
4448
  // aFrame has special border drawing that causes opaque borders to not
4449
  // actually be opaque.
4450
  static bool AppendBackgroundItemsToTop(
4451
    nsDisplayListBuilder* aBuilder,
4452
    nsIFrame* aFrame,
4453
    const nsRect& aBackgroundRect,
4454
    nsDisplayList* aList,
4455
    bool aAllowWillPaintBorderOptimization = true,
4456
    mozilla::ComputedStyle* aComputedStyle = nullptr,
4457
    const nsRect& aBackgroundOriginRect = nsRect(),
4458
    nsIFrame* aSecondaryReferenceFrame = nullptr);
4459
4460
  LayerState GetLayerState(
4461
    nsDisplayListBuilder* aBuilder,
4462
    LayerManager* aManager,
4463
    const ContainerLayerParameters& aParameters) override;
4464
  already_AddRefed<Layer> BuildLayer(
4465
    nsDisplayListBuilder* aBuilder,
4466
    LayerManager* aManager,
4467
    const ContainerLayerParameters& aContainerParameters) override;
4468
  bool CreateWebRenderCommands(
4469
    mozilla::wr::DisplayListBuilder& aBuilder,
4470
    mozilla::wr::IpcResourceUpdateQueue& aResources,
4471
    const StackingContextHelper& aSc,
4472
    mozilla::layers::WebRenderLayerManager* aManager,
4473
    nsDisplayListBuilder* aDisplayListBuilder) override;
4474
  void HitTest(nsDisplayListBuilder* aBuilder,
4475
               const nsRect& aRect,
4476
               HitTestState* aState,
4477
               nsTArray<nsIFrame*>* aOutFrames) override;
4478
  bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
4479
                         nsRegion* aVisibleRegion) override;
4480
  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
4481
                           bool* aSnap) const override;
4482
  mozilla::Maybe<nscolor> IsUniform(
4483
    nsDisplayListBuilder* aBuilder) const override;
4484
4485
  /**
4486
   * GetBounds() returns the background painting area.
4487
   */
4488
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
4489
4490
  void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
4491
4492
  uint32_t GetPerFrameKey() const override
4493
0
  {
4494
0
    return (mLayer << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
4495
0
  }
4496
4497
  /**
4498
   * Return the background positioning area.
4499
   * (GetBounds() returns the background painting area.)
4500
   * Can be called only when mBackgroundStyle is non-null.
4501
   */
4502
  nsRect GetPositioningArea() const;
4503
4504
  /**
4505
   * Returns true if existing rendered pixels of this display item may need
4506
   * to be redrawn if the positioning area size changes but its position does
4507
   * not.
4508
   * If false, only the changed painting area needs to be redrawn when the
4509
   * positioning area size changes but its position does not.
4510
   */
4511
  bool RenderingMightDependOnPositioningAreaSizeChange() const;
4512
4513
  nsDisplayItemGeometry* AllocateGeometry(
4514
    nsDisplayListBuilder* aBuilder) override
4515
0
  {
4516
0
    return new nsDisplayBackgroundGeometry(this, aBuilder);
4517
0
  }
4518
4519
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
4520
                                 const nsDisplayItemGeometry* aGeometry,
4521
                                 nsRegion* aInvalidRegion) const override;
4522
  bool CanOptimizeToImageLayer(LayerManager* aManager,
4523
                               nsDisplayListBuilder* aBuilder) override;
4524
  already_AddRefed<imgIContainer> GetImage() override;
4525
  nsRect GetDestRect() const override;
4526
4527
  void UpdateDrawResult(mozilla::image::ImgDrawResult aResult) override
4528
0
  {
4529
0
    nsDisplayBackgroundGeometry::UpdateDrawResult(this, aResult);
4530
0
  }
4531
4532
  static nsRegion GetInsideClipRegion(const nsDisplayItem* aItem,
4533
                                      StyleGeometryBox aClip,
4534
                                      const nsRect& aRect,
4535
                                      const nsRect& aBackgroundRect);
4536
4537
  bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) const override
4538
0
  {
4539
0
    return mShouldFixToViewport;
4540
0
  }
4541
4542
0
  nsIFrame* GetDependentFrame() override { return mDependentFrame; }
4543
4544
  void SetDependentFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
4545
0
  {
4546
0
    if (!aBuilder->IsRetainingDisplayList()) {
4547
0
      return;
4548
0
    }
4549
0
    mDependentFrame = aFrame;
4550
0
    if (aFrame) {
4551
0
      mDependentFrame->AddDisplayItem(this);
4552
0
    }
4553
0
  }
4554
4555
  void RemoveFrame(nsIFrame* aFrame) override
4556
0
  {
4557
0
    if (aFrame == mDependentFrame) {
4558
0
      mDependentFrame = nullptr;
4559
0
    }
4560
0
    nsDisplayItem::RemoveFrame(aFrame);
4561
0
  }
4562
4563
protected:
4564
  typedef class mozilla::layers::ImageContainer ImageContainer;
4565
  typedef class mozilla::layers::ImageLayer ImageLayer;
4566
4567
  bool CanBuildWebRenderDisplayItems(LayerManager* aManager,
4568
                                     nsDisplayListBuilder* aBuilder);
4569
  nsRect GetBoundsInternal(nsDisplayListBuilder* aBuilder,
4570
                           nsIFrame* aFrameForBounds = nullptr);
4571
4572
  void PaintInternal(nsDisplayListBuilder* aBuilder,
4573
                     gfxContext* aCtx,
4574
                     const nsRect& aBounds,
4575
                     nsRect* aClipRect);
4576
4577
  // Determine whether we want to be separated into our own layer, independent
4578
  // of whether this item can actually be layerized.
4579
  enum ImageLayerization
4580
  {
4581
    WHENEVER_POSSIBLE,
4582
    ONLY_FOR_SCALING,
4583
    NO_LAYER_NEEDED
4584
  };
4585
  ImageLayerization ShouldCreateOwnLayer(nsDisplayListBuilder* aBuilder,
4586
                                         LayerManager* aManager);
4587
4588
  // Cache the result of nsCSSRendering::FindBackground. Always null if
4589
  // mIsThemed is true or if FindBackground returned false.
4590
  RefPtr<mozilla::ComputedStyle> mBackgroundStyle;
4591
  nsCOMPtr<imgIContainer> mImage;
4592
  nsIFrame* mDependentFrame;
4593
  nsRect mBackgroundRect; // relative to the reference frame
4594
  nsRect mFillRect;
4595
  nsRect mDestRect;
4596
  /* Bounds of this display item */
4597
  nsRect mBounds;
4598
  uint32_t mLayer;
4599
  bool mIsRasterImage;
4600
  /* Whether the image should be treated as fixed to the viewport. */
4601
  bool mShouldFixToViewport;
4602
  uint32_t mImageFlags;
4603
};
4604
4605
enum class TableType : uint8_t
4606
{
4607
  TABLE,
4608
  TABLE_COL,
4609
  TABLE_COL_GROUP,
4610
  TABLE_ROW,
4611
  TABLE_ROW_GROUP,
4612
  TABLE_CELL,
4613
4614
  TABLE_TYPE_MAX
4615
};
4616
4617
enum class TableTypeBits : uint8_t
4618
{
4619
  COUNT = 3
4620
};
4621
4622
static_assert(static_cast<uint8_t>(TableType::TABLE_TYPE_MAX) <
4623
                (1 << (static_cast<uint8_t>(TableTypeBits::COUNT) + 1)),
4624
              "TableType cannot fit with TableTypeBits::COUNT");
4625
TableType
4626
GetTableTypeFromFrame(nsIFrame* aFrame);
4627
4628
/**
4629
 * A display item to paint background image for table. For table parts, such
4630
 * as row, row group, col, col group, when drawing its background, we'll
4631
 * create separate background image display item for its containning cell.
4632
 * Those background image display items will reference to same DisplayItemData
4633
 * if we keep the mFrame point to cell's ancestor frame. We don't want to this
4634
 * happened bacause share same DisplatItemData will cause many bugs. So that
4635
 * we let mFrame point to cell frame and store the table type of the ancestor
4636
 * frame. And use mFrame and table type as key to generate DisplayItemData to
4637
 * avoid sharing DisplayItemData.
4638
 *
4639
 * Also store ancestor frame as mStyleFrame for all rendering informations.
4640
 */
4641
class nsDisplayTableBackgroundImage : public nsDisplayBackgroundImage
4642
{
4643
public:
4644
  nsDisplayTableBackgroundImage(nsDisplayListBuilder* aBuilder,
4645
                                const InitData& aInitData,
4646
                                nsIFrame* aCellFrame);
4647
  ~nsDisplayTableBackgroundImage() override;
4648
4649
  NS_DISPLAY_DECL_NAME("TableBackgroundImage", TYPE_TABLE_BACKGROUND_IMAGE)
4650
4651
  uint32_t GetPerFrameKey() const override
4652
0
  {
4653
0
    return (mLayer << (TYPE_BITS +
4654
0
                       static_cast<uint8_t>(TableTypeBits::COUNT))) |
4655
0
           (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
4656
0
           nsDisplayItem::GetPerFrameKey();
4657
0
  }
4658
4659
  bool IsInvalid(nsRect& aRect) const override;
4660
4661
0
  nsIFrame* FrameForInvalidation() const override { return mStyleFrame; }
4662
4663
  bool HasDeletedFrame() const override
4664
0
  {
4665
0
    return !mStyleFrame || nsDisplayBackgroundImage::HasDeletedFrame();
4666
0
  }
4667
4668
  void RemoveFrame(nsIFrame* aFrame) override
4669
0
  {
4670
0
    if (aFrame == mStyleFrame) {
4671
0
      mStyleFrame = nullptr;
4672
0
    }
4673
0
    nsDisplayBackgroundImage::RemoveFrame(aFrame);
4674
0
  }
4675
4676
protected:
4677
0
  nsIFrame* StyleFrame() const override { return mStyleFrame; }
4678
4679
  nsIFrame* mStyleFrame;
4680
  TableType mTableType;
4681
};
4682
4683
/**
4684
 * A display item to paint the native theme background for a frame.
4685
 */
4686
class nsDisplayThemedBackground : public nsDisplayItem
4687
{
4688
public:
4689
  nsDisplayThemedBackground(nsDisplayListBuilder* aBuilder,
4690
                            nsIFrame* aFrame,
4691
                            const nsRect& aBackgroundRect);
4692
4693
#ifdef NS_BUILD_REFCNT_LOGGING
4694
  ~nsDisplayThemedBackground() override
4695
  {
4696
    MOZ_COUNT_DTOR(nsDisplayThemedBackground);
4697
  }
4698
#else
4699
  ~nsDisplayThemedBackground() override = default;
4700
#endif
4701
4702
  NS_DISPLAY_DECL_NAME("ThemedBackground", TYPE_THEMED_BACKGROUND)
4703
4704
  void Init(nsDisplayListBuilder* aBuilder);
4705
4706
  void Destroy(nsDisplayListBuilder* aBuilder) override
4707
0
  {
4708
0
    aBuilder->UnregisterThemeGeometry(this);
4709
0
    nsDisplayItem::Destroy(aBuilder);
4710
0
  }
4711
4712
  void HitTest(nsDisplayListBuilder* aBuilder,
4713
               const nsRect& aRect,
4714
               HitTestState* aState,
4715
               nsTArray<nsIFrame*>* aOutFrames) override;
4716
  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
4717
                           bool* aSnap) const override;
4718
  mozilla::Maybe<nscolor> IsUniform(
4719
    nsDisplayListBuilder* aBuilder) const override;
4720
  bool CreateWebRenderCommands(
4721
    mozilla::wr::DisplayListBuilder& aBuilder,
4722
    mozilla::wr::IpcResourceUpdateQueue& aResources,
4723
    const StackingContextHelper& aSc,
4724
    mozilla::layers::WebRenderLayerManager* aManager,
4725
    nsDisplayListBuilder* aDisplayListBuilder) override;
4726
4727
0
  bool MustPaintOnContentSide() const override { return true; }
4728
4729
  /**
4730
   * GetBounds() returns the background painting area.
4731
   */
4732
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
4733
4734
  void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
4735
4736
  /**
4737
   * Return the background positioning area.
4738
   * (GetBounds() returns the background painting area.)
4739
   * Can be called only when mBackgroundStyle is non-null.
4740
   */
4741
  nsRect GetPositioningArea() const;
4742
4743
  /**
4744
   * Return whether our frame's document does not have the state
4745
   * NS_DOCUMENT_STATE_WINDOW_INACTIVE.
4746
   */
4747
  bool IsWindowActive() const;
4748
4749
  nsDisplayItemGeometry* AllocateGeometry(
4750
    nsDisplayListBuilder* aBuilder) override
4751
0
  {
4752
0
    return new nsDisplayThemedBackgroundGeometry(this, aBuilder);
4753
0
  }
4754
4755
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
4756
                                 const nsDisplayItemGeometry* aGeometry,
4757
                                 nsRegion* aInvalidRegion) const override;
4758
4759
  void WriteDebugInfo(std::stringstream& aStream) override;
4760
4761
protected:
4762
  nsRect GetBoundsInternal();
4763
4764
  void PaintInternal(nsDisplayListBuilder* aBuilder,
4765
                     gfxContext* aCtx,
4766
                     const nsRect& aBounds,
4767
                     nsRect* aClipRect);
4768
4769
  nsRect mBackgroundRect;
4770
  nsRect mBounds;
4771
  nsITheme::Transparency mThemeTransparency;
4772
  mozilla::StyleAppearance mAppearance;
4773
};
4774
4775
class nsDisplayTableThemedBackground : public nsDisplayThemedBackground
4776
{
4777
public:
4778
  nsDisplayTableThemedBackground(nsDisplayListBuilder* aBuilder,
4779
                                 nsIFrame* aFrame,
4780
                                 const nsRect& aBackgroundRect,
4781
                                 nsIFrame* aAncestorFrame)
4782
    : nsDisplayThemedBackground(aBuilder, aFrame, aBackgroundRect)
4783
    , mAncestorFrame(aAncestorFrame)
4784
    , mTableType(GetTableTypeFromFrame(aAncestorFrame))
4785
0
  {
4786
0
    if (aBuilder->IsRetainingDisplayList()) {
4787
0
      mAncestorFrame->AddDisplayItem(this);
4788
0
    }
4789
0
  }
4790
4791
  ~nsDisplayTableThemedBackground() override
4792
0
  {
4793
0
    if (mAncestorFrame) {
4794
0
      mAncestorFrame->RemoveDisplayItem(this);
4795
0
    }
4796
0
  }
4797
4798
  NS_DISPLAY_DECL_NAME("TableThemedBackground",
4799
                       TYPE_TABLE_THEMED_BACKGROUND_IMAGE)
4800
4801
  uint32_t GetPerFrameKey() const override
4802
0
  {
4803
0
    return (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
4804
0
           nsDisplayItem::GetPerFrameKey();
4805
0
  }
4806
4807
0
  nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
4808
4809
  bool HasDeletedFrame() const override
4810
0
  {
4811
0
    return !mAncestorFrame || nsDisplayThemedBackground::HasDeletedFrame();
4812
0
  }
4813
4814
  void RemoveFrame(nsIFrame* aFrame) override
4815
0
  {
4816
0
    if (aFrame == mAncestorFrame) {
4817
0
      mAncestorFrame = nullptr;
4818
0
    }
4819
0
    nsDisplayThemedBackground::RemoveFrame(aFrame);
4820
0
  }
4821
4822
protected:
4823
0
  nsIFrame* StyleFrame() const override { return mAncestorFrame; }
4824
  nsIFrame* mAncestorFrame;
4825
  TableType mTableType;
4826
};
4827
4828
class nsDisplayBackgroundColor : public nsDisplayItem
4829
{
4830
  typedef mozilla::gfx::Color Color;
4831
4832
public:
4833
  nsDisplayBackgroundColor(nsDisplayListBuilder* aBuilder,
4834
                           nsIFrame* aFrame,
4835
                           const nsRect& aBackgroundRect,
4836
                           mozilla::ComputedStyle* aBackgroundStyle,
4837
                           nscolor aColor)
4838
    : nsDisplayItem(aBuilder, aFrame)
4839
    , mBackgroundRect(aBackgroundRect)
4840
    , mBackgroundStyle(aBackgroundStyle)
4841
    , mDependentFrame(nullptr)
4842
    , mColor(Color::FromABGR(aColor))
4843
0
  {
4844
0
    mState.mColor = mColor;
4845
0
  }
4846
4847
  ~nsDisplayBackgroundColor() override
4848
0
  {
4849
0
    if (mDependentFrame) {
4850
0
      mDependentFrame->RemoveDisplayItem(this);
4851
0
    }
4852
0
  }
4853
4854
  NS_DISPLAY_DECL_NAME("BackgroundColor", TYPE_BACKGROUND_COLOR)
4855
4856
  void RestoreState() override
4857
0
  {
4858
0
    nsDisplayItem::RestoreState();
4859
0
    mColor = mState.mColor;
4860
0
  }
4861
4862
  LayerState GetLayerState(
4863
    nsDisplayListBuilder* aBuilder,
4864
    LayerManager* aManager,
4865
    const ContainerLayerParameters& aParameters) override;
4866
  void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
4867
  void PaintWithClip(nsDisplayListBuilder* aBuilder,
4868
                     gfxContext* aCtx,
4869
                     const DisplayItemClip& aClip) override;
4870
  already_AddRefed<Layer> BuildLayer(
4871
    nsDisplayListBuilder* aBuilder,
4872
    LayerManager* aManager,
4873
    const ContainerLayerParameters& aContainerParameters) override;
4874
  bool CreateWebRenderCommands(
4875
    mozilla::wr::DisplayListBuilder& aBuilder,
4876
    mozilla::wr::IpcResourceUpdateQueue& aResources,
4877
    const StackingContextHelper& aSc,
4878
    mozilla::layers::WebRenderLayerManager* aManager,
4879
    nsDisplayListBuilder* aDisplayListBuilder) override;
4880
  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
4881
                           bool* aSnap) const override;
4882
  mozilla::Maybe<nscolor> IsUniform(
4883
    nsDisplayListBuilder* aBuilder) const override;
4884
  void HitTest(nsDisplayListBuilder* aBuilder,
4885
               const nsRect& aRect,
4886
               HitTestState* aState,
4887
               nsTArray<nsIFrame*>* aOutFrames) override;
4888
  void ApplyOpacity(nsDisplayListBuilder* aBuilder,
4889
                    float aOpacity,
4890
                    const DisplayItemClipChain* aClip) override;
4891
4892
  bool CanApplyOpacity() const override;
4893
4894
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override
4895
0
  {
4896
0
    *aSnap = true;
4897
0
    return mBackgroundRect;
4898
0
  }
4899
4900
  bool CanPaintWithClip(const DisplayItemClip& aClip) override
4901
0
  {
4902
0
    mozilla::StyleGeometryBox clip =
4903
0
      mBackgroundStyle->StyleBackground()->mImage.mLayers[0].mClip;
4904
0
4905
0
    if (clip == mozilla::StyleGeometryBox::Text) {
4906
0
      return false;
4907
0
    }
4908
0
    if (aClip.GetRoundedRectCount() > 1) {
4909
0
      return false;
4910
0
    }
4911
0
    return true;
4912
0
  }
4913
4914
  nsDisplayItemGeometry* AllocateGeometry(
4915
    nsDisplayListBuilder* aBuilder) override
4916
0
  {
4917
0
    return new nsDisplaySolidColorGeometry(this, aBuilder, mColor.ToABGR());
4918
0
  }
4919
4920
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
4921
                                 const nsDisplayItemGeometry* aGeometry,
4922
                                 nsRegion* aInvalidRegion) const override
4923
0
  {
4924
0
    const nsDisplaySolidColorGeometry* geometry =
4925
0
      static_cast<const nsDisplaySolidColorGeometry*>(aGeometry);
4926
0
4927
0
    if (mColor.ToABGR() != geometry->mColor) {
4928
0
      bool dummy;
4929
0
      aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &dummy));
4930
0
      return;
4931
0
    }
4932
0
    ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
4933
0
  }
4934
4935
0
  nsIFrame* GetDependentFrame() override { return mDependentFrame; }
4936
4937
  void SetDependentFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
4938
0
  {
4939
0
    if (!aBuilder->IsRetainingDisplayList()) {
4940
0
      return;
4941
0
    }
4942
0
    mDependentFrame = aFrame;
4943
0
    if (aFrame) {
4944
0
      mDependentFrame->AddDisplayItem(this);
4945
0
    }
4946
0
  }
4947
4948
  void RemoveFrame(nsIFrame* aFrame) override
4949
0
  {
4950
0
    if (aFrame == mDependentFrame) {
4951
0
      mDependentFrame = nullptr;
4952
0
    }
4953
0
    nsDisplayItem::RemoveFrame(aFrame);
4954
0
  }
4955
4956
  void WriteDebugInfo(std::stringstream& aStream) override;
4957
4958
protected:
4959
  const nsRect mBackgroundRect;
4960
  RefPtr<mozilla::ComputedStyle> mBackgroundStyle;
4961
  nsIFrame* mDependentFrame;
4962
  mozilla::gfx::Color mColor;
4963
4964
  struct
4965
  {
4966
    mozilla::gfx::Color mColor;
4967
  } mState;
4968
};
4969
4970
class nsDisplayTableBackgroundColor : public nsDisplayBackgroundColor
4971
{
4972
public:
4973
  nsDisplayTableBackgroundColor(nsDisplayListBuilder* aBuilder,
4974
                                nsIFrame* aFrame,
4975
                                const nsRect& aBackgroundRect,
4976
                                mozilla::ComputedStyle* aBackgroundStyle,
4977
                                nscolor aColor,
4978
                                nsIFrame* aAncestorFrame)
4979
    : nsDisplayBackgroundColor(aBuilder,
4980
                               aFrame,
4981
                               aBackgroundRect,
4982
                               aBackgroundStyle,
4983
                               aColor)
4984
    , mAncestorFrame(aAncestorFrame)
4985
    , mTableType(GetTableTypeFromFrame(aAncestorFrame))
4986
0
  {
4987
0
    if (aBuilder->IsRetainingDisplayList()) {
4988
0
      mAncestorFrame->AddDisplayItem(this);
4989
0
    }
4990
0
  }
4991
4992
  ~nsDisplayTableBackgroundColor() override
4993
0
  {
4994
0
    if (mAncestorFrame) {
4995
0
      mAncestorFrame->RemoveDisplayItem(this);
4996
0
    }
4997
0
  }
4998
4999
  NS_DISPLAY_DECL_NAME("TableBackgroundColor", TYPE_TABLE_BACKGROUND_COLOR)
5000
5001
0
  nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
5002
5003
  bool HasDeletedFrame() const override
5004
0
  {
5005
0
    return !mAncestorFrame || nsDisplayBackgroundColor::HasDeletedFrame();
5006
0
  }
5007
5008
  void RemoveFrame(nsIFrame* aFrame) override
5009
0
  {
5010
0
    if (aFrame == mAncestorFrame) {
5011
0
      mAncestorFrame = nullptr;
5012
0
    }
5013
0
    nsDisplayBackgroundColor::RemoveFrame(aFrame);
5014
0
  }
5015
5016
  uint32_t GetPerFrameKey() const override
5017
0
  {
5018
0
    return (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
5019
0
           nsDisplayItem::GetPerFrameKey();
5020
0
  }
5021
5022
protected:
5023
  nsIFrame* mAncestorFrame;
5024
  TableType mTableType;
5025
};
5026
5027
class nsDisplayClearBackground : public nsDisplayItem
5028
{
5029
public:
5030
  nsDisplayClearBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
5031
    : nsDisplayItem(aBuilder, aFrame)
5032
0
  {
5033
0
  }
5034
5035
  NS_DISPLAY_DECL_NAME("ClearBackground", TYPE_CLEAR_BACKGROUND)
5036
5037
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override
5038
0
  {
5039
0
    *aSnap = true;
5040
0
    return nsRect(ToReferenceFrame(), Frame()->GetSize());
5041
0
  }
5042
5043
  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
5044
                           bool* aSnap) const override
5045
0
  {
5046
0
    *aSnap = false;
5047
0
    return GetBounds(aBuilder, aSnap);
5048
0
  }
5049
5050
  mozilla::Maybe<nscolor> IsUniform(
5051
    nsDisplayListBuilder* aBuilder) const override
5052
0
  {
5053
0
    return mozilla::Some(NS_RGBA(0, 0, 0, 0));
5054
0
  }
5055
5056
0
  bool ClearsBackground() const override { return true; }
5057
5058
  LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
5059
                           LayerManager* aManager,
5060
                           const ContainerLayerParameters& aParameters) override
5061
0
  {
5062
0
    return mozilla::LAYER_ACTIVE_FORCE;
5063
0
  }
5064
5065
  already_AddRefed<Layer> BuildLayer(
5066
    nsDisplayListBuilder* aBuilder,
5067
    LayerManager* aManager,
5068
    const ContainerLayerParameters& aContainerParameters) override;
5069
5070
  bool CreateWebRenderCommands(
5071
    mozilla::wr::DisplayListBuilder& aBuilder,
5072
    mozilla::wr::IpcResourceUpdateQueue& aResources,
5073
    const StackingContextHelper& aSc,
5074
    mozilla::layers::WebRenderLayerManager* aManager,
5075
    nsDisplayListBuilder* aDisplayListBuilder) override;
5076
};
5077
5078
/**
5079
 * The standard display item to paint the outer CSS box-shadows of a frame.
5080
 */
5081
class nsDisplayBoxShadowOuter final : public nsDisplayItem
5082
{
5083
public:
5084
  nsDisplayBoxShadowOuter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
5085
    : nsDisplayItem(aBuilder, aFrame)
5086
    , mOpacity(1.0f)
5087
0
  {
5088
0
    MOZ_COUNT_CTOR(nsDisplayBoxShadowOuter);
5089
0
    mBounds = GetBoundsInternal();
5090
0
  }
5091
5092
#ifdef NS_BUILD_REFCNT_LOGGING
5093
  ~nsDisplayBoxShadowOuter() override
5094
  {
5095
    MOZ_COUNT_DTOR(nsDisplayBoxShadowOuter);
5096
  }
5097
#endif
5098
5099
  NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER)
5100
5101
  void RestoreState() override
5102
0
  {
5103
0
    nsDisplayItem::RestoreState();
5104
0
    mVisibleRegion.SetEmpty();
5105
0
    mOpacity = 1.0f;
5106
0
  }
5107
5108
  void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
5109
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
5110
  bool IsInvisibleInRect(const nsRect& aRect) const override;
5111
  bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
5112
                         nsRegion* aVisibleRegion) override;
5113
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
5114
                                 const nsDisplayItemGeometry* aGeometry,
5115
                                 nsRegion* aInvalidRegion) const override;
5116
5117
  void ApplyOpacity(nsDisplayListBuilder* aBuilder,
5118
                    float aOpacity,
5119
                    const DisplayItemClipChain* aClip) override
5120
0
  {
5121
0
    NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
5122
0
    mOpacity = aOpacity;
5123
0
    IntersectClip(aBuilder, aClip, false);
5124
0
  }
5125
5126
0
  bool CanApplyOpacity() const override { return true; }
5127
5128
  nsDisplayItemGeometry* AllocateGeometry(
5129
    nsDisplayListBuilder* aBuilder) override
5130
0
  {
5131
0
    return new nsDisplayBoxShadowOuterGeometry(this, aBuilder, mOpacity);
5132
0
  }
5133
5134
  bool CanBuildWebRenderDisplayItems();
5135
  bool CreateWebRenderCommands(
5136
    mozilla::wr::DisplayListBuilder& aBuilder,
5137
    mozilla::wr::IpcResourceUpdateQueue& aResources,
5138
    const StackingContextHelper& aSc,
5139
    mozilla::layers::WebRenderLayerManager* aManager,
5140
    nsDisplayListBuilder* aDisplayListBuilder) override;
5141
  nsRect GetBoundsInternal();
5142
5143
private:
5144
  nsRegion mVisibleRegion;
5145
  nsRect mBounds;
5146
  float mOpacity;
5147
};
5148
5149
/**
5150
 * The standard display item to paint the inner CSS box-shadows of a frame.
5151
 */
5152
class nsDisplayBoxShadowInner : public nsDisplayItem
5153
{
5154
public:
5155
  nsDisplayBoxShadowInner(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
5156
    : nsDisplayItem(aBuilder, aFrame)
5157
0
  {
5158
0
    MOZ_COUNT_CTOR(nsDisplayBoxShadowInner);
5159
0
  }
5160
5161
#ifdef NS_BUILD_REFCNT_LOGGING
5162
  ~nsDisplayBoxShadowInner() override
5163
  {
5164
    MOZ_COUNT_DTOR(nsDisplayBoxShadowInner);
5165
  }
5166
#endif
5167
5168
  NS_DISPLAY_DECL_NAME("BoxShadowInner", TYPE_BOX_SHADOW_INNER)
5169
5170
  void RestoreState() override
5171
0
  {
5172
0
    nsDisplayItem::RestoreState();
5173
0
    mVisibleRegion.SetEmpty();
5174
0
  }
5175
5176
  void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
5177
  bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
5178
                         nsRegion* aVisibleRegion) override;
5179
5180
  nsDisplayItemGeometry* AllocateGeometry(
5181
    nsDisplayListBuilder* aBuilder) override
5182
0
  {
5183
0
    return new nsDisplayBoxShadowInnerGeometry(this, aBuilder);
5184
0
  }
5185
5186
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
5187
                                 const nsDisplayItemGeometry* aGeometry,
5188
                                 nsRegion* aInvalidRegion) const override
5189
0
  {
5190
0
    const nsDisplayBoxShadowInnerGeometry* geometry =
5191
0
      static_cast<const nsDisplayBoxShadowInnerGeometry*>(aGeometry);
5192
0
    if (!geometry->mPaddingRect.IsEqualInterior(GetPaddingRect())) {
5193
0
      // nsDisplayBoxShadowInner is based around the padding rect, but it can
5194
0
      // touch pixels outside of this. We should invalidate the entire bounds.
5195
0
      bool snap;
5196
0
      aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &snap));
5197
0
    }
5198
0
  }
5199
5200
  static bool CanCreateWebRenderCommands(nsDisplayListBuilder* aBuilder,
5201
                                         nsIFrame* aFrame,
5202
                                         const nsPoint& aReferencePoint);
5203
  static void CreateInsetBoxShadowWebRenderCommands(
5204
    mozilla::wr::DisplayListBuilder& aBuilder,
5205
    const StackingContextHelper& aSc,
5206
    nsRegion& aVisibleRegion,
5207
    nsIFrame* aFrame,
5208
    const nsRect& aBorderRect);
5209
  bool CreateWebRenderCommands(
5210
    mozilla::wr::DisplayListBuilder& aBuilder,
5211
    mozilla::wr::IpcResourceUpdateQueue& aResources,
5212
    const StackingContextHelper& aSc,
5213
    mozilla::layers::WebRenderLayerManager* aManager,
5214
    nsDisplayListBuilder* aDisplayListBuilder) override;
5215
5216
private:
5217
  nsRegion mVisibleRegion;
5218
};
5219
5220
/**
5221
 * The standard display item to paint the CSS outline of a frame.
5222
 */
5223
class nsDisplayOutline : public nsDisplayItem
5224
{
5225
public:
5226
  nsDisplayOutline(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
5227
    : nsDisplayItem(aBuilder, aFrame)
5228
0
  {
5229
0
    MOZ_COUNT_CTOR(nsDisplayOutline);
5230
0
  }
5231
5232
#ifdef NS_BUILD_REFCNT_LOGGING
5233
  ~nsDisplayOutline() override { MOZ_COUNT_DTOR(nsDisplayOutline); }
5234
#endif
5235
5236
  NS_DISPLAY_DECL_NAME("Outline", TYPE_OUTLINE)
5237
5238
  bool CreateWebRenderCommands(
5239
    mozilla::wr::DisplayListBuilder& aBuilder,
5240
    mozilla::wr::IpcResourceUpdateQueue& aResources,
5241
    const StackingContextHelper& aSc,
5242
    mozilla::layers::WebRenderLayerManager* aManager,
5243
    nsDisplayListBuilder* aDisplayListBuilder) override;
5244
  bool IsInvisibleInRect(const nsRect& aRect) const override;
5245
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
5246
  void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
5247
};
5248
5249
/**
5250
 * A class that lets you receive events within the frame bounds but never
5251
 * paints.
5252
 */
5253
class nsDisplayEventReceiver : public nsDisplayItem
5254
{
5255
public:
5256
  nsDisplayEventReceiver(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
5257
    : nsDisplayItem(aBuilder, aFrame)
5258
0
  {
5259
0
    MOZ_COUNT_CTOR(nsDisplayEventReceiver);
5260
0
  }
5261
5262
#ifdef NS_BUILD_REFCNT_LOGGING
5263
  ~nsDisplayEventReceiver() override { MOZ_COUNT_DTOR(nsDisplayEventReceiver); }
5264
#endif
5265
5266
  NS_DISPLAY_DECL_NAME("EventReceiver", TYPE_EVENT_RECEIVER)
5267
5268
  void HitTest(nsDisplayListBuilder* aBuilder,
5269
               const nsRect& aRect,
5270
               HitTestState* aState,
5271
               nsTArray<nsIFrame*>* aOutFrames) override;
5272
  bool CreateWebRenderCommands(
5273
    mozilla::wr::DisplayListBuilder& aBuilder,
5274
    mozilla::wr::IpcResourceUpdateQueue& aResources,
5275
    const StackingContextHelper& aSc,
5276
    mozilla::layers::WebRenderLayerManager* aManager,
5277
    nsDisplayListBuilder* aDisplayListBuilder) override;
5278
};
5279
5280
/**
5281
 * Similar to nsDisplayEventReceiver in that it is used for hit-testing. However
5282
 * this gets built when we're doing widget painting and we need to send the
5283
 * compositor some hit-test info for a frame. This is effectively a dummy item
5284
 * whose sole purpose is to carry the hit-test info to the compositor.
5285
 */
5286
class nsDisplayCompositorHitTestInfo : public nsDisplayEventReceiver
5287
{
5288
public:
5289
  nsDisplayCompositorHitTestInfo(
5290
    nsDisplayListBuilder* aBuilder,
5291
    nsIFrame* aFrame,
5292
    mozilla::gfx::CompositorHitTestInfo aHitTestInfo,
5293
    uint32_t aIndex = 0,
5294
    const mozilla::Maybe<nsRect>& aArea = mozilla::Nothing());
5295
5296
#ifdef NS_BUILD_REFCNT_LOGGING
5297
  ~nsDisplayCompositorHitTestInfo() override
5298
  {
5299
    MOZ_COUNT_DTOR(nsDisplayCompositorHitTestInfo);
5300
  }
5301
#endif
5302
5303
  NS_DISPLAY_DECL_NAME("CompositorHitTestInfo", TYPE_COMPOSITOR_HITTEST_INFO)
5304
5305
  mozilla::gfx::CompositorHitTestInfo HitTestInfo() const
5306
0
  {
5307
0
    return mHitTestInfo;
5308
0
  }
5309
5310
  bool CreateWebRenderCommands(
5311
    mozilla::wr::DisplayListBuilder& aBuilder,
5312
    mozilla::wr::IpcResourceUpdateQueue& aResources,
5313
    const StackingContextHelper& aSc,
5314
    mozilla::layers::WebRenderLayerManager* aManager,
5315
    nsDisplayListBuilder* aDisplayListBuilder) override;
5316
  void WriteDebugInfo(std::stringstream& aStream) override;
5317
  uint32_t GetPerFrameKey() const override;
5318
  int32_t ZIndex() const override;
5319
  void SetOverrideZIndex(int32_t aZIndex);
5320
5321
  /**
5322
   * Returns the hit test area of this item.
5323
   */
5324
0
  const nsRect& Area() const { return mArea; }
5325
5326
  /**
5327
   * ApplyOpacity() is overriden for opacity flattening.
5328
   */
5329
  void ApplyOpacity(nsDisplayListBuilder* aBuilder,
5330
                    float aOpacity,
5331
                    const DisplayItemClipChain* aClip) override
5332
0
  {
5333
0
  }
5334
5335
  /**
5336
   * CanApplyOpacity() is overriden for opacity flattening.
5337
   */
5338
0
  bool CanApplyOpacity() const override { return true; }
5339
5340
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override
5341
0
  {
5342
0
    *aSnap = false;
5343
0
    return nsRect();
5344
0
  }
5345
5346
private:
5347
  mozilla::gfx::CompositorHitTestInfo mHitTestInfo;
5348
  mozilla::Maybe<mozilla::layers::FrameMetrics::ViewID> mScrollTarget;
5349
  nsRect mArea;
5350
  uint32_t mIndex;
5351
  mozilla::Maybe<int32_t> mOverrideZIndex;
5352
  int32_t mAppUnitsPerDevPixel;
5353
};
5354
5355
/**
5356
 * A class that lets you wrap a display list as a display item.
5357
 *
5358
 * GetUnderlyingFrame() is troublesome for wrapped lists because if the wrapped
5359
 * list has many items, it's not clear which one has the 'underlying frame'.
5360
 * Thus we force the creator to specify what the underlying frame is. The
5361
 * underlying frame should be the root of a stacking context, because sorting
5362
 * a list containing this item will not get at the children.
5363
 *
5364
 * In some cases (e.g., clipping) we want to wrap a list but we don't have a
5365
 * particular underlying frame that is a stacking context root. In that case
5366
 * we allow the frame to be nullptr. Callers to GetUnderlyingFrame must
5367
 * detect and handle this case.
5368
 */
5369
class nsDisplayWrapList : public nsDisplayItem
5370
{
5371
public:
5372
  /**
5373
   * Takes all the items from aList and puts them in our list.
5374
   */
5375
  nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
5376
                    nsIFrame* aFrame,
5377
                    nsDisplayList* aList,
5378
                    bool aAnonymous = false);
5379
  nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
5380
                    nsIFrame* aFrame,
5381
                    nsDisplayList* aList,
5382
                    const ActiveScrolledRoot* aActiveScrolledRoot,
5383
                    bool aClearClipChain = false,
5384
                    uint32_t aIndex = 0,
5385
                    bool aAnonymous = false);
5386
  nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
5387
                    nsIFrame* aFrame,
5388
                    nsDisplayItem* aItem,
5389
                    bool aAnonymous = false);
5390
  nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
5391
    : nsDisplayItem(aBuilder, aFrame)
5392
    , mFrameActiveScrolledRoot(aBuilder->CurrentActiveScrolledRoot())
5393
    , mOverrideZIndex(0)
5394
    , mIndex(0)
5395
    , mHasZIndexOverride(false)
5396
0
  {
5397
0
    MOZ_COUNT_CTOR(nsDisplayWrapList);
5398
0
    mBaseBuildingRect = GetBuildingRect();
5399
0
    mListPtr = &mList;
5400
0
  }
5401
5402
  nsDisplayWrapList() = delete;
5403
5404
  /**
5405
   * A custom copy-constructor that does not copy mList, as this would mutate
5406
   * the other item.
5407
   */
5408
  nsDisplayWrapList(const nsDisplayWrapList& aOther) = delete;
5409
  nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
5410
                    const nsDisplayWrapList& aOther)
5411
    : nsDisplayItem(aBuilder, aOther)
5412
    , mListPtr(&mList)
5413
    , mFrameActiveScrolledRoot(aOther.mFrameActiveScrolledRoot)
5414
    , mMergedFrames(aOther.mMergedFrames)
5415
    , mBounds(aOther.mBounds)
5416
    , mBaseBuildingRect(aOther.mBaseBuildingRect)
5417
    , mOverrideZIndex(aOther.mOverrideZIndex)
5418
    , mIndex(aOther.mIndex)
5419
    , mHasZIndexOverride(aOther.mHasZIndexOverride)
5420
    , mClearingClipChain(aOther.mClearingClipChain)
5421
0
  {
5422
0
    MOZ_COUNT_CTOR(nsDisplayWrapList);
5423
0
  }
5424
5425
  ~nsDisplayWrapList() override;
5426
5427
  NS_DISPLAY_DECL_NAME("WrapList", TYPE_WRAP_LIST)
5428
5429
0
  const nsDisplayWrapList* AsDisplayWrapList() const override { return this; }
5430
5431
0
  nsDisplayWrapList* AsDisplayWrapList() override { return this; }
5432
5433
  void Destroy(nsDisplayListBuilder* aBuilder) override
5434
0
  {
5435
0
    mList.DeleteAll(aBuilder);
5436
0
    nsDisplayItem::Destroy(aBuilder);
5437
0
  }
5438
5439
  /**
5440
   * Creates a new nsDisplayWrapList that holds a pointer to the display list
5441
   * owned by the given nsDisplayItem. The new nsDisplayWrapList will be added
5442
   * to the bottom of this item's contents.
5443
   */
5444
  void MergeDisplayListFromItem(nsDisplayListBuilder* aBuilder,
5445
                                const nsDisplayItem* aItem) override;
5446
5447
  /**
5448
   * Call this if the wrapped list is changed.
5449
   */
5450
  void UpdateBounds(nsDisplayListBuilder* aBuilder) override
5451
0
  {
5452
0
    // Clear the clip chain up to the asr, but don't store it, so that we'll
5453
0
    // recover it when we reuse the item.
5454
0
    if (mClearingClipChain) {
5455
0
      const DisplayItemClipChain* clip = mState.mClipChain;
5456
0
      while (clip && ActiveScrolledRoot::IsAncestor(GetActiveScrolledRoot(),
5457
0
                                                    clip->mASR)) {
5458
0
        clip = clip->mParent;
5459
0
      }
5460
0
      SetClipChain(clip, false);
5461
0
    }
5462
0
5463
0
    nsRect buildingRect;
5464
0
    mBounds = mListPtr->GetClippedBoundsWithRespectToASR(
5465
0
      aBuilder, mActiveScrolledRoot, &buildingRect);
5466
0
    // The display list may contain content that's visible outside the visible
5467
0
    // rect (i.e. the current dirty rect) passed in when the item was created.
5468
0
    // This happens when the dirty rect has been restricted to the visual
5469
0
    // overflow rect of a frame for some reason (e.g. when setting up dirty
5470
0
    // rects in nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay), but that
5471
0
    // frame contains placeholders for out-of-flows that aren't descendants of
5472
0
    // the frame.
5473
0
    buildingRect.UnionRect(mBaseBuildingRect, buildingRect);
5474
0
    SetBuildingRect(buildingRect);
5475
0
  }
5476
5477
  void HitTest(nsDisplayListBuilder* aBuilder,
5478
               const nsRect& aRect,
5479
               HitTestState* aState,
5480
               nsTArray<nsIFrame*>* aOutFrames) override;
5481
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
5482
  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
5483
                           bool* aSnap) const override;
5484
  mozilla::Maybe<nscolor> IsUniform(
5485
    nsDisplayListBuilder* aBuilder) const override;
5486
  void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
5487
  bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
5488
                         nsRegion* aVisibleRegion) override;
5489
5490
  uint32_t GetPerFrameKey() const override
5491
0
  {
5492
0
    return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
5493
0
  }
5494
5495
0
  bool CanMerge(const nsDisplayItem* aItem) const override { return false; }
5496
5497
  void Merge(const nsDisplayItem* aItem) override
5498
0
  {
5499
0
    MOZ_ASSERT(CanMerge(aItem));
5500
0
    MOZ_ASSERT(Frame() != aItem->Frame());
5501
0
    MergeFromTrackingMergedFrames(static_cast<const nsDisplayWrapList*>(aItem));
5502
0
  }
5503
5504
  void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) const override
5505
0
  {
5506
0
    aFrames->AppendElements(mMergedFrames);
5507
0
  }
5508
5509
0
  bool HasMergedFrames() const override { return !mMergedFrames.IsEmpty(); }
5510
5511
  bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
5512
0
  {
5513
0
    return true;
5514
0
  }
5515
5516
  bool IsInvalid(nsRect& aRect) const override
5517
0
  {
5518
0
    if (mFrame->IsInvalid(aRect) && aRect.IsEmpty()) {
5519
0
      return true;
5520
0
    }
5521
0
    nsRect temp;
5522
0
    for (uint32_t i = 0; i < mMergedFrames.Length(); i++) {
5523
0
      if (mMergedFrames[i]->IsInvalid(temp) && temp.IsEmpty()) {
5524
0
        aRect.SetEmpty();
5525
0
        return true;
5526
0
      }
5527
0
      aRect = aRect.Union(temp);
5528
0
    }
5529
0
    aRect += ToReferenceFrame();
5530
0
    return !aRect.IsEmpty();
5531
0
  }
5532
5533
  nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const override;
5534
5535
  RetainedDisplayList* GetSameCoordinateSystemChildren() const override
5536
0
  {
5537
0
    NS_ASSERTION(mListPtr->IsEmpty() || !ReferenceFrame() ||
5538
0
                   !mListPtr->GetBottom()->ReferenceFrame() ||
5539
0
                   mListPtr->GetBottom()->ReferenceFrame() == ReferenceFrame(),
5540
0
                 "Children must have same reference frame");
5541
0
    return mListPtr;
5542
0
  }
5543
5544
0
  RetainedDisplayList* GetChildren() const override { return mListPtr; }
5545
5546
  int32_t ZIndex() const override
5547
0
  {
5548
0
    return (mHasZIndexOverride) ? mOverrideZIndex : nsDisplayItem::ZIndex();
5549
0
  }
5550
5551
  void SetOverrideZIndex(int32_t aZIndex)
5552
0
  {
5553
0
    mHasZIndexOverride = true;
5554
0
    mOverrideZIndex = aZIndex;
5555
0
  }
5556
5557
  void SetReferenceFrame(const nsIFrame* aFrame);
5558
5559
  /**
5560
   * This creates a copy of this item, but wrapping aItem instead of
5561
   * our existing list. Only gets called if this item returned nullptr
5562
   * for GetUnderlyingFrame(). aItem is guaranteed to return non-null from
5563
   * GetUnderlyingFrame().
5564
   */
5565
  nsDisplayWrapList* WrapWithClone(nsDisplayListBuilder* aBuilder,
5566
                                   nsDisplayItem* aItem)
5567
  {
5568
    MOZ_ASSERT_UNREACHABLE("We never returned nullptr for GetUnderlyingFrame!");
5569
    return nullptr;
5570
  }
5571
5572
  bool CreateWebRenderCommands(
5573
    mozilla::wr::DisplayListBuilder& aBuilder,
5574
    mozilla::wr::IpcResourceUpdateQueue& aResources,
5575
    const StackingContextHelper& aSc,
5576
    mozilla::layers::WebRenderLayerManager* aManager,
5577
    nsDisplayListBuilder* aDisplayListBuilder) override;
5578
5579
  const ActiveScrolledRoot* GetFrameActiveScrolledRoot()
5580
0
  {
5581
0
    return mFrameActiveScrolledRoot;
5582
0
  }
5583
5584
protected:
5585
  void MergeFromTrackingMergedFrames(const nsDisplayWrapList* aOther)
5586
0
  {
5587
0
    mBounds.UnionRect(mBounds, aOther->mBounds);
5588
0
    nsRect buildingRect;
5589
0
    buildingRect.UnionRect(GetBuildingRect(), aOther->GetBuildingRect());
5590
0
    SetBuildingRect(buildingRect);
5591
0
    mMergedFrames.AppendElement(aOther->mFrame);
5592
0
    mMergedFrames.AppendElements(aOther->mMergedFrames);
5593
0
  }
5594
5595
  RetainedDisplayList mList;
5596
  RetainedDisplayList* mListPtr;
5597
  // The active scrolled root for the frame that created this
5598
  // wrap list.
5599
  RefPtr<const ActiveScrolledRoot> mFrameActiveScrolledRoot;
5600
  // The frames from items that have been merged into this item, excluding
5601
  // this item's own frame.
5602
  nsTArray<nsIFrame*> mMergedFrames;
5603
  nsRect mBounds;
5604
  // Displaylist building rect contributed by this display item itself.
5605
  // Our mBuildingRect may include the visible areas of children.
5606
  nsRect mBaseBuildingRect;
5607
  int32_t mOverrideZIndex;
5608
  uint32_t mIndex;
5609
  bool mHasZIndexOverride;
5610
  bool mClearingClipChain = false;
5611
};
5612
5613
/**
5614
 * We call WrapDisplayList on the in-flow lists: BorderBackground(),
5615
 * BlockBorderBackgrounds() and Content().
5616
 * We call WrapDisplayItem on each item of Outlines(), PositionedDescendants(),
5617
 * and Floats(). This is done to support special wrapping processing for frames
5618
 * that may not be in-flow descendants of the current frame.
5619
 */
5620
class nsDisplayWrapper
5621
{
5622
public:
5623
  // This is never instantiated directly (it has pure virtual methods), so no
5624
  // need to count constructors and destructors.
5625
5626
0
  bool WrapBorderBackground() { return true; }
5627
  virtual nsDisplayItem* WrapList(nsDisplayListBuilder* aBuilder,
5628
                                  nsIFrame* aFrame,
5629
                                  nsDisplayList* aList) = 0;
5630
  virtual nsDisplayItem* WrapItem(nsDisplayListBuilder* aBuilder,
5631
                                  nsDisplayItem* aItem) = 0;
5632
5633
  nsresult WrapLists(nsDisplayListBuilder* aBuilder,
5634
                     nsIFrame* aFrame,
5635
                     const nsDisplayListSet& aIn,
5636
                     const nsDisplayListSet& aOut);
5637
  nsresult WrapListsInPlace(nsDisplayListBuilder* aBuilder,
5638
                            nsIFrame* aFrame,
5639
                            const nsDisplayListSet& aLists);
5640
5641
protected:
5642
0
  nsDisplayWrapper() = default;
5643
};
5644
5645
/**
5646
 * The standard display item to paint a stacking context with translucency
5647
 * set by the stacking context root frame's 'opacity' style.
5648
 */
5649
class nsDisplayOpacity : public nsDisplayWrapList
5650
{
5651
public:
5652
  nsDisplayOpacity(nsDisplayListBuilder* aBuilder,
5653
                   nsIFrame* aFrame,
5654
                   nsDisplayList* aList,
5655
                   const ActiveScrolledRoot* aActiveScrolledRoot,
5656
                   bool aForEventsAndPluginsOnly,
5657
                   bool aNeedsActiveLayer);
5658
5659
  nsDisplayOpacity(nsDisplayListBuilder* aBuilder,
5660
                   const nsDisplayOpacity& aOther)
5661
    : nsDisplayWrapList(aBuilder, aOther)
5662
    , mOpacity(aOther.mOpacity)
5663
    , mForEventsAndPluginsOnly(aOther.mForEventsAndPluginsOnly)
5664
    , mNeedsActiveLayer(aOther.mNeedsActiveLayer)
5665
    , mChildOpacityState(ChildOpacityState::Unknown)
5666
0
  {
5667
0
    // We should not try to merge flattened opacities.
5668
0
    MOZ_ASSERT(aOther.mChildOpacityState != ChildOpacityState::Applied);
5669
0
  }
5670
5671
#ifdef NS_BUILD_REFCNT_LOGGING
5672
  ~nsDisplayOpacity() override { MOZ_COUNT_DTOR(nsDisplayOpacity); }
5673
#endif
5674
5675
  NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
5676
5677
  void RestoreState() override
5678
0
  {
5679
0
    nsDisplayItem::RestoreState();
5680
0
    mOpacity = mState.mOpacity;
5681
0
  }
5682
5683
  nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
5684
0
  {
5685
0
    MOZ_COUNT_CTOR(nsDisplayOpacity);
5686
0
    return MakeDisplayItem<nsDisplayOpacity>(aBuilder, *this);
5687
0
  }
5688
5689
  void InvalidateCachedChildInfo() override
5690
0
  {
5691
0
    mChildOpacityState = ChildOpacityState::Unknown;
5692
0
  }
5693
5694
  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
5695
                           bool* aSnap) const override;
5696
  already_AddRefed<Layer> BuildLayer(
5697
    nsDisplayListBuilder* aBuilder,
5698
    LayerManager* aManager,
5699
    const ContainerLayerParameters& aContainerParameters) override;
5700
  LayerState GetLayerState(
5701
    nsDisplayListBuilder* aBuilder,
5702
    LayerManager* aManager,
5703
    const ContainerLayerParameters& aParameters) override;
5704
  bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
5705
                         nsRegion* aVisibleRegion) override;
5706
5707
  bool CanMerge(const nsDisplayItem* aItem) const override
5708
0
  {
5709
0
    // items for the same content element should be merged into a single
5710
0
    // compositing group
5711
0
    // aItem->GetUnderlyingFrame() returns non-null because it's
5712
0
    // nsDisplayOpacity
5713
0
    return HasDifferentFrame(aItem) && HasSameTypeAndClip(aItem) &&
5714
0
           HasSameContent(aItem);
5715
0
  }
5716
5717
  nsDisplayItemGeometry* AllocateGeometry(
5718
    nsDisplayListBuilder* aBuilder) override
5719
0
  {
5720
0
    return new nsDisplayOpacityGeometry(this, aBuilder, mOpacity);
5721
0
  }
5722
5723
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
5724
                                 const nsDisplayItemGeometry* aGeometry,
5725
                                 nsRegion* aInvalidRegion) const override;
5726
5727
  bool IsInvalid(nsRect& aRect) const override
5728
0
  {
5729
0
    if (mForEventsAndPluginsOnly) {
5730
0
      return false;
5731
0
    }
5732
0
    return nsDisplayWrapList::IsInvalid(aRect);
5733
0
  }
5734
  void ApplyOpacity(nsDisplayListBuilder* aBuilder,
5735
                    float aOpacity,
5736
                    const DisplayItemClipChain* aClip) override;
5737
  bool CanApplyOpacity() const override;
5738
  bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override;
5739
5740
  bool NeedsGeometryUpdates() const override
5741
0
  {
5742
0
    // For flattened nsDisplayOpacity items, ComputeInvalidationRegion() only
5743
0
    // handles invalidation for changed |mOpacity|. In order to keep track of
5744
0
    // the current bounds of the item for invalidation, nsDisplayOpacityGeometry
5745
0
    // for the corresponding DisplayItemData needs to be updated, even if the
5746
0
    // reported invalidation region is empty.
5747
0
    return mChildOpacityState == ChildOpacityState::Deferred;
5748
0
  }
5749
5750
  /**
5751
   * Returns true if ShouldFlattenAway() applied opacity to children.
5752
   */
5753
  bool OpacityAppliedToChildren() const
5754
0
  {
5755
0
    return mChildOpacityState == ChildOpacityState::Applied;
5756
0
  }
5757
5758
  static bool NeedsActiveLayer(nsDisplayListBuilder* aBuilder,
5759
                               nsIFrame* aFrame);
5760
  void WriteDebugInfo(std::stringstream& aStream) override;
5761
  bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) override;
5762
  bool CreateWebRenderCommands(
5763
    mozilla::wr::DisplayListBuilder& aBuilder,
5764
    mozilla::wr::IpcResourceUpdateQueue& aResources,
5765
    const StackingContextHelper& aSc,
5766
    mozilla::layers::WebRenderLayerManager* aManager,
5767
    nsDisplayListBuilder* aDisplayListBuilder) override;
5768
5769
  float GetOpacity() const { return mOpacity; }
5770
5771
private:
5772
  bool ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder);
5773
5774
  float mOpacity;
5775
  bool mForEventsAndPluginsOnly : 1;
5776
  enum class ChildOpacityState : uint8_t
5777
  {
5778
    // Our child list has changed since the last time ApplyOpacityToChildren was
5779
    // called.
5780
    Unknown,
5781
    // Our children defer opacity handling to us.
5782
    Deferred,
5783
    // Opacity is applied to our children.
5784
    Applied
5785
  };
5786
  bool mNeedsActiveLayer : 1;
5787
#ifndef __GNUC__
5788
  ChildOpacityState mChildOpacityState : 2;
5789
#else
5790
  ChildOpacityState mChildOpacityState;
5791
#endif
5792
5793
  struct
5794
  {
5795
    float mOpacity;
5796
  } mState;
5797
};
5798
5799
class nsDisplayBlendMode : public nsDisplayWrapList
5800
{
5801
public:
5802
  nsDisplayBlendMode(nsDisplayListBuilder* aBuilder,
5803
                     nsIFrame* aFrame,
5804
                     nsDisplayList* aList,
5805
                     uint8_t aBlendMode,
5806
                     const ActiveScrolledRoot* aActiveScrolledRoot,
5807
                     uint32_t aIndex = 0);
5808
  nsDisplayBlendMode(nsDisplayListBuilder* aBuilder,
5809
                     const nsDisplayBlendMode& aOther)
5810
    : nsDisplayWrapList(aBuilder, aOther)
5811
    , mBlendMode(aOther.mBlendMode)
5812
    , mIndex(aOther.mIndex)
5813
0
  {
5814
0
  }
5815
5816
#ifdef NS_BUILD_REFCNT_LOGGING
5817
  ~nsDisplayBlendMode() override { MOZ_COUNT_DTOR(nsDisplayBlendMode); }
5818
#endif
5819
5820
  NS_DISPLAY_DECL_NAME("BlendMode", TYPE_BLEND_MODE)
5821
5822
  nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
5823
0
  {
5824
0
    MOZ_COUNT_CTOR(nsDisplayBlendMode);
5825
0
    return MakeDisplayItem<nsDisplayBlendMode>(aBuilder, *this);
5826
0
  }
5827
5828
  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
5829
                           bool* aSnap) const override;
5830
  already_AddRefed<Layer> BuildLayer(
5831
    nsDisplayListBuilder* aBuilder,
5832
    LayerManager* aManager,
5833
    const ContainerLayerParameters& aContainerParameters) override;
5834
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
5835
                                 const nsDisplayItemGeometry* aGeometry,
5836
                                 nsRegion* aInvalidRegion) const override
5837
0
  {
5838
0
    // We don't need to compute an invalidation region since we have
5839
0
    // LayerTreeInvalidation
5840
0
  }
5841
5842
  uint32_t GetPerFrameKey() const override
5843
0
  {
5844
0
    return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
5845
0
  }
5846
5847
  LayerState GetLayerState(
5848
    nsDisplayListBuilder* aBuilder,
5849
    LayerManager* aManager,
5850
    const ContainerLayerParameters& aParameters) override;
5851
  bool CreateWebRenderCommands(
5852
    mozilla::wr::DisplayListBuilder& aBuilder,
5853
    mozilla::wr::IpcResourceUpdateQueue& aResources,
5854
    const StackingContextHelper& aSc,
5855
    mozilla::layers::WebRenderLayerManager* aManager,
5856
    nsDisplayListBuilder* aDisplayListBuilder) override;
5857
  bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
5858
                         nsRegion* aVisibleRegion) override;
5859
5860
  bool CanMerge(const nsDisplayItem* aItem) const override;
5861
5862
  bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
5863
0
  {
5864
0
    return false;
5865
0
  }
5866
5867
  mozilla::gfx::CompositionOp BlendMode();
5868
5869
protected:
5870
  uint8_t mBlendMode;
5871
  uint32_t mIndex;
5872
};
5873
5874
class nsDisplayTableBlendMode : public nsDisplayBlendMode
5875
{
5876
public:
5877
  nsDisplayTableBlendMode(nsDisplayListBuilder* aBuilder,
5878
                          nsIFrame* aFrame,
5879
                          nsDisplayList* aList,
5880
                          uint8_t aBlendMode,
5881
                          const ActiveScrolledRoot* aActiveScrolledRoot,
5882
                          uint32_t aIndex,
5883
                          nsIFrame* aAncestorFrame)
5884
    : nsDisplayBlendMode(aBuilder,
5885
                         aFrame,
5886
                         aList,
5887
                         aBlendMode,
5888
                         aActiveScrolledRoot,
5889
                         aIndex)
5890
    , mAncestorFrame(aAncestorFrame)
5891
    , mTableType(GetTableTypeFromFrame(aAncestorFrame))
5892
0
  {
5893
0
    if (aBuilder->IsRetainingDisplayList()) {
5894
0
      mAncestorFrame->AddDisplayItem(this);
5895
0
    }
5896
0
  }
5897
5898
  nsDisplayTableBlendMode(nsDisplayListBuilder* aBuilder,
5899
                          const nsDisplayTableBlendMode& aOther)
5900
    : nsDisplayBlendMode(aBuilder, aOther)
5901
    , mAncestorFrame(aOther.mAncestorFrame)
5902
    , mTableType(aOther.mTableType)
5903
0
  {
5904
0
    if (aBuilder->IsRetainingDisplayList()) {
5905
0
      mAncestorFrame->AddDisplayItem(this);
5906
0
    }
5907
0
  }
5908
5909
  ~nsDisplayTableBlendMode() override
5910
0
  {
5911
0
    if (mAncestorFrame) {
5912
0
      mAncestorFrame->RemoveDisplayItem(this);
5913
0
    }
5914
0
  }
5915
5916
  NS_DISPLAY_DECL_NAME("TableBlendMode", TYPE_TABLE_BLEND_MODE)
5917
5918
  nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
5919
0
  {
5920
0
    return MakeDisplayItem<nsDisplayTableBlendMode>(aBuilder, *this);
5921
0
  }
5922
5923
0
  nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
5924
5925
  bool HasDeletedFrame() const override
5926
0
  {
5927
0
    return !mAncestorFrame || nsDisplayBlendMode::HasDeletedFrame();
5928
0
  }
5929
5930
  void RemoveFrame(nsIFrame* aFrame) override
5931
0
  {
5932
0
    if (aFrame == mAncestorFrame) {
5933
0
      mAncestorFrame = nullptr;
5934
0
    }
5935
0
    nsDisplayBlendMode::RemoveFrame(aFrame);
5936
0
  }
5937
5938
  uint32_t GetPerFrameKey() const override
5939
0
  {
5940
0
    return (mIndex << (TYPE_BITS +
5941
0
                       static_cast<uint8_t>(TableTypeBits::COUNT))) |
5942
0
           (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
5943
0
           nsDisplayItem::GetPerFrameKey();
5944
0
  }
5945
5946
protected:
5947
  nsIFrame* mAncestorFrame;
5948
  TableType mTableType;
5949
};
5950
5951
class nsDisplayBlendContainer : public nsDisplayWrapList
5952
{
5953
public:
5954
  static nsDisplayBlendContainer* CreateForMixBlendMode(
5955
    nsDisplayListBuilder* aBuilder,
5956
    nsIFrame* aFrame,
5957
    nsDisplayList* aList,
5958
    const ActiveScrolledRoot* aActiveScrolledRoot);
5959
5960
  static nsDisplayBlendContainer* CreateForBackgroundBlendMode(
5961
    nsDisplayListBuilder* aBuilder,
5962
    nsIFrame* aFrame,
5963
    nsDisplayList* aList,
5964
    const ActiveScrolledRoot* aActiveScrolledRoot);
5965
5966
#ifdef NS_BUILD_REFCNT_LOGGING
5967
  ~nsDisplayBlendContainer() override
5968
  {
5969
    MOZ_COUNT_DTOR(nsDisplayBlendContainer);
5970
  }
5971
#endif
5972
5973
  NS_DISPLAY_DECL_NAME("BlendContainer", TYPE_BLEND_CONTAINER)
5974
5975
  nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
5976
0
  {
5977
0
    MOZ_COUNT_CTOR(nsDisplayBlendContainer);
5978
0
    return MakeDisplayItem<nsDisplayBlendContainer>(aBuilder, *this);
5979
0
  }
5980
5981
  already_AddRefed<Layer> BuildLayer(
5982
    nsDisplayListBuilder* aBuilder,
5983
    LayerManager* aManager,
5984
    const ContainerLayerParameters& aContainerParameters) override;
5985
  LayerState GetLayerState(
5986
    nsDisplayListBuilder* aBuilder,
5987
    LayerManager* aManager,
5988
    const ContainerLayerParameters& aParameters) override;
5989
  bool CreateWebRenderCommands(
5990
    mozilla::wr::DisplayListBuilder& aBuilder,
5991
    mozilla::wr::IpcResourceUpdateQueue& aResources,
5992
    const StackingContextHelper& aSc,
5993
    mozilla::layers::WebRenderLayerManager* aManager,
5994
    nsDisplayListBuilder* aDisplayListBuilder) override;
5995
5996
  bool CanMerge(const nsDisplayItem* aItem) const override
5997
0
  {
5998
0
    // Items for the same content element should be merged into a single
5999
0
    // compositing group.
6000
0
    return HasDifferentFrame(aItem) && HasSameTypeAndClip(aItem) &&
6001
0
           HasSameContent(aItem) &&
6002
0
           mIsForBackground ==
6003
0
             static_cast<const nsDisplayBlendContainer*>(aItem)
6004
0
               ->mIsForBackground;
6005
0
  }
6006
6007
  bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
6008
0
  {
6009
0
    return false;
6010
0
  }
6011
6012
  uint32_t GetPerFrameKey() const override
6013
0
  {
6014
0
    return (mIsForBackground ? 1 << TYPE_BITS : 0) |
6015
0
           nsDisplayItem::GetPerFrameKey();
6016
0
  }
6017
6018
protected:
6019
  nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder,
6020
                          nsIFrame* aFrame,
6021
                          nsDisplayList* aList,
6022
                          const ActiveScrolledRoot* aActiveScrolledRoot,
6023
                          bool aIsForBackground);
6024
  nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder,
6025
                          const nsDisplayBlendContainer& aOther)
6026
    : nsDisplayWrapList(aBuilder, aOther)
6027
    , mIsForBackground(aOther.mIsForBackground)
6028
0
  {
6029
0
  }
6030
6031
  // Used to distinguish containers created at building stacking
6032
  // context or appending background.
6033
  bool mIsForBackground;
6034
};
6035
6036
class nsDisplayTableBlendContainer : public nsDisplayBlendContainer
6037
{
6038
public:
6039
  static nsDisplayTableBlendContainer* CreateForBackgroundBlendMode(
6040
    nsDisplayListBuilder* aBuilder,
6041
    nsIFrame* aFrame,
6042
    nsDisplayList* aList,
6043
    const ActiveScrolledRoot* aActiveScrolledRoot,
6044
    nsIFrame* aAncestorFrame);
6045
6046
  NS_DISPLAY_DECL_NAME("TableBlendContainer", TYPE_TABLE_BLEND_CONTAINER)
6047
6048
  nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
6049
0
  {
6050
0
    return MakeDisplayItem<nsDisplayTableBlendContainer>(aBuilder, *this);
6051
0
  }
6052
6053
0
  nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
6054
6055
  bool HasDeletedFrame() const override
6056
0
  {
6057
0
    return !mAncestorFrame || nsDisplayBlendContainer::HasDeletedFrame();
6058
0
  }
6059
6060
  void RemoveFrame(nsIFrame* aFrame) override
6061
0
  {
6062
0
    if (aFrame == mAncestorFrame) {
6063
0
      mAncestorFrame = nullptr;
6064
0
    }
6065
0
    nsDisplayBlendContainer::RemoveFrame(aFrame);
6066
0
  }
6067
6068
  uint32_t GetPerFrameKey() const override
6069
0
  {
6070
0
    return (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
6071
0
           nsDisplayItem::GetPerFrameKey();
6072
0
  }
6073
6074
protected:
6075
  nsDisplayTableBlendContainer(nsDisplayListBuilder* aBuilder,
6076
                               nsIFrame* aFrame,
6077
                               nsDisplayList* aList,
6078
                               const ActiveScrolledRoot* aActiveScrolledRoot,
6079
                               bool aIsForBackground,
6080
                               nsIFrame* aAncestorFrame)
6081
    : nsDisplayBlendContainer(aBuilder,
6082
                              aFrame,
6083
                              aList,
6084
                              aActiveScrolledRoot,
6085
                              aIsForBackground)
6086
    , mAncestorFrame(aAncestorFrame)
6087
    , mTableType(GetTableTypeFromFrame(aAncestorFrame))
6088
0
  {
6089
0
    if (aBuilder->IsRetainingDisplayList()) {
6090
0
      mAncestorFrame->AddDisplayItem(this);
6091
0
    }
6092
0
  }
6093
6094
  nsDisplayTableBlendContainer(nsDisplayListBuilder* aBuilder,
6095
                               const nsDisplayTableBlendContainer& aOther)
6096
    : nsDisplayBlendContainer(aBuilder, aOther)
6097
    , mAncestorFrame(aOther.mAncestorFrame)
6098
    , mTableType(aOther.mTableType)
6099
0
  {
6100
0
    if (aBuilder->IsRetainingDisplayList()) {
6101
0
      mAncestorFrame->AddDisplayItem(this);
6102
0
    }
6103
0
  }
6104
6105
  ~nsDisplayTableBlendContainer() override
6106
0
  {
6107
0
    if (mAncestorFrame) {
6108
0
      mAncestorFrame->RemoveDisplayItem(this);
6109
0
    }
6110
0
  }
6111
6112
  nsIFrame* mAncestorFrame;
6113
  TableType mTableType;
6114
};
6115
6116
/**
6117
 * nsDisplayOwnLayer constructor flags. If we nest this class inside
6118
 * nsDisplayOwnLayer then we can't forward-declare it up at the top of this
6119
 * file and that makes it hard to use in all the places that we need to use it.
6120
 */
6121
enum class nsDisplayOwnLayerFlags
6122
{
6123
  eNone = 0,
6124
  eGenerateSubdocInvalidations = 1 << 0,
6125
  eGenerateScrollableLayer = 1 << 1,
6126
};
6127
6128
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsDisplayOwnLayerFlags)
6129
6130
/**
6131
 * A display item that has no purpose but to ensure its contents get
6132
 * their own layer.
6133
 */
6134
class nsDisplayOwnLayer : public nsDisplayWrapList
6135
{
6136
public:
6137
  typedef mozilla::layers::ScrollbarData ScrollbarData;
6138
6139
  /**
6140
   * @param aFlags eGenerateSubdocInvalidations :
6141
   * Add UserData to the created ContainerLayer, so that invalidations
6142
   * for this layer are send to our nsPresContext.
6143
   * eGenerateScrollableLayer : only valid on nsDisplaySubDocument (and
6144
   * subclasses), indicates this layer is to be a scrollable layer, so call
6145
   * ComputeFrameMetrics, etc.
6146
   * @param aScrollTarget when eVerticalScrollbar or eHorizontalScrollbar
6147
   * is set in the flags, this parameter should be the ViewID of the
6148
   * scrollable content this scrollbar is for.
6149
   */
6150
  nsDisplayOwnLayer(
6151
    nsDisplayListBuilder* aBuilder,
6152
    nsIFrame* aFrame,
6153
    nsDisplayList* aList,
6154
    const ActiveScrolledRoot* aActiveScrolledRoot,
6155
    nsDisplayOwnLayerFlags aFlags = nsDisplayOwnLayerFlags::eNone,
6156
    const ScrollbarData& aScrollbarData = ScrollbarData{},
6157
    bool aForceActive = true,
6158
    bool aClearClipChain = false);
6159
6160
  nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder,
6161
                    const nsDisplayOwnLayer& aOther)
6162
    : nsDisplayWrapList(aBuilder, aOther)
6163
    , mFlags(aOther.mFlags)
6164
    , mScrollbarData(aOther.mScrollbarData)
6165
    , mForceActive(aOther.mForceActive)
6166
    , mWrAnimationId(aOther.mWrAnimationId)
6167
0
  {
6168
0
    MOZ_COUNT_CTOR(nsDisplayOwnLayer);
6169
0
  }
6170
6171
#ifdef NS_BUILD_REFCNT_LOGGING
6172
  ~nsDisplayOwnLayer() override { MOZ_COUNT_DTOR(nsDisplayOwnLayer); }
6173
#endif
6174
6175
  NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
6176
6177
  bool ShouldBuildLayerEvenIfInvisible(
6178
    nsDisplayListBuilder* aBuilder) const override;
6179
  already_AddRefed<Layer> BuildLayer(
6180
    nsDisplayListBuilder* aBuilder,
6181
    LayerManager* aManager,
6182
    const ContainerLayerParameters& aContainerParameters) override;
6183
  bool CreateWebRenderCommands(
6184
    mozilla::wr::DisplayListBuilder& aBuilder,
6185
    mozilla::wr::IpcResourceUpdateQueue& aResources,
6186
    const StackingContextHelper& aSc,
6187
    mozilla::layers::WebRenderLayerManager* aManager,
6188
    nsDisplayListBuilder* aDisplayListBuilder) override;
6189
  bool UpdateScrollData(
6190
    mozilla::layers::WebRenderScrollData* aData,
6191
    mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
6192
  LayerState GetLayerState(
6193
    nsDisplayListBuilder* aBuilder,
6194
    LayerManager* aManager,
6195
    const ContainerLayerParameters& aParameters) override;
6196
6197
  bool CanMerge(const nsDisplayItem* aItem) const override
6198
0
  {
6199
0
    // Don't allow merging, each sublist must have its own layer
6200
0
    return false;
6201
0
  }
6202
6203
  bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
6204
0
  {
6205
0
    return false;
6206
0
  }
6207
6208
  void WriteDebugInfo(std::stringstream& aStream) override;
6209
  nsDisplayOwnLayerFlags GetFlags() { return mFlags; }
6210
  bool IsScrollThumbLayer() const;
6211
  bool IsScrollbarContainer() const;
6212
6213
protected:
6214
  nsDisplayOwnLayerFlags mFlags;
6215
6216
  /**
6217
   * If this nsDisplayOwnLayer represents a scroll thumb layer or a
6218
   * scrollbar container layer, mScrollbarData stores information
6219
   * about the scrollbar. Otherwise, mScrollbarData will be
6220
   * default-constructed (in particular with mDirection == Nothing())
6221
   * and can be ignored.
6222
   */
6223
  ScrollbarData mScrollbarData;
6224
  bool mForceActive;
6225
  uint64_t mWrAnimationId;
6226
};
6227
6228
/**
6229
 * A display item for subdocuments. This is more or less the same as
6230
 * nsDisplayOwnLayer, except that it always populates the FrameMetrics instance
6231
 * on the ContainerLayer it builds.
6232
 */
6233
class nsDisplaySubDocument : public nsDisplayOwnLayer
6234
{
6235
public:
6236
  nsDisplaySubDocument(nsDisplayListBuilder* aBuilder,
6237
                       nsIFrame* aFrame,
6238
                       nsSubDocumentFrame* aSubDocFrame,
6239
                       nsDisplayList* aList,
6240
                       nsDisplayOwnLayerFlags aFlags);
6241
  ~nsDisplaySubDocument() override;
6242
6243
  NS_DISPLAY_DECL_NAME("SubDocument", TYPE_SUBDOCUMENT)
6244
6245
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
6246
6247
0
  virtual nsSubDocumentFrame* SubDocumentFrame() { return mSubDocFrame; }
6248
6249
  bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
6250
                         nsRegion* aVisibleRegion) override;
6251
  bool ShouldBuildLayerEvenIfInvisible(
6252
    nsDisplayListBuilder* aBuilder) const override;
6253
6254
  bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
6255
0
  {
6256
0
    return mShouldFlatten;
6257
0
  }
6258
6259
  void SetShouldFlattenAway(bool aShouldFlatten)
6260
0
  {
6261
0
    mShouldFlatten = aShouldFlatten;
6262
0
  }
6263
6264
  LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
6265
                           LayerManager* aManager,
6266
                           const ContainerLayerParameters& aParameters) override
6267
0
  {
6268
0
    if (mShouldFlatten) {
6269
0
      return mozilla::LAYER_NONE;
6270
0
    }
6271
0
    return nsDisplayOwnLayer::GetLayerState(aBuilder, aManager, aParameters);
6272
0
  }
6273
6274
  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
6275
                           bool* aSnap) const override;
6276
6277
  mozilla::UniquePtr<ScrollMetadata> ComputeScrollMetadata(
6278
    LayerManager* aLayerManager,
6279
    const ContainerLayerParameters& aContainerParameters);
6280
6281
  nsIFrame* FrameForInvalidation() const override;
6282
  bool HasDeletedFrame() const override;
6283
  void RemoveFrame(nsIFrame* aFrame) override;
6284
6285
  void Disown();
6286
6287
protected:
6288
  ViewID mScrollParentId;
6289
  bool mForceDispatchToContentRegion;
6290
  bool mShouldFlatten;
6291
  nsSubDocumentFrame* mSubDocFrame;
6292
};
6293
6294
/**
6295
 * A display item for subdocuments to capture the resolution from the presShell
6296
 * and ensure that it gets applied to all the right elements. This item creates
6297
 * a container layer.
6298
 */
6299
class nsDisplayResolution : public nsDisplaySubDocument
6300
{
6301
public:
6302
  nsDisplayResolution(nsDisplayListBuilder* aBuilder,
6303
                      nsIFrame* aFrame,
6304
                      nsSubDocumentFrame* aSubDocFrame,
6305
                      nsDisplayList* aList,
6306
                      nsDisplayOwnLayerFlags aFlags);
6307
#ifdef NS_BUILD_REFCNT_LOGGING
6308
  ~nsDisplayResolution() override { MOZ_COUNT_DTOR(nsDisplayResolution); }
6309
#endif
6310
6311
  NS_DISPLAY_DECL_NAME("Resolution", TYPE_RESOLUTION)
6312
6313
  void HitTest(nsDisplayListBuilder* aBuilder,
6314
               const nsRect& aRect,
6315
               HitTestState* aState,
6316
               nsTArray<nsIFrame*>* aOutFrames) override;
6317
  already_AddRefed<Layer> BuildLayer(
6318
    nsDisplayListBuilder* aBuilder,
6319
    LayerManager* aManager,
6320
    const ContainerLayerParameters& aContainerParameters) override;
6321
};
6322
6323
/**
6324
 * A display item used to represent sticky position elements. The contents
6325
 * gets its own layer and creates a stacking context, and the layer will have
6326
 * position-related metadata set on it.
6327
 */
6328
class nsDisplayStickyPosition : public nsDisplayOwnLayer
6329
{
6330
public:
6331
  nsDisplayStickyPosition(nsDisplayListBuilder* aBuilder,
6332
                          nsIFrame* aFrame,
6333
                          nsDisplayList* aList,
6334
                          const ActiveScrolledRoot* aActiveScrolledRoot,
6335
                          const ActiveScrolledRoot* aContainerASR);
6336
  nsDisplayStickyPosition(nsDisplayListBuilder* aBuilder,
6337
                          const nsDisplayStickyPosition& aOther)
6338
    : nsDisplayOwnLayer(aBuilder, aOther)
6339
    , mContainerASR(aOther.mContainerASR)
6340
0
  {
6341
0
  }
6342
6343
#ifdef NS_BUILD_REFCNT_LOGGING
6344
  ~nsDisplayStickyPosition() override
6345
  {
6346
    MOZ_COUNT_DTOR(nsDisplayStickyPosition);
6347
  }
6348
#endif
6349
6350
  void SetClipChain(const DisplayItemClipChain* aClipChain,
6351
                    bool aStore) override;
6352
  nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
6353
0
  {
6354
0
    MOZ_COUNT_CTOR(nsDisplayStickyPosition);
6355
0
    return MakeDisplayItem<nsDisplayStickyPosition>(aBuilder, *this);
6356
0
  }
6357
6358
  already_AddRefed<Layer> BuildLayer(
6359
    nsDisplayListBuilder* aBuilder,
6360
    LayerManager* aManager,
6361
    const ContainerLayerParameters& aContainerParameters) override;
6362
  NS_DISPLAY_DECL_NAME("StickyPosition", TYPE_STICKY_POSITION)
6363
  LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
6364
                           LayerManager* aManager,
6365
                           const ContainerLayerParameters& aParameters) override
6366
0
  {
6367
0
    return mozilla::LAYER_ACTIVE;
6368
0
  }
6369
6370
  bool CreateWebRenderCommands(
6371
    mozilla::wr::DisplayListBuilder& aBuilder,
6372
    mozilla::wr::IpcResourceUpdateQueue& aResources,
6373
    const StackingContextHelper& aSc,
6374
    mozilla::layers::WebRenderLayerManager* aManager,
6375
    nsDisplayListBuilder* aDisplayListBuilder) override;
6376
6377
  const ActiveScrolledRoot* GetContainerASR() const { return mContainerASR; }
6378
6379
private:
6380
  // This stores the ASR that this sticky container item would have assuming it
6381
  // has no fixed descendants. This may be the same as the ASR returned by
6382
  // GetActiveScrolledRoot(), or it may be a descendant of that.
6383
  RefPtr<const ActiveScrolledRoot> mContainerASR;
6384
};
6385
6386
class nsDisplayFixedPosition : public nsDisplayOwnLayer
6387
{
6388
public:
6389
  nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder,
6390
                         nsIFrame* aFrame,
6391
                         nsDisplayList* aList,
6392
                         const ActiveScrolledRoot* aActiveScrolledRoot,
6393
                         const ActiveScrolledRoot* aContainerASR);
6394
  nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder,
6395
                         const nsDisplayFixedPosition& aOther)
6396
    : nsDisplayOwnLayer(aBuilder, aOther)
6397
    , mAnimatedGeometryRootForScrollMetadata(
6398
        aOther.mAnimatedGeometryRootForScrollMetadata)
6399
    , mIndex(aOther.mIndex)
6400
    , mIsFixedBackground(aOther.mIsFixedBackground)
6401
    , mContainerASR(aOther.mContainerASR)
6402
0
  {
6403
0
    MOZ_COUNT_CTOR(nsDisplayFixedPosition);
6404
0
  }
6405
6406
  static nsDisplayFixedPosition* CreateForFixedBackground(
6407
    nsDisplayListBuilder* aBuilder,
6408
    nsIFrame* aFrame,
6409
    nsDisplayBackgroundImage* aImage,
6410
    uint32_t aIndex);
6411
6412
#ifdef NS_BUILD_REFCNT_LOGGING
6413
  ~nsDisplayFixedPosition() override { MOZ_COUNT_DTOR(nsDisplayFixedPosition); }
6414
#endif
6415
6416
  NS_DISPLAY_DECL_NAME("FixedPosition", TYPE_FIXED_POSITION)
6417
6418
  nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
6419
0
  {
6420
0
    return MakeDisplayItem<nsDisplayFixedPosition>(aBuilder, *this);
6421
0
  }
6422
6423
  already_AddRefed<Layer> BuildLayer(
6424
    nsDisplayListBuilder* aBuilder,
6425
    LayerManager* aManager,
6426
    const ContainerLayerParameters& aContainerParameters) override;
6427
6428
  LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
6429
                           LayerManager* aManager,
6430
                           const ContainerLayerParameters& aParameters) override
6431
0
  {
6432
0
    return mozilla::LAYER_ACTIVE_FORCE;
6433
0
  }
6434
6435
  bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) const override
6436
0
  {
6437
0
    return mIsFixedBackground;
6438
0
  }
6439
6440
  uint32_t GetPerFrameKey() const override
6441
0
  {
6442
0
    return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
6443
0
  }
6444
6445
  AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const override
6446
0
  {
6447
0
    return mAnimatedGeometryRootForScrollMetadata;
6448
0
  }
6449
6450
  bool CreateWebRenderCommands(
6451
    mozilla::wr::DisplayListBuilder& aBuilder,
6452
    mozilla::wr::IpcResourceUpdateQueue& aResources,
6453
    const StackingContextHelper& aSc,
6454
    mozilla::layers::WebRenderLayerManager* aManager,
6455
    nsDisplayListBuilder* aDisplayListBuilder) override;
6456
  bool UpdateScrollData(
6457
    mozilla::layers::WebRenderScrollData* aData,
6458
    mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
6459
  void WriteDebugInfo(std::stringstream& aStream) override;
6460
6461
protected:
6462
  // For background-attachment:fixed
6463
  nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder,
6464
                         nsIFrame* aFrame,
6465
                         nsDisplayList* aList,
6466
                         uint32_t aIndex);
6467
  void Init(nsDisplayListBuilder* aBuilder);
6468
  ViewID GetScrollTargetId();
6469
6470
  RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRootForScrollMetadata;
6471
  uint32_t mIndex;
6472
  bool mIsFixedBackground;
6473
  RefPtr<const ActiveScrolledRoot> mContainerASR;
6474
};
6475
6476
class nsDisplayTableFixedPosition : public nsDisplayFixedPosition
6477
{
6478
public:
6479
  static nsDisplayTableFixedPosition* CreateForFixedBackground(
6480
    nsDisplayListBuilder* aBuilder,
6481
    nsIFrame* aFrame,
6482
    nsDisplayBackgroundImage* aImage,
6483
    uint32_t aIndex,
6484
    nsIFrame* aAncestorFrame);
6485
6486
  NS_DISPLAY_DECL_NAME("TableFixedPosition", TYPE_TABLE_FIXED_POSITION)
6487
6488
  nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
6489
0
  {
6490
0
    return MakeDisplayItem<nsDisplayTableFixedPosition>(aBuilder, *this);
6491
0
  }
6492
6493
0
  nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
6494
6495
  bool HasDeletedFrame() const override
6496
0
  {
6497
0
    return !mAncestorFrame || nsDisplayFixedPosition::HasDeletedFrame();
6498
0
  }
6499
6500
  void RemoveFrame(nsIFrame* aFrame) override
6501
0
  {
6502
0
    if (aFrame == mAncestorFrame) {
6503
0
      mAncestorFrame = nullptr;
6504
0
    }
6505
0
    nsDisplayFixedPosition::RemoveFrame(aFrame);
6506
0
  }
6507
6508
  uint32_t GetPerFrameKey() const override
6509
0
  {
6510
0
    return (mIndex << (TYPE_BITS +
6511
0
                       static_cast<uint8_t>(TableTypeBits::COUNT))) |
6512
0
           (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
6513
0
           nsDisplayItem::GetPerFrameKey();
6514
0
  }
6515
6516
protected:
6517
  nsDisplayTableFixedPosition(nsDisplayListBuilder* aBuilder,
6518
                              nsIFrame* aFrame,
6519
                              nsDisplayList* aList,
6520
                              uint32_t aIndex,
6521
                              nsIFrame* aAncestorFrame);
6522
6523
  nsDisplayTableFixedPosition(nsDisplayListBuilder* aBuilder,
6524
                              const nsDisplayTableFixedPosition& aOther)
6525
    : nsDisplayFixedPosition(aBuilder, aOther)
6526
    , mAncestorFrame(aOther.mAncestorFrame)
6527
    , mTableType(aOther.mTableType)
6528
0
  {
6529
0
    if (aBuilder->IsRetainingDisplayList()) {
6530
0
      mAncestorFrame->AddDisplayItem(this);
6531
0
    }
6532
0
  }
6533
6534
  ~nsDisplayTableFixedPosition() override
6535
0
  {
6536
0
    if (mAncestorFrame) {
6537
0
      mAncestorFrame->RemoveDisplayItem(this);
6538
0
    }
6539
0
  }
6540
6541
  nsIFrame* mAncestorFrame;
6542
  TableType mTableType;
6543
};
6544
6545
/**
6546
 * This creates an empty scrollable layer. It has no child layers.
6547
 * It is used to record the existence of a scrollable frame in the layer
6548
 * tree.
6549
 */
6550
class nsDisplayScrollInfoLayer : public nsDisplayWrapList
6551
{
6552
public:
6553
  nsDisplayScrollInfoLayer(nsDisplayListBuilder* aBuilder,
6554
                           nsIFrame* aScrolledFrame,
6555
                           nsIFrame* aScrollFrame);
6556
6557
#ifdef NS_BUILD_REFCNT_LOGGING
6558
  ~nsDisplayScrollInfoLayer() override
6559
  {
6560
    MOZ_COUNT_DTOR(nsDisplayScrollInfoLayer);
6561
  }
6562
#endif
6563
6564
  NS_DISPLAY_DECL_NAME("ScrollInfoLayer", TYPE_SCROLL_INFO_LAYER)
6565
6566
  already_AddRefed<Layer> BuildLayer(
6567
    nsDisplayListBuilder* aBuilder,
6568
    LayerManager* aManager,
6569
    const ContainerLayerParameters& aContainerParameters) override;
6570
6571
  bool ShouldBuildLayerEvenIfInvisible(
6572
    nsDisplayListBuilder* aBuilder) const override
6573
0
  {
6574
0
    return true;
6575
0
  }
6576
6577
  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
6578
                           bool* aSnap) const override
6579
0
  {
6580
0
    *aSnap = false;
6581
0
    return nsRegion();
6582
0
  }
6583
6584
  LayerState GetLayerState(
6585
    nsDisplayListBuilder* aBuilder,
6586
    LayerManager* aManager,
6587
    const ContainerLayerParameters& aParameters) override;
6588
6589
  bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
6590
0
  {
6591
0
    return false;
6592
0
  }
6593
6594
  void WriteDebugInfo(std::stringstream& aStream) override;
6595
  mozilla::UniquePtr<ScrollMetadata> ComputeScrollMetadata(
6596
    LayerManager* aLayerManager,
6597
    const ContainerLayerParameters& aContainerParameters);
6598
  bool UpdateScrollData(
6599
    mozilla::layers::WebRenderScrollData* aData,
6600
    mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
6601
6602
protected:
6603
  nsIFrame* mScrollFrame;
6604
  nsIFrame* mScrolledFrame;
6605
  ViewID mScrollParentId;
6606
};
6607
6608
/**
6609
 * nsDisplayZoom is used for subdocuments that have a different full zoom than
6610
 * their parent documents. This item creates a container layer.
6611
 */
6612
class nsDisplayZoom : public nsDisplaySubDocument
6613
{
6614
public:
6615
  /**
6616
   * @param aFrame is the root frame of the subdocument.
6617
   * @param aList contains the display items for the subdocument.
6618
   * @param aAPD is the app units per dev pixel ratio of the subdocument.
6619
   * @param aParentAPD is the app units per dev pixel ratio of the parent
6620
   * document.
6621
   * @param aFlags eGenerateSubdocInvalidations :
6622
   * Add UserData to the created ContainerLayer, so that invalidations
6623
   * for this layer are send to our nsPresContext.
6624
   */
6625
  nsDisplayZoom(nsDisplayListBuilder* aBuilder,
6626
                nsIFrame* aFrame,
6627
                nsSubDocumentFrame* aSubDocFrame,
6628
                nsDisplayList* aList,
6629
                int32_t aAPD,
6630
                int32_t aParentAPD,
6631
                nsDisplayOwnLayerFlags aFlags = nsDisplayOwnLayerFlags::eNone);
6632
6633
#ifdef NS_BUILD_REFCNT_LOGGING
6634
  ~nsDisplayZoom() override { MOZ_COUNT_DTOR(nsDisplayZoom); }
6635
#endif
6636
6637
  NS_DISPLAY_DECL_NAME("Zoom", TYPE_ZOOM)
6638
6639
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
6640
  void HitTest(nsDisplayListBuilder* aBuilder,
6641
               const nsRect& aRect,
6642
               HitTestState* aState,
6643
               nsTArray<nsIFrame*>* aOutFrames) override;
6644
  bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
6645
                         nsRegion* aVisibleRegion) override;
6646
  LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
6647
                           LayerManager* aManager,
6648
                           const ContainerLayerParameters& aParameters) override
6649
0
  {
6650
0
    return mozilla::LAYER_ACTIVE;
6651
0
  }
6652
6653
  // Get the app units per dev pixel ratio of the child document.
6654
  int32_t GetChildAppUnitsPerDevPixel() { return mAPD; }
6655
  // Get the app units per dev pixel ratio of the parent document.
6656
  int32_t GetParentAppUnitsPerDevPixel() { return mParentAPD; }
6657
6658
private:
6659
  int32_t mAPD, mParentAPD;
6660
};
6661
6662
class nsDisplaySVGEffects : public nsDisplayWrapList
6663
{
6664
public:
6665
  nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder,
6666
                      nsIFrame* aFrame,
6667
                      nsDisplayList* aList,
6668
                      bool aHandleOpacity,
6669
                      const ActiveScrolledRoot* aActiveScrolledRoot,
6670
                      bool aClearClipChain = false);
6671
  nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder,
6672
                      nsIFrame* aFrame,
6673
                      nsDisplayList* aList,
6674
                      bool aHandleOpacity);
6675
6676
  nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder,
6677
                      const nsDisplaySVGEffects& aOther)
6678
    : nsDisplayWrapList(aBuilder, aOther)
6679
    , mEffectsBounds(aOther.mEffectsBounds)
6680
    , mHandleOpacity(aOther.mHandleOpacity)
6681
0
  {
6682
0
    MOZ_COUNT_CTOR(nsDisplaySVGEffects);
6683
0
  }
6684
6685
#ifdef NS_BUILD_REFCNT_LOGGING
6686
  ~nsDisplaySVGEffects() override { MOZ_COUNT_DTOR(nsDisplaySVGEffects); }
6687
#endif
6688
6689
  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
6690
                           bool* aSnap) const override;
6691
  void HitTest(nsDisplayListBuilder* aBuilder,
6692
               const nsRect& aRect,
6693
               HitTestState* aState,
6694
               nsTArray<nsIFrame*>* aOutFrames) override;
6695
6696
  bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
6697
0
  {
6698
0
    return false;
6699
0
  }
6700
6701
0
  bool ShouldHandleOpacity() { return mHandleOpacity; }
6702
6703
  gfxRect BBoxInUserSpace() const;
6704
  gfxPoint UserSpaceOffset() const;
6705
6706
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
6707
                                 const nsDisplayItemGeometry* aGeometry,
6708
                                 nsRegion* aInvalidRegion) const override;
6709
6710
protected:
6711
  bool ValidateSVGFrame();
6712
6713
  // relative to mFrame
6714
  nsRect mEffectsBounds;
6715
  // True if we need to handle css opacity in this display item.
6716
  bool mHandleOpacity;
6717
};
6718
6719
/**
6720
 * A display item to paint a stacking context with mask and clip effects
6721
 * set by the stacking context root frame's style.
6722
 */
6723
class nsDisplayMask : public nsDisplaySVGEffects
6724
{
6725
public:
6726
  typedef mozilla::layers::ImageLayer ImageLayer;
6727
6728
  nsDisplayMask(nsDisplayListBuilder* aBuilder,
6729
                nsIFrame* aFrame,
6730
                nsDisplayList* aList,
6731
                bool aHandleOpacity,
6732
                const ActiveScrolledRoot* aActiveScrolledRoot);
6733
  nsDisplayMask(nsDisplayListBuilder* aBuilder, const nsDisplayMask& aOther)
6734
    : nsDisplaySVGEffects(aBuilder, aOther)
6735
    , mDestRects(aOther.mDestRects)
6736
0
  {
6737
0
  }
6738
6739
#ifdef NS_BUILD_REFCNT_LOGGING
6740
  ~nsDisplayMask() override { MOZ_COUNT_DTOR(nsDisplayMask); }
6741
#endif
6742
6743
  NS_DISPLAY_DECL_NAME("Mask", TYPE_MASK)
6744
6745
  nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
6746
0
  {
6747
0
    MOZ_COUNT_CTOR(nsDisplayMask);
6748
0
    return MakeDisplayItem<nsDisplayMask>(aBuilder, *this);
6749
0
  }
6750
6751
  bool CanMerge(const nsDisplayItem* aItem) const override;
6752
6753
  void Merge(const nsDisplayItem* aItem) override
6754
0
  {
6755
0
    nsDisplayWrapList::Merge(aItem);
6756
0
6757
0
    const nsDisplayMask* other = static_cast<const nsDisplayMask*>(aItem);
6758
0
    mEffectsBounds.UnionRect(mEffectsBounds,
6759
0
                             other->mEffectsBounds +
6760
0
                               other->mFrame->GetOffsetTo(mFrame));
6761
0
  }
6762
6763
  already_AddRefed<Layer> BuildLayer(
6764
    nsDisplayListBuilder* aBuilder,
6765
    LayerManager* aManager,
6766
    const ContainerLayerParameters& aContainerParameters) override;
6767
  LayerState GetLayerState(
6768
    nsDisplayListBuilder* aBuilder,
6769
    LayerManager* aManager,
6770
    const ContainerLayerParameters& aParameters) override;
6771
  bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
6772
                         nsRegion* aVisibleRegion) override;
6773
6774
  nsDisplayItemGeometry* AllocateGeometry(
6775
    nsDisplayListBuilder* aBuilder) override
6776
0
  {
6777
0
    return new nsDisplayMaskGeometry(this, aBuilder);
6778
0
  }
6779
6780
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
6781
                                 const nsDisplayItemGeometry* aGeometry,
6782
                                 nsRegion* aInvalidRegion) const override;
6783
#ifdef MOZ_DUMP_PAINTING
6784
  void PrintEffects(nsACString& aTo);
6785
#endif
6786
6787
  bool IsValidMask();
6788
6789
  void PaintAsLayer(nsDisplayListBuilder* aBuilder,
6790
                    gfxContext* aCtx,
6791
                    LayerManager* aManager);
6792
6793
  void PaintWithContentsPaintCallback(nsDisplayListBuilder* aBuilder,
6794
                                      gfxContext* aCtx,
6795
                                      const std::function<void()>& aPaintChildren);
6796
6797
6798
  /*
6799
   * Paint mask onto aMaskContext in mFrame's coordinate space and
6800
   * return whether the mask layer was painted successfully.
6801
   */
6802
  bool PaintMask(nsDisplayListBuilder* aBuilder,
6803
                 gfxContext* aMaskContext,
6804
                 bool* aMaskPainted = nullptr);
6805
6806
0
  const nsTArray<nsRect>& GetDestRects() { return mDestRects; }
6807
6808
  bool CreateWebRenderCommands(
6809
    mozilla::wr::DisplayListBuilder& aBuilder,
6810
    mozilla::wr::IpcResourceUpdateQueue& aResources,
6811
    const StackingContextHelper& aSc,
6812
    mozilla::layers::WebRenderLayerManager* aManager,
6813
    nsDisplayListBuilder* aDisplayListBuilder) override;
6814
6815
  mozilla::Maybe<nsRect> GetClipWithRespectToASR(
6816
    nsDisplayListBuilder* aBuilder,
6817
    const ActiveScrolledRoot* aASR) const override;
6818
6819
private:
6820
  // According to mask property and the capability of aManager, determine
6821
  // whether we can paint the mask onto a dedicate mask layer.
6822
  bool CanPaintOnMaskLayer(LayerManager* aManager);
6823
6824
  nsTArray<nsRect> mDestRects;
6825
};
6826
6827
/**
6828
 * A display item to paint a stacking context with filter effects set by the
6829
 * stacking context root frame's style.
6830
 */
6831
class nsDisplayFilter : public nsDisplaySVGEffects
6832
{
6833
public:
6834
  nsDisplayFilter(nsDisplayListBuilder* aBuilder,
6835
                  nsIFrame* aFrame,
6836
                  nsDisplayList* aList,
6837
                  bool aHandleOpacity);
6838
6839
  nsDisplayFilter(nsDisplayListBuilder* aBuilder, const nsDisplayFilter& aOther)
6840
    : nsDisplaySVGEffects(aBuilder, aOther)
6841
    , mEffectsBounds(aOther.mEffectsBounds)
6842
0
  {
6843
0
  }
6844
6845
#ifdef NS_BUILD_REFCNT_LOGGING
6846
  ~nsDisplayFilter() override { MOZ_COUNT_DTOR(nsDisplayFilter); }
6847
#endif
6848
6849
  NS_DISPLAY_DECL_NAME("Filter", TYPE_FILTER)
6850
6851
  nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
6852
0
  {
6853
0
    MOZ_COUNT_CTOR(nsDisplayFilter);
6854
0
    return MakeDisplayItem<nsDisplayFilter>(aBuilder, *this);
6855
0
  }
6856
6857
  bool CanMerge(const nsDisplayItem* aItem) const override
6858
0
  {
6859
0
    // Items for the same content element should be merged into a single
6860
0
    // compositing group.
6861
0
    return HasDifferentFrame(aItem) && HasSameTypeAndClip(aItem) &&
6862
0
           HasSameContent(aItem);
6863
0
  }
6864
6865
  void Merge(const nsDisplayItem* aItem) override
6866
0
  {
6867
0
    nsDisplayWrapList::Merge(aItem);
6868
0
6869
0
    const nsDisplayFilter* other = static_cast<const nsDisplayFilter*>(aItem);
6870
0
    mEffectsBounds.UnionRect(mEffectsBounds,
6871
0
                             other->mEffectsBounds +
6872
0
                               other->mFrame->GetOffsetTo(mFrame));
6873
0
  }
6874
6875
  already_AddRefed<Layer> BuildLayer(
6876
    nsDisplayListBuilder* aBuilder,
6877
    LayerManager* aManager,
6878
    const ContainerLayerParameters& aContainerParameters) override;
6879
  LayerState GetLayerState(
6880
    nsDisplayListBuilder* aBuilder,
6881
    LayerManager* aManager,
6882
    const ContainerLayerParameters& aParameters) override;
6883
6884
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override
6885
0
  {
6886
0
    *aSnap = false;
6887
0
    return mEffectsBounds + ToReferenceFrame();
6888
0
  }
6889
6890
  bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
6891
                         nsRegion* aVisibleRegion) override;
6892
6893
  nsDisplayItemGeometry* AllocateGeometry(
6894
    nsDisplayListBuilder* aBuilder) override
6895
0
  {
6896
0
    return new nsDisplayFilterGeometry(this, aBuilder);
6897
0
  }
6898
6899
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
6900
                                 const nsDisplayItemGeometry* aGeometry,
6901
                                 nsRegion* aInvalidRegion) const override;
6902
#ifdef MOZ_DUMP_PAINTING
6903
  void PrintEffects(nsACString& aTo);
6904
#endif
6905
6906
  void PaintAsLayer(nsDisplayListBuilder* aBuilder,
6907
                    gfxContext* aCtx,
6908
                    LayerManager* aManager);
6909
6910
  bool CreateWebRenderCommands(
6911
    mozilla::wr::DisplayListBuilder& aBuilder,
6912
    mozilla::wr::IpcResourceUpdateQueue& aResources,
6913
    const StackingContextHelper& aSc,
6914
    mozilla::layers::WebRenderLayerManager* aManager,
6915
    nsDisplayListBuilder* aDisplayListBuilder) override;
6916
6917
private:
6918
  // relative to mFrame
6919
  nsRect mEffectsBounds;
6920
};
6921
6922
/* A display item that applies a transformation to all of its descendant
6923
 * elements.  This wrapper should only be used if there is a transform applied
6924
 * to the root element.
6925
 *
6926
 * The reason that a "bounds" rect is involved in transform calculations is
6927
 * because CSS-transforms allow percentage values for the x and y components
6928
 * of <translation-value>s, where percentages are percentages of the element's
6929
 * border box.
6930
 *
6931
 * INVARIANT: The wrapped frame is transformed or we supplied a transform getter
6932
 * function.
6933
 * INVARIANT: The wrapped frame is non-null.
6934
 */
6935
class nsDisplayTransform : public nsDisplayItem
6936
{
6937
  typedef mozilla::gfx::Matrix4x4 Matrix4x4;
6938
  typedef mozilla::gfx::Matrix4x4Flagged Matrix4x4Flagged;
6939
  typedef mozilla::gfx::Point3D Point3D;
6940
6941
  /*
6942
   * Avoid doing UpdateBounds() during construction.
6943
   */
6944
  class StoreList : public nsDisplayWrapList
6945
  {
6946
  public:
6947
    StoreList(nsDisplayListBuilder* aBuilder,
6948
              nsIFrame* aFrame,
6949
              nsDisplayList* aList)
6950
      : nsDisplayWrapList(aBuilder, aFrame, aList, true)
6951
0
    {
6952
0
    }
6953
6954
    ~StoreList() override = default;
6955
6956
    void UpdateBounds(nsDisplayListBuilder* aBuilder) override
6957
0
    {
6958
0
      // For extending 3d rendering context, the bounds would be
6959
0
      // updated by DoUpdateBoundsPreserves3D(), not here.
6960
0
      if (!mFrame->Extend3DContext()) {
6961
0
        nsDisplayWrapList::UpdateBounds(aBuilder);
6962
0
      }
6963
0
    }
6964
6965
    void ForceUpdateBounds(nsDisplayListBuilder* aBuilder)
6966
0
    {
6967
0
      nsDisplayWrapList::UpdateBounds(aBuilder);
6968
0
    }
6969
6970
    void DoUpdateBoundsPreserves3D(nsDisplayListBuilder* aBuilder) override
6971
0
    {
6972
0
      for (nsDisplayItem* i = mList.GetBottom(); i; i = i->GetAbove()) {
6973
0
        i->DoUpdateBoundsPreserves3D(aBuilder);
6974
0
      }
6975
0
      nsDisplayWrapList::UpdateBounds(aBuilder);
6976
0
    }
6977
  };
6978
6979
public:
6980
  enum PrerenderDecision
6981
  {
6982
    NoPrerender,
6983
    FullPrerender,
6984
    PartialPrerender
6985
  };
6986
6987
  /**
6988
   * Returns a matrix (in pixels) for the current frame. The matrix should be
6989
   * relative to the current frame's coordinate space.
6990
   *
6991
   * @param aFrame The frame to compute the transform for.
6992
   * @param aAppUnitsPerPixel The number of app units per graphics unit.
6993
   */
6994
  typedef Matrix4x4 (*ComputeTransformFunction)(nsIFrame* aFrame,
6995
                                                float aAppUnitsPerPixel);
6996
6997
  /* Constructor accepts a display list, empties it, and wraps it up.  It also
6998
   * ferries the underlying frame to the nsDisplayItem constructor.
6999
   */
7000
  nsDisplayTransform(nsDisplayListBuilder* aBuilder,
7001
                     nsIFrame* aFrame,
7002
                     nsDisplayList* aList,
7003
                     const nsRect& aChildrenBuildingRect,
7004
                     uint32_t aIndex = 0,
7005
                     bool aAllowAsyncAnimation = false);
7006
  nsDisplayTransform(nsDisplayListBuilder* aBuilder,
7007
                     nsIFrame* aFrame,
7008
                     nsDisplayList* aList,
7009
                     const nsRect& aChildrenBuildingRect,
7010
                     ComputeTransformFunction aTransformGetter,
7011
                     uint32_t aIndex = 0);
7012
  nsDisplayTransform(nsDisplayListBuilder* aBuilder,
7013
                     nsIFrame* aFrame,
7014
                     nsDisplayList* aList,
7015
                     const nsRect& aChildrenBuildingRect,
7016
                     const Matrix4x4& aTransform,
7017
                     uint32_t aIndex = 0);
7018
7019
#ifdef NS_BUILD_REFCNT_LOGGING
7020
  ~nsDisplayTransform() override { MOZ_COUNT_DTOR(nsDisplayTransform); }
7021
#endif
7022
7023
  NS_DISPLAY_DECL_NAME("nsDisplayTransform", TYPE_TRANSFORM)
7024
7025
0
  void RestoreState() override { mShouldFlatten = false; }
7026
7027
  void UpdateBounds(nsDisplayListBuilder* aBuilder) override
7028
0
  {
7029
0
    mHasBounds = false;
7030
0
    if (IsTransformSeparator()) {
7031
0
      mStoredList.ForceUpdateBounds(aBuilder);
7032
0
      return;
7033
0
    }
7034
0
    mStoredList.UpdateBounds(aBuilder);
7035
0
    UpdateBoundsFor3D(aBuilder);
7036
0
  }
7037
7038
  void Destroy(nsDisplayListBuilder* aBuilder) override
7039
0
  {
7040
0
    mStoredList.GetChildren()->DeleteAll(aBuilder);
7041
0
    nsDisplayItem::Destroy(aBuilder);
7042
0
  }
7043
7044
  nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const override
7045
0
  {
7046
0
    if (mStoredList.GetComponentAlphaBounds(aBuilder).IsEmpty())
7047
0
      return nsRect();
7048
0
    bool snap;
7049
0
    return GetBounds(aBuilder, &snap);
7050
0
  }
7051
7052
  RetainedDisplayList* GetChildren() const override
7053
0
  {
7054
0
    return mStoredList.GetChildren();
7055
0
  }
7056
7057
  bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override;
7058
7059
  void SetActiveScrolledRoot(
7060
    const ActiveScrolledRoot* aActiveScrolledRoot) override
7061
0
  {
7062
0
    nsDisplayItem::SetActiveScrolledRoot(aActiveScrolledRoot);
7063
0
    mStoredList.SetActiveScrolledRoot(aActiveScrolledRoot);
7064
0
  }
7065
7066
  void HitTest(nsDisplayListBuilder* aBuilder,
7067
               const nsRect& aRect,
7068
               HitTestState* aState,
7069
               nsTArray<nsIFrame*>* aOutFrames) override;
7070
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
7071
  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
7072
                           bool* aSnap) const override;
7073
  LayerState GetLayerState(
7074
    nsDisplayListBuilder* aBuilder,
7075
    LayerManager* aManager,
7076
    const ContainerLayerParameters& aParameters) override;
7077
  already_AddRefed<Layer> BuildLayer(
7078
    nsDisplayListBuilder* aBuilder,
7079
    LayerManager* aManager,
7080
    const ContainerLayerParameters& aContainerParameters) override;
7081
  bool CreateWebRenderCommands(
7082
    mozilla::wr::DisplayListBuilder& aBuilder,
7083
    mozilla::wr::IpcResourceUpdateQueue& aResources,
7084
    const StackingContextHelper& aSc,
7085
    mozilla::layers::WebRenderLayerManager* aManager,
7086
    nsDisplayListBuilder* aDisplayListBuilder) override;
7087
  bool UpdateScrollData(
7088
    mozilla::layers::WebRenderScrollData* aData,
7089
    mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
7090
  bool ShouldBuildLayerEvenIfInvisible(
7091
    nsDisplayListBuilder* aBuilder) const override;
7092
  bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
7093
                         nsRegion* aVisibleRegion) override;
7094
7095
0
  bool CanMerge(const nsDisplayItem* aItem) const override { return false; }
7096
7097
  uint32_t GetPerFrameKey() const override
7098
0
  {
7099
0
    return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
7100
0
  }
7101
7102
  nsDisplayItemGeometry* AllocateGeometry(
7103
    nsDisplayListBuilder* aBuilder) override
7104
0
  {
7105
0
    return new nsDisplayTransformGeometry(
7106
0
      this,
7107
0
      aBuilder,
7108
0
      GetTransformForRendering(),
7109
0
      mFrame->PresContext()->AppUnitsPerDevPixel());
7110
0
  }
7111
7112
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
7113
                                 const nsDisplayItemGeometry* aGeometry,
7114
                                 nsRegion* aInvalidRegion) const override
7115
0
  {
7116
0
    const nsDisplayTransformGeometry* geometry =
7117
0
      static_cast<const nsDisplayTransformGeometry*>(aGeometry);
7118
0
7119
0
    // This code is only called for flattened, inactive transform items.
7120
0
    // Only check if the transform has changed. The bounds invalidation should
7121
0
    // be handled by the children themselves.
7122
0
    if (!geometry->mTransform.FuzzyEqual(GetTransformForRendering())) {
7123
0
      bool snap;
7124
0
      aInvalidRegion->Or(GetBounds(aBuilder, &snap), geometry->mBounds);
7125
0
    }
7126
0
  }
7127
7128
0
  bool NeedsGeometryUpdates() const override { return mShouldFlatten; }
7129
7130
  const nsIFrame* ReferenceFrameForChildren() const override
7131
0
  {
7132
0
    // If we were created using a transform-getter, then we don't
7133
0
    // belong to a transformed frame, and aren't a reference frame
7134
0
    // for our children.
7135
0
    if (!mTransformGetter) {
7136
0
      return mFrame;
7137
0
    }
7138
0
    return nsDisplayItem::ReferenceFrameForChildren();
7139
0
  }
7140
7141
  AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const override
7142
0
  {
7143
0
    return mAnimatedGeometryRootForScrollMetadata;
7144
0
  }
7145
7146
  const nsRect& GetBuildingRectForChildren() const override
7147
0
  {
7148
0
    return mChildrenBuildingRect;
7149
0
  }
7150
7151
  enum
7152
  {
7153
    INDEX_MAX = UINT32_MAX >> TYPE_BITS
7154
  };
7155
7156
  /**
7157
   * We include the perspective matrix from our containing block for the
7158
   * purposes of visibility calculations, but we exclude it from the transform
7159
   * we set on the layer (for rendering), since there will be an
7160
   * nsDisplayPerspective created for that.
7161
   */
7162
  const Matrix4x4Flagged& GetTransform() const;
7163
  const Matrix4x4Flagged& GetInverseTransform() const;
7164
7165
  bool ShouldSkipTransform(nsDisplayListBuilder* aBuilder) const;
7166
  Matrix4x4 GetTransformForRendering(
7167
    mozilla::LayoutDevicePoint* aOutOrigin = nullptr) const;
7168
7169
  /**
7170
   * Return the transform that is aggregation of all transform on the
7171
   * preserves3d chain.
7172
   */
7173
  const Matrix4x4& GetAccumulatedPreserved3DTransform(
7174
    nsDisplayListBuilder* aBuilder);
7175
7176
  float GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder,
7177
                           const nsPoint& aPoint);
7178
7179
  /**
7180
   * TransformRect takes in as parameters a rectangle (in aFrame's coordinate
7181
   * space) and returns the smallest rectangle (in aFrame's coordinate space)
7182
   * containing the transformed image of that rectangle.  That is, it takes
7183
   * the four corners of the rectangle, transforms them according to the
7184
   * matrix associated with the specified frame, then returns the smallest
7185
   * rectangle containing the four transformed points.
7186
   *
7187
   * @param untransformedBounds The rectangle (in app units) to transform.
7188
   * @param aFrame The frame whose transformation should be applied.  This
7189
   *        function raises an assertion if aFrame is null or doesn't have a
7190
   *        transform applied to it.
7191
   * @param aOrigin The origin of the transform relative to aFrame's local
7192
   *        coordinate space.
7193
   * @param aBoundsOverride (optional) Rather than using the frame's computed
7194
   *        bounding rect as frame bounds, use this rectangle instead.  Pass
7195
   *        nullptr (or nothing at all) to use the default.
7196
   */
7197
  static nsRect TransformRect(const nsRect& aUntransformedBounds,
7198
                              const nsIFrame* aFrame,
7199
                              const nsRect* aBoundsOverride = nullptr);
7200
7201
  /* UntransformRect is like TransformRect, except that it inverts the
7202
   * transform.
7203
   */
7204
  static bool UntransformRect(const nsRect& aTransformedBounds,
7205
                              const nsRect& aChildBounds,
7206
                              const nsIFrame* aFrame,
7207
                              nsRect* aOutRect);
7208
7209
  bool UntransformRect(nsDisplayListBuilder* aBuilder,
7210
                       const nsRect& aRect,
7211
                       nsRect* aOutRect) const;
7212
7213
  bool UntransformBuildingRect(nsDisplayListBuilder* aBuilder,
7214
                               nsRect* aOutRect) const
7215
0
  {
7216
0
    return UntransformRect(aBuilder, GetBuildingRect(), aOutRect);
7217
0
  }
7218
7219
  bool UntransformPaintRect(nsDisplayListBuilder* aBuilder,
7220
                            nsRect* aOutRect) const
7221
0
  {
7222
0
    return UntransformRect(aBuilder, GetPaintRect(), aOutRect);
7223
0
  }
7224
7225
  static Point3D GetDeltaToTransformOrigin(const nsIFrame* aFrame,
7226
                                           float aAppUnitsPerPixel,
7227
                                           const nsRect* aBoundsOverride);
7228
7229
  /*
7230
   * Returns true if aFrame has perspective applied from its containing
7231
   * block.
7232
   * Returns the matrix to append to apply the persective (taking
7233
   * perspective-origin into account), relative to aFrames coordinate
7234
   * space).
7235
   * aOutMatrix is assumed to be the identity matrix, and isn't explicitly
7236
   * cleared.
7237
   */
7238
  static bool ComputePerspectiveMatrix(const nsIFrame* aFrame,
7239
                                       float aAppUnitsPerPixel,
7240
                                       Matrix4x4& aOutMatrix);
7241
7242
  struct FrameTransformProperties
7243
  {
7244
    FrameTransformProperties(const nsIFrame* aFrame,
7245
                             float aAppUnitsPerPixel,
7246
                             const nsRect* aBoundsOverride);
7247
    // This constructor is used on the compositor (for animations).
7248
    // Bug 1186329, Bug 1425837, If we want to support compositor animationsf
7249
    // or individual transforms and motion path, we may need to update this.
7250
    // For now, let mIndividualTransformList and mMotion as nullptr and
7251
    // Nothing().
7252
    FrameTransformProperties(
7253
      RefPtr<const nsCSSValueSharedList>&& aTransformList,
7254
      const Point3D& aToTransformOrigin)
7255
      : mFrame(nullptr)
7256
      , mTransformList(std::move(aTransformList))
7257
      , mToTransformOrigin(aToTransformOrigin)
7258
    {
7259
    }
7260
7261
    bool HasTransform() const
7262
0
    {
7263
0
      return mIndividualTransformList || mTransformList || mMotion.isSome();
7264
0
    }
7265
7266
    const nsIFrame* mFrame;
7267
    const RefPtr<const nsCSSValueSharedList> mIndividualTransformList;
7268
    const mozilla::Maybe<mozilla::MotionPathData> mMotion;
7269
    const RefPtr<const nsCSSValueSharedList> mTransformList;
7270
    const Point3D mToTransformOrigin;
7271
  };
7272
7273
  /**
7274
   * Given a frame with the -moz-transform property or an SVG transform,
7275
   * returns the transformation matrix for that frame.
7276
   *
7277
   * @param aFrame The frame to get the matrix from.
7278
   * @param aOrigin Relative to which point this transform should be applied.
7279
   * @param aAppUnitsPerPixel The number of app units per graphics unit.
7280
   * @param aBoundsOverride [optional] If this is nullptr (the default), the
7281
   *        computation will use the value of TransformReferenceBox(aFrame).
7282
   *        Otherwise, it will use the value of aBoundsOverride.  This is
7283
   *        mostly for internal use and in most cases you will not need to
7284
   *        specify a value.
7285
   * @param aFlags OFFSET_BY_ORIGIN The resulting matrix will be translated
7286
   *        by aOrigin. This translation is applied *before* the CSS transform.
7287
   * @param aFlags INCLUDE_PRESERVE3D_ANCESTORS The computed transform will
7288
   *        include the transform of any ancestors participating in the same
7289
   *        3d rendering context.
7290
   * @param aFlags INCLUDE_PERSPECTIVE The resulting matrix will include the
7291
   *        perspective transform from the containing block if applicable.
7292
   */
7293
  enum
7294
  {
7295
    OFFSET_BY_ORIGIN = 1 << 0,
7296
    INCLUDE_PRESERVE3D_ANCESTORS = 1 << 1,
7297
    INCLUDE_PERSPECTIVE = 1 << 2,
7298
  };
7299
  static Matrix4x4 GetResultingTransformMatrix(
7300
    const nsIFrame* aFrame,
7301
    const nsPoint& aOrigin,
7302
    float aAppUnitsPerPixel,
7303
    uint32_t aFlags,
7304
    const nsRect* aBoundsOverride = nullptr);
7305
  static Matrix4x4 GetResultingTransformMatrix(
7306
    const FrameTransformProperties& aProperties,
7307
    const nsPoint& aOrigin,
7308
    float aAppUnitsPerPixel,
7309
    uint32_t aFlags,
7310
    const nsRect* aBoundsOverride = nullptr);
7311
  /**
7312
   * Decide whether we should prerender some or all of the contents of the
7313
   * transformed frame even when it's not completely visible (yet).
7314
   * Return FullPrerender if the entire contents should be prerendered,
7315
   * PartialPrerender if some but not all of the contents should be prerendered,
7316
   * or NoPrerender if only the visible area should be rendered.
7317
   * |aDirtyRect| is updated to the area that should be prerendered.
7318
   */
7319
  static PrerenderDecision ShouldPrerenderTransformedContent(
7320
    nsDisplayListBuilder* aBuilder,
7321
    nsIFrame* aFrame,
7322
    nsRect* aDirtyRect);
7323
  bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) override;
7324
7325
  bool MayBeAnimated(nsDisplayListBuilder* aBuilder) const;
7326
7327
  void WriteDebugInfo(std::stringstream& aStream) override;
7328
7329
  // Force the layer created for this item not to extend 3D context.
7330
  // See nsIFrame::BuildDisplayListForStackingContext()
7331
0
  void SetNoExtendContext() { mNoExtendContext = true; }
7332
7333
  void DoUpdateBoundsPreserves3D(nsDisplayListBuilder* aBuilder) override
7334
0
  {
7335
0
    MOZ_ASSERT(mFrame->Combines3DTransformWithAncestors() ||
7336
0
               IsTransformSeparator());
7337
0
    // Updating is not going through to child 3D context.
7338
0
    ComputeBounds(aBuilder);
7339
0
  }
7340
7341
  /**
7342
   * This function updates bounds for items with a frame establishing
7343
   * 3D rendering context.
7344
   *
7345
   * \see nsDisplayItem::DoUpdateBoundsPreserves3D()
7346
   */
7347
  void UpdateBoundsFor3D(nsDisplayListBuilder* aBuilder)
7348
0
  {
7349
0
    if (!mFrame->Extend3DContext() ||
7350
0
        mFrame->Combines3DTransformWithAncestors() || IsTransformSeparator()) {
7351
0
      // Not an establisher of a 3D rendering context.
7352
0
      return;
7353
0
    }
7354
0
    // Always start updating from an establisher of a 3D rendering context.
7355
0
7356
0
    nsDisplayListBuilder::AutoAccumulateRect accRect(aBuilder);
7357
0
    nsDisplayListBuilder::AutoAccumulateTransform accTransform(aBuilder);
7358
0
    accTransform.StartRoot();
7359
0
    ComputeBounds(aBuilder);
7360
0
    mBounds = aBuilder->GetAccumulatedRect();
7361
0
    mHasBounds = true;
7362
0
  }
7363
7364
  /**
7365
   * This item is an additional item as the boundary between parent
7366
   * and child 3D rendering context.
7367
   * \see nsIFrame::BuildDisplayListForStackingContext().
7368
   */
7369
0
  bool IsTransformSeparator() { return mIsTransformSeparator; }
7370
  /**
7371
   * This item is the boundary between parent and child 3D rendering
7372
   * context.
7373
   */
7374
  bool IsLeafOf3DContext()
7375
0
  {
7376
0
    return (IsTransformSeparator() ||
7377
0
            (!mFrame->Extend3DContext() &&
7378
0
             mFrame->Combines3DTransformWithAncestors()));
7379
0
  }
7380
  /**
7381
   * The backing frame of this item participates a 3D rendering
7382
   * context.
7383
   */
7384
  bool IsParticipating3DContext()
7385
0
  {
7386
0
    return mFrame->Extend3DContext() ||
7387
0
           mFrame->Combines3DTransformWithAncestors();
7388
0
  }
7389
7390
  void RemoveFrame(nsIFrame* aFrame) override
7391
0
  {
7392
0
    nsDisplayItem::RemoveFrame(aFrame);
7393
0
    mStoredList.RemoveFrame(aFrame);
7394
0
  }
7395
7396
private:
7397
  void ComputeBounds(nsDisplayListBuilder* aBuilder);
7398
  void SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder);
7399
  void Init(nsDisplayListBuilder* aBuilder);
7400
7401
  static Matrix4x4 GetResultingTransformMatrixInternal(
7402
    const FrameTransformProperties& aProperties,
7403
    const nsPoint& aOrigin,
7404
    float aAppUnitsPerPixel,
7405
    uint32_t aFlags,
7406
    const nsRect* aBoundsOverride);
7407
7408
  StoreList mStoredList;
7409
  mutable mozilla::Maybe<Matrix4x4Flagged> mTransform;
7410
  mutable mozilla::Maybe<Matrix4x4Flagged> mInverseTransform;
7411
  // Accumulated transform of ancestors on the preserves-3d chain.
7412
  Matrix4x4 mTransformPreserves3D;
7413
  ComputeTransformFunction mTransformGetter;
7414
  RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRootForChildren;
7415
  RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRootForScrollMetadata;
7416
  nsRect mChildrenBuildingRect;
7417
  uint32_t mIndex;
7418
  mutable nsRect mBounds;
7419
  // True for mBounds is valid.
7420
  mutable bool mHasBounds;
7421
  // Be forced not to extend 3D context.  Since we don't create a
7422
  // transform item, a container layer, for every frames in a
7423
  // preserves3d context, the transform items of a child preserves3d
7424
  // context may extend the parent context not intented if the root of
7425
  // the child preserves3d context doesn't create a transform item.
7426
  // With this flags, we force the item not extending 3D context.
7427
  bool mNoExtendContext;
7428
  // This item is a separator between 3D rendering contexts, and
7429
  // mTransform have been presetted by the constructor.
7430
  bool mIsTransformSeparator;
7431
  // True if mTransformPreserves3D have been initialized.
7432
  bool mTransformPreserves3DInited;
7433
  // True if async animation of the transform is allowed.
7434
  bool mAllowAsyncAnimation;
7435
  // True if this nsDisplayTransform should get flattened
7436
  bool mShouldFlatten;
7437
};
7438
7439
/* A display item that applies a perspective transformation to a single
7440
 * nsDisplayTransform child item. We keep this as a separate item since the
7441
 * perspective-origin is relative to an ancestor of the transformed frame, and
7442
 * APZ can scroll the child separately.
7443
 */
7444
class nsDisplayPerspective : public nsDisplayItem
7445
{
7446
  typedef mozilla::gfx::Point3D Point3D;
7447
7448
public:
7449
  nsDisplayPerspective(nsDisplayListBuilder* aBuilder,
7450
                       nsIFrame* aFrame,
7451
                       nsDisplayList* aList);
7452
0
  ~nsDisplayPerspective() override = default;
7453
7454
  NS_DISPLAY_DECL_NAME("nsDisplayPerspective", TYPE_PERSPECTIVE)
7455
7456
  void HitTest(nsDisplayListBuilder* aBuilder,
7457
               const nsRect& aRect,
7458
               HitTestState* aState,
7459
               nsTArray<nsIFrame*>* aOutFrames) override
7460
0
  {
7461
0
    return mList.HitTest(aBuilder, aRect, aState, aOutFrames);
7462
0
  }
7463
7464
  nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override
7465
0
  {
7466
0
    return mList.GetBounds(aBuilder, aSnap);
7467
0
  }
7468
7469
  void UpdateBounds(nsDisplayListBuilder* aBuilder) override
7470
0
  {
7471
0
    mList.UpdateBounds(aBuilder);
7472
0
  }
7473
7474
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
7475
                                 const nsDisplayItemGeometry* aGeometry,
7476
                                 nsRegion* aInvalidRegion) const override
7477
0
  {
7478
0
  }
7479
7480
  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
7481
                           bool* aSnap) const override
7482
0
  {
7483
0
    return mList.GetOpaqueRegion(aBuilder, aSnap);
7484
0
  }
7485
7486
  mozilla::Maybe<nscolor> IsUniform(
7487
    nsDisplayListBuilder* aBuilder) const override
7488
0
  {
7489
0
    return mList.IsUniform(aBuilder);
7490
0
  }
7491
7492
  LayerState GetLayerState(
7493
    nsDisplayListBuilder* aBuilder,
7494
    LayerManager* aManager,
7495
    const ContainerLayerParameters& aParameters) override;
7496
  bool CreateWebRenderCommands(
7497
    mozilla::wr::DisplayListBuilder& aBuilder,
7498
    mozilla::wr::IpcResourceUpdateQueue& aResources,
7499
    const StackingContextHelper& aSc,
7500
    mozilla::layers::WebRenderLayerManager* aManager,
7501
    nsDisplayListBuilder* aDisplayListBuilder) override;
7502
7503
  bool ShouldBuildLayerEvenIfInvisible(
7504
    nsDisplayListBuilder* aBuilder) const override
7505
0
  {
7506
0
    if (!mList.GetChildren()->GetTop()) {
7507
0
      return false;
7508
0
    }
7509
0
    return mList.GetChildren()->GetTop()->ShouldBuildLayerEvenIfInvisible(
7510
0
      aBuilder);
7511
0
  }
7512
7513
  already_AddRefed<Layer> BuildLayer(
7514
    nsDisplayListBuilder* aBuilder,
7515
    LayerManager* aManager,
7516
    const ContainerLayerParameters& aContainerParameters) override;
7517
7518
  bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
7519
                         nsRegion* aVisibleRegion) override
7520
0
  {
7521
0
    mList.RecomputeVisibility(aBuilder, aVisibleRegion);
7522
0
    return true;
7523
0
  }
7524
7525
  RetainedDisplayList* GetSameCoordinateSystemChildren() const override
7526
0
  {
7527
0
    return mList.GetChildren();
7528
0
  }
7529
7530
  RetainedDisplayList* GetChildren() const override
7531
0
  {
7532
0
    return mList.GetChildren();
7533
0
  }
7534
7535
  void SetActiveScrolledRoot(
7536
    const ActiveScrolledRoot* aActiveScrolledRoot) override
7537
0
  {
7538
0
    nsDisplayItem::SetActiveScrolledRoot(aActiveScrolledRoot);
7539
0
    mList.SetActiveScrolledRoot(aActiveScrolledRoot);
7540
0
  }
7541
7542
  nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const override
7543
0
  {
7544
0
    return mList.GetComponentAlphaBounds(aBuilder);
7545
0
  }
7546
7547
  void DoUpdateBoundsPreserves3D(nsDisplayListBuilder* aBuilder) override
7548
0
  {
7549
0
    if (mList.GetChildren()->GetTop()) {
7550
0
      static_cast<nsDisplayTransform*>(mList.GetChildren()->GetTop())
7551
0
        ->DoUpdateBoundsPreserves3D(aBuilder);
7552
0
    }
7553
0
  }
7554
7555
  void Destroy(nsDisplayListBuilder* aBuilder) override
7556
0
  {
7557
0
    mList.GetChildren()->DeleteAll(aBuilder);
7558
0
    nsDisplayItem::Destroy(aBuilder);
7559
0
  }
7560
7561
  void RemoveFrame(nsIFrame* aFrame) override
7562
0
  {
7563
0
    nsDisplayItem::RemoveFrame(aFrame);
7564
0
    mList.RemoveFrame(aFrame);
7565
0
  }
7566
7567
private:
7568
  nsDisplayWrapList mList;
7569
};
7570
7571
/**
7572
 * This class adds basic support for limiting the rendering (in the inline axis
7573
 * of the writing mode) to the part inside the specified edges.  It's a base
7574
 * class for the display item classes that do the actual work.
7575
 * The two members, mVisIStartEdge and mVisIEndEdge, are relative to the edges
7576
 * of the frame's scrollable overflow rectangle and are the amount to suppress
7577
 * on each side.
7578
 *
7579
 * Setting none, both or only one edge is allowed.
7580
 * The values must be non-negative.
7581
 * The default value for both edges is zero, which means everything is painted.
7582
 */
7583
class nsCharClipDisplayItem : public nsDisplayItem
7584
{
7585
public:
7586
  nsCharClipDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
7587
    : nsDisplayItem(aBuilder, aFrame)
7588
    , mVisIStartEdge(0)
7589
    , mVisIEndEdge(0)
7590
0
  {
7591
0
  }
7592
7593
  explicit nsCharClipDisplayItem(nsIFrame* aFrame)
7594
    : nsDisplayItem(aFrame)
7595
    , mVisIStartEdge(0)
7596
    , mVisIEndEdge(0)
7597
0
  {
7598
0
  }
7599
7600
  void RestoreState() override
7601
0
  {
7602
0
    nsDisplayItem::RestoreState();
7603
0
    mIsFrameSelected.reset();
7604
0
  }
7605
7606
  nsDisplayItemGeometry* AllocateGeometry(
7607
    nsDisplayListBuilder* aBuilder) override;
7608
7609
  void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
7610
                                 const nsDisplayItemGeometry* aGeometry,
7611
                                 nsRegion* aInvalidRegion) const override;
7612
7613
  struct ClipEdges
7614
  {
7615
    ClipEdges(const nsDisplayItem& aItem,
7616
              nscoord aVisIStartEdge,
7617
              nscoord aVisIEndEdge)
7618
0
    {
7619
0
      nsRect r =
7620
0
        aItem.Frame()->GetScrollableOverflowRect() + aItem.ToReferenceFrame();
7621
0
      if (aItem.Frame()->GetWritingMode().IsVertical()) {
7622
0
        mVisIStart = aVisIStartEdge > 0 ? r.y + aVisIStartEdge : nscoord_MIN;
7623
0
        mVisIEnd = aVisIEndEdge > 0
7624
0
                     ? std::max(r.YMost() - aVisIEndEdge, mVisIStart)
7625
0
                     : nscoord_MAX;
7626
0
      } else {
7627
0
        mVisIStart = aVisIStartEdge > 0 ? r.x + aVisIStartEdge : nscoord_MIN;
7628
0
        mVisIEnd = aVisIEndEdge > 0
7629
0
                     ? std::max(r.XMost() - aVisIEndEdge, mVisIStart)
7630
0
                     : nscoord_MAX;
7631
0
      }
7632
0
    }
7633
7634
    void Intersect(nscoord* aVisIStart, nscoord* aVisISize) const
7635
0
    {
7636
0
      nscoord end = *aVisIStart + *aVisISize;
7637
0
      *aVisIStart = std::max(*aVisIStart, mVisIStart);
7638
0
      *aVisISize = std::max(std::min(end, mVisIEnd) - *aVisIStart, 0);
7639
0
    }
7640
7641
    nscoord mVisIStart;
7642
    nscoord mVisIEnd;
7643
  };
7644
7645
  ClipEdges Edges() const
7646
  {
7647
    return ClipEdges(*this, mVisIStartEdge, mVisIEndEdge);
7648
  }
7649
7650
  static nsCharClipDisplayItem* CheckCast(nsDisplayItem* aItem)
7651
0
  {
7652
0
    DisplayItemType t = aItem->GetType();
7653
0
    return (t == DisplayItemType::TYPE_TEXT ||
7654
0
            t == DisplayItemType::TYPE_SVG_CHAR_CLIP)
7655
0
             ? static_cast<nsCharClipDisplayItem*>(aItem)
7656
0
             : nullptr;
7657
0
  }
7658
7659
  // Lengths measured from the visual inline start and end sides
7660
  // (i.e. left and right respectively in horizontal writing modes,
7661
  // regardless of bidi directionality; top and bottom in vertical modes).
7662
  nscoord mVisIStartEdge;
7663
  nscoord mVisIEndEdge;
7664
  // Cached result of mFrame->IsSelected().  Only initialized when needed.
7665
  mutable mozilla::Maybe<bool> mIsFrameSelected;
7666
};
7667
7668
/**
7669
 * A display item that for webrender to handle SVG
7670
 */
7671
class nsDisplaySVGWrapper : public nsDisplayWrapList
7672
{
7673
public:
7674
  nsDisplaySVGWrapper(nsDisplayListBuilder* aBuilder,
7675
                      nsIFrame* aFrame,
7676
                      nsDisplayList* aList);
7677
7678
#ifdef NS_BUILD_REFCNT_LOGGING
7679
  ~nsDisplaySVGWrapper() override { MOZ_COUNT_DTOR(nsDisplaySVGWrapper); }
7680
#endif
7681
7682
  NS_DISPLAY_DECL_NAME("SVGWrapper", TYPE_SVG_WRAPPER)
7683
7684
  already_AddRefed<Layer> BuildLayer(
7685
    nsDisplayListBuilder* aBuilder,
7686
    LayerManager* aManager,
7687
    const ContainerLayerParameters& aContainerParameters) override;
7688
  LayerState GetLayerState(
7689
    nsDisplayListBuilder* aBuilder,
7690
    LayerManager* aManager,
7691
    const ContainerLayerParameters& aParameters) override;
7692
  bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override;
7693
  bool CreateWebRenderCommands(
7694
    mozilla::wr::DisplayListBuilder& aBuilder,
7695
    mozilla::wr::IpcResourceUpdateQueue& aResources,
7696
    const StackingContextHelper& aSc,
7697
    mozilla::layers::WebRenderLayerManager* aManager,
7698
    nsDisplayListBuilder* aDisplayListBuilder) override;
7699
};
7700
7701
/**
7702
 * A display item for webrender to handle SVG foreign object
7703
 */
7704
class nsDisplayForeignObject : public nsDisplayWrapList {
7705
public:
7706
  NS_DISPLAY_DECL_NAME("ForeignObject", TYPE_FOREIGN_OBJECT)
7707
7708
  nsDisplayForeignObject(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
7709
                         nsDisplayList* aList);
7710
#ifdef NS_BUILD_REFCNT_LOGGING
7711
  virtual ~nsDisplayForeignObject();
7712
#endif
7713
  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
7714
                                             LayerManager* aManager,
7715
                                             const ContainerLayerParameters& aContainerParameters) override;
7716
  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
7717
                                   LayerManager* aManager,
7718
                                   const ContainerLayerParameters& aParameters) override;
7719
  virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override;
7720
7721
  bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
7722
                               mozilla::wr::IpcResourceUpdateQueue& aResources,
7723
                               const StackingContextHelper& aSc,
7724
                               mozilla::layers::WebRenderLayerManager* aManager,
7725
                               nsDisplayListBuilder* aDisplayListBuilder) override;
7726
};
7727
7728
namespace mozilla {
7729
7730
class PaintTelemetry
7731
{
7732
public:
7733
  enum class Metric
7734
  {
7735
    DisplayList,
7736
    Layerization,
7737
    FlushRasterization,
7738
    Rasterization,
7739
    COUNT,
7740
  };
7741
7742
  class AutoRecord
7743
  {
7744
  public:
7745
    explicit AutoRecord(Metric aMetric);
7746
    ~AutoRecord();
7747
7748
0
    TimeStamp GetStart() const { return mStart; }
7749
7750
  private:
7751
    Metric mMetric;
7752
    mozilla::TimeStamp mStart;
7753
  };
7754
7755
  class AutoRecordPaint
7756
  {
7757
  public:
7758
    AutoRecordPaint();
7759
    ~AutoRecordPaint();
7760
7761
  private:
7762
    mozilla::TimeStamp mStart;
7763
  };
7764
7765
private:
7766
  static uint32_t sPaintLevel;
7767
  static uint32_t sMetricLevel;
7768
  static mozilla::EnumeratedArray<Metric, Metric::COUNT, double> sMetrics;
7769
};
7770
7771
} // namespace mozilla
7772
7773
#endif /*NSDISPLAYLIST_H_*/