/work/obj-fuzz/dist/include/mozilla/layers/AsyncCompositionManager.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 | | #ifndef GFX_ASYNCCOMPOSITIONMANAGER_H |
8 | | #define GFX_ASYNCCOMPOSITIONMANAGER_H |
9 | | |
10 | | #include "Units.h" // for ScreenPoint, etc |
11 | | #include "mozilla/layers/LayerManagerComposite.h" // for LayerManagerComposite |
12 | | #include "mozilla/Attributes.h" // for final, etc |
13 | | #include "mozilla/RefPtr.h" // for RefCounted |
14 | | #include "mozilla/TimeStamp.h" // for TimeStamp |
15 | | #include "mozilla/gfx/BasePoint.h" // for BasePoint |
16 | | #include "mozilla/gfx/Matrix.h" // for Matrix4x4 |
17 | | #include "mozilla/HalScreenConfiguration.h" // For ScreenOrientation |
18 | | #include "mozilla/layers/FrameUniformityData.h" // For FrameUniformityData |
19 | | #include "mozilla/layers/LayersMessages.h" // for TargetConfig |
20 | | #include "mozilla/RefPtr.h" // for nsRefPtr |
21 | | #include "nsISupportsImpl.h" // for LayerManager::AddRef, etc |
22 | | #include "CompositorBridgeParent.h" // for TransformsToSkip |
23 | | |
24 | | namespace mozilla { |
25 | | namespace layers { |
26 | | |
27 | | class Layer; |
28 | | class LayerManagerComposite; |
29 | | class AutoResolveRefLayers; |
30 | | class CompositorBridgeParent; |
31 | | |
32 | | // Represents async transforms consisting of a scale and a translation. |
33 | | struct AsyncTransform { |
34 | | explicit AsyncTransform(LayerToParentLayerScale aScale = LayerToParentLayerScale(), |
35 | | ParentLayerPoint aTranslation = ParentLayerPoint()) |
36 | | : mScale(aScale) |
37 | | , mTranslation(aTranslation) |
38 | 0 | {} |
39 | | |
40 | | operator AsyncTransformComponentMatrix() const |
41 | 0 | { |
42 | 0 | return AsyncTransformComponentMatrix::Scaling(mScale.scale, mScale.scale, 1) |
43 | 0 | .PostTranslate(mTranslation.x, mTranslation.y, 0); |
44 | 0 | } |
45 | | |
46 | 0 | bool operator==(const AsyncTransform& rhs) const { |
47 | 0 | return mTranslation == rhs.mTranslation && mScale == rhs.mScale; |
48 | 0 | } |
49 | | |
50 | 0 | bool operator!=(const AsyncTransform& rhs) const { |
51 | 0 | return !(*this == rhs); |
52 | 0 | } |
53 | | |
54 | | LayerToParentLayerScale mScale; |
55 | | ParentLayerPoint mTranslation; |
56 | | }; |
57 | | |
58 | | /** |
59 | | * Manage async composition effects. This class is only used with OMTC and only |
60 | | * lives on the compositor thread. It is a layer on top of the layer manager |
61 | | * (LayerManagerComposite) which deals with elements of composition which are |
62 | | * usually dealt with by dom or layout when main thread rendering, but which can |
63 | | * short circuit that stuff to directly affect layers as they are composited, |
64 | | * for example, off-main thread animation, async video, async pan/zoom. |
65 | | */ |
66 | | class AsyncCompositionManager final |
67 | | { |
68 | | friend class AutoResolveRefLayers; |
69 | | ~AsyncCompositionManager(); |
70 | | |
71 | | public: |
72 | | NS_INLINE_DECL_REFCOUNTING(AsyncCompositionManager) |
73 | | |
74 | | explicit AsyncCompositionManager(CompositorBridgeParent* aParent, HostLayerManager* aManager); |
75 | | |
76 | | /** |
77 | | * This forces the is-first-paint flag to true. This is intended to |
78 | | * be called by the widget code when it loses its viewport information |
79 | | * (or for whatever reason wants to refresh the viewport information). |
80 | | * The information refresh happens because the compositor will call |
81 | | * AndroidDynamicToolbarAnimator::FirstPaint() on the next frame of composition. |
82 | | */ |
83 | 0 | void ForceIsFirstPaint() { mIsFirstPaint = true; } |
84 | | |
85 | | // Sample transforms for layer trees. Return true to request |
86 | | // another animation frame. |
87 | | bool TransformShadowTree( |
88 | | TimeStamp aCurrentFrame, |
89 | | TimeDuration aVsyncRate, |
90 | | CompositorBridgeParentBase::TransformsToSkip aSkip = |
91 | | CompositorBridgeParentBase::TransformsToSkip::NoneOfThem); |
92 | | |
93 | | // Calculates the correct rotation and applies the transform to |
94 | | // our layer manager |
95 | | void ComputeRotation(); |
96 | | |
97 | | // Call after updating our layer tree. |
98 | | void Updated(bool isFirstPaint, const TargetConfig& aTargetConfig) |
99 | 0 | { |
100 | 0 | mIsFirstPaint |= isFirstPaint; |
101 | 0 | mLayersUpdated = true; |
102 | 0 | mTargetConfig = aTargetConfig; |
103 | 0 | } |
104 | | |
105 | | bool RequiresReorientation(hal::ScreenOrientation aOrientation) const |
106 | 0 | { |
107 | 0 | return mTargetConfig.orientation() != aOrientation; |
108 | 0 | } |
109 | | |
110 | | // True if the underlying layer tree is ready to be composited. |
111 | 0 | bool ReadyForCompose() { return mReadyForCompose; } |
112 | | |
113 | | // Returns true if the next composition will be the first for a |
114 | | // particular document. |
115 | 0 | bool IsFirstPaint() { return mIsFirstPaint; } |
116 | | |
117 | | // GetFrameUniformity will return the frame uniformity for each layer attached to an APZ |
118 | | // from the recorded data in RecordShadowTransform |
119 | | void GetFrameUniformity(FrameUniformityData* aFrameUniformityData); |
120 | | |
121 | | // Stores the clip rect of a layer in two parts: a fixed part and a scrolled |
122 | | // part. When a layer is fixed, the clip needs to be adjusted to account for |
123 | | // async transforms. Only the fixed part needs to be adjusted, so we need |
124 | | // to store the two parts separately. |
125 | | struct ClipParts { |
126 | | Maybe<ParentLayerIntRect> mFixedClip; |
127 | | Maybe<ParentLayerIntRect> mScrolledClip; |
128 | | |
129 | 0 | Maybe<ParentLayerIntRect> Intersect() const { |
130 | 0 | return IntersectMaybeRects(mFixedClip, mScrolledClip); |
131 | 0 | } |
132 | | }; |
133 | | |
134 | | typedef std::map<Layer*, ClipParts> ClipPartsCache; |
135 | | |
136 | | private: |
137 | | // Return true if an AsyncPanZoomController content transform was |
138 | | // applied for |aLayer|. |*aOutFoundRoot| is set to true on Android only, if |
139 | | // one of the metrics on one of the layers was determined to be the "root" |
140 | | // and its state was synced to the Java front-end. |aOutFoundRoot| must be |
141 | | // non-null. |
142 | | bool ApplyAsyncContentTransformToTree(Layer* aLayer, |
143 | | bool* aOutFoundRoot); |
144 | | /** |
145 | | * Update the shadow transform for aLayer assuming that is a scrollbar, |
146 | | * so that it stays in sync with the content that is being scrolled by APZ. |
147 | | */ |
148 | | void ApplyAsyncTransformToScrollbar(Layer* aLayer); |
149 | | |
150 | | /** |
151 | | * Adds a translation to the transform of any fixed position (whose parent |
152 | | * layer is not fixed) or sticky position layer descendant of |
153 | | * |aTransformedSubtreeRoot|. The translation is chosen so that the layer's |
154 | | * anchor point relative to |aTransformedSubtreeRoot|'s parent layer is the same |
155 | | * as it was when |aTransformedSubtreeRoot|'s GetLocalTransform() was |
156 | | * |aPreviousTransformForRoot|. |aCurrentTransformForRoot| is |
157 | | * |aTransformedSubtreeRoot|'s current GetLocalTransform() modulo any |
158 | | * overscroll-related transform, which we don't want to adjust for. |
159 | | * For sticky position layers, the translation is further intersected with |
160 | | * the layer's sticky scroll ranges. |
161 | | * This function will also adjust layers so that the given content document |
162 | | * fixed position margins will be respected during asynchronous panning and |
163 | | * zooming. |
164 | | * |aTransformScrollId| is the scroll id of the scroll frame that scrolls |
165 | | * |aTransformedSubtreeRoot|. |
166 | | * |aClipPartsCache| optionally maps layers to separate fixed and scrolled |
167 | | * clips, so we can only adjust the fixed portion. |
168 | | * This function has a recursive implementation; aStartTraversalAt specifies |
169 | | * where to start the current recursion of the traversal. For the initial |
170 | | * call, it should be the same as aTrasnformedSubtreeRoot. |
171 | | */ |
172 | | void AlignFixedAndStickyLayers(Layer* aTransformedSubtreeRoot, |
173 | | Layer* aStartTraversalAt, |
174 | | FrameMetrics::ViewID aTransformScrollId, |
175 | | const LayerToParentLayerMatrix4x4& aPreviousTransformForRoot, |
176 | | const LayerToParentLayerMatrix4x4& aCurrentTransformForRoot, |
177 | | const ScreenMargin& aFixedLayerMargins, |
178 | | ClipPartsCache* aClipPartsCache); |
179 | | |
180 | | /** |
181 | | * DRAWING PHASE ONLY |
182 | | * |
183 | | * For reach RefLayer in our layer tree, look up its referent and connect it |
184 | | * to the layer tree, if found. |
185 | | * aHasRemoteContent - indicates if the layer tree contains a remote reflayer. |
186 | | * May be null. |
187 | | * aResolvePlugins - incoming value indicates if plugin windows should be |
188 | | * updated through a call on aCompositor's UpdatePluginWindowState. Applies |
189 | | * to linux and windows only, may be null. On return value indicates |
190 | | * if any updates occured. |
191 | | */ |
192 | | void ResolveRefLayers(CompositorBridgeParent* aCompositor, bool* aHasRemoteContent, |
193 | | bool* aResolvePlugins); |
194 | | |
195 | | /** |
196 | | * Detaches all referents resolved by ResolveRefLayers. |
197 | | * Assumes that mLayerManager->GetRoot() and mTargetConfig have not changed |
198 | | * since ResolveRefLayers was called. |
199 | | */ |
200 | | void DetachRefLayers(); |
201 | | |
202 | | // Records the shadow transforms for the tree of layers rooted at the given layer |
203 | | void RecordShadowTransforms(Layer* aLayer); |
204 | | |
205 | | TargetConfig mTargetConfig; |
206 | | CSSRect mContentRect; |
207 | | |
208 | | RefPtr<HostLayerManager> mLayerManager; |
209 | | // When this flag is set, the next composition will be the first for a |
210 | | // particular document (i.e. the document displayed on the screen will change). |
211 | | // This happens when loading a new page or switching tabs. We notify the |
212 | | // front-end (e.g. Java on Android) about this so that it take the new page |
213 | | // size and zoom into account when providing us with the next view transform. |
214 | | bool mIsFirstPaint; |
215 | | |
216 | | // This flag is set during a layers update, so that the first composition |
217 | | // after a layers update has it set. It is cleared after that first composition. |
218 | | bool mLayersUpdated; |
219 | | |
220 | | bool mReadyForCompose; |
221 | | |
222 | | gfx::Matrix mWorldTransform; |
223 | | LayerTransformRecorder mLayerTransformRecorder; |
224 | | |
225 | | TimeStamp mPreviousFrameTimeStamp; |
226 | | |
227 | | MOZ_NON_OWNING_REF CompositorBridgeParent* mCompositorBridge; |
228 | | |
229 | | #ifdef MOZ_WIDGET_ANDROID |
230 | | public: |
231 | | void SetFixedLayerMargins(ScreenIntCoord aTop, ScreenIntCoord aBottom); |
232 | | private: |
233 | | // The following two fields are only needed on Fennec with C++ APZ, because |
234 | | // then we need to reposition the gecko scrollbar to deal with the |
235 | | // dynamic toolbar shifting content around. |
236 | | FrameMetrics::ViewID mRootScrollableId; |
237 | | ScreenMargin mFixedLayerMargins; |
238 | | #endif |
239 | | }; |
240 | | |
241 | | class MOZ_STACK_CLASS AutoResolveRefLayers { |
242 | | public: |
243 | | explicit AutoResolveRefLayers(AsyncCompositionManager* aManager, |
244 | | CompositorBridgeParent* aCompositor = nullptr, |
245 | | bool* aHasRemoteContent = nullptr, |
246 | | bool* aResolvePlugins = nullptr) : |
247 | | mManager(aManager) |
248 | 0 | { |
249 | 0 | if (mManager) { |
250 | 0 | mManager->ResolveRefLayers(aCompositor, aHasRemoteContent, aResolvePlugins); |
251 | 0 | } |
252 | 0 | } |
253 | | |
254 | | ~AutoResolveRefLayers() |
255 | 0 | { |
256 | 0 | if (mManager) { |
257 | 0 | mManager->DetachRefLayers(); |
258 | 0 | } |
259 | 0 | } |
260 | | |
261 | | private: |
262 | | AsyncCompositionManager* mManager; |
263 | | |
264 | | AutoResolveRefLayers(const AutoResolveRefLayers&) = delete; |
265 | | AutoResolveRefLayers& operator=(const AutoResolveRefLayers&) = delete; |
266 | | }; |
267 | | |
268 | | } // namespace layers |
269 | | } // namespace mozilla |
270 | | |
271 | | #endif |