/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_*/ |