/work/obj-fuzz/dist/include/mozilla/layers/WebRenderScrollDataWrapper.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_WEBRENDERSCROLLDATAWRAPPER_H |
8 | | #define GFX_WEBRENDERSCROLLDATAWRAPPER_H |
9 | | |
10 | | #include "FrameMetrics.h" |
11 | | #include "mozilla/layers/CompositorBridgeParent.h" |
12 | | #include "mozilla/layers/WebRenderBridgeParent.h" |
13 | | #include "mozilla/layers/WebRenderScrollData.h" |
14 | | |
15 | | namespace mozilla { |
16 | | namespace layers { |
17 | | |
18 | | /* |
19 | | * This class is a wrapper to walk through a WebRenderScrollData object, with |
20 | | * an exposed API that is template-compatible to LayerMetricsWrapper. This allows |
21 | | * APZ to walk through both layer trees and WebRender scroll metadata structures |
22 | | * without a lot of code duplication. |
23 | | * (Note that not all functions from LayerMetricsWrapper are implemented here, |
24 | | * only the ones we've needed in APZ code so far.) |
25 | | * |
26 | | * A WebRenderScrollData object is basically a flattened layer tree, with a |
27 | | * number of WebRenderLayerScrollData objects that have a 1:1 correspondence |
28 | | * to layers in a layer tree. Therefore the mLayer pointer in this class can |
29 | | * be considered equivalent to the mLayer pointer in the LayerMetricsWrapper. |
30 | | * There are some extra fields (mData, mLayerIndex, mContainingSubtreeLastIndex) |
31 | | * to move around between these "layers" given the flattened representation. |
32 | | * The mMetadataIndex field in this class corresponds to the mIndex field in |
33 | | * LayerMetricsWrapper, as both classes also need to manage walking through |
34 | | * "virtual" container layers implied by the list of ScrollMetadata objects. |
35 | | * |
36 | | * One important note here is that this class holds a pointer to the "owning" |
37 | | * WebRenderScrollData. The caller must ensure that this class does not outlive |
38 | | * the owning WebRenderScrollData, or this may result in use-after-free errors. |
39 | | * This class being declared a MOZ_STACK_CLASS should help with that. |
40 | | * |
41 | | * Refer to LayerMetricsWrapper.h for actual documentation on the exposed API. |
42 | | */ |
43 | | class MOZ_STACK_CLASS WebRenderScrollDataWrapper { |
44 | | public: |
45 | | // Basic constructor for external callers. Starts the walker at the root of |
46 | | // the tree. |
47 | | explicit WebRenderScrollDataWrapper(const APZUpdater& aUpdater, |
48 | | const WebRenderScrollData* aData = nullptr) |
49 | | : mUpdater(&aUpdater) |
50 | | , mData(aData) |
51 | | , mLayerIndex(0) |
52 | | , mContainingSubtreeLastIndex(0) |
53 | | , mLayer(nullptr) |
54 | | , mMetadataIndex(0) |
55 | 0 | { |
56 | 0 | if (!mData) { |
57 | 0 | return; |
58 | 0 | } |
59 | 0 | mLayer = mData->GetLayerData(mLayerIndex); |
60 | 0 | if (!mLayer) { |
61 | 0 | return; |
62 | 0 | } |
63 | 0 | |
64 | 0 | // sanity check on the data |
65 | 0 | MOZ_ASSERT(mData->GetLayerCount() == (size_t)(1 + mLayer->GetDescendantCount())); |
66 | 0 | mContainingSubtreeLastIndex = mData->GetLayerCount(); |
67 | 0 |
|
68 | 0 | // See documentation in LayerMetricsWrapper.h about this. mMetadataIndex |
69 | 0 | // in this class is equivalent to mIndex in that class. |
70 | 0 | mMetadataIndex = mLayer->GetScrollMetadataCount(); |
71 | 0 | if (mMetadataIndex > 0) { |
72 | 0 | mMetadataIndex--; |
73 | 0 | } |
74 | 0 | } |
75 | | |
76 | | private: |
77 | | // Internal constructor for walking from one WebRenderLayerScrollData to |
78 | | // another. In this case we need to recompute the mMetadataIndex to be the |
79 | | // "topmost" scroll metadata on the new layer. |
80 | | WebRenderScrollDataWrapper(const APZUpdater* aUpdater, |
81 | | const WebRenderScrollData* aData, |
82 | | size_t aLayerIndex, |
83 | | size_t aContainingSubtreeLastIndex) |
84 | | : mUpdater(aUpdater) |
85 | | , mData(aData) |
86 | | , mLayerIndex(aLayerIndex) |
87 | | , mContainingSubtreeLastIndex(aContainingSubtreeLastIndex) |
88 | | , mLayer(nullptr) |
89 | | , mMetadataIndex(0) |
90 | 0 | { |
91 | 0 | MOZ_ASSERT(mData); |
92 | 0 | mLayer = mData->GetLayerData(mLayerIndex); |
93 | 0 | MOZ_ASSERT(mLayer); |
94 | 0 |
|
95 | 0 | // See documentation in LayerMetricsWrapper.h about this. mMetadataIndex |
96 | 0 | // in this class is equivalent to mIndex in that class. |
97 | 0 | mMetadataIndex = mLayer->GetScrollMetadataCount(); |
98 | 0 | if (mMetadataIndex > 0) { |
99 | 0 | mMetadataIndex--; |
100 | 0 | } |
101 | 0 | } |
102 | | |
103 | | // Internal constructor for walking from one metadata to another metadata on |
104 | | // the same WebRenderLayerScrollData. |
105 | | WebRenderScrollDataWrapper(const APZUpdater* aUpdater, |
106 | | const WebRenderScrollData* aData, |
107 | | size_t aLayerIndex, |
108 | | size_t aContainingSubtreeLastIndex, |
109 | | const WebRenderLayerScrollData* aLayer, |
110 | | uint32_t aMetadataIndex) |
111 | | : mUpdater(aUpdater) |
112 | | , mData(aData) |
113 | | , mLayerIndex(aLayerIndex) |
114 | | , mContainingSubtreeLastIndex(aContainingSubtreeLastIndex) |
115 | | , mLayer(aLayer) |
116 | | , mMetadataIndex(aMetadataIndex) |
117 | 0 | { |
118 | 0 | MOZ_ASSERT(mData); |
119 | 0 | MOZ_ASSERT(mLayer); |
120 | 0 | MOZ_ASSERT(mLayer == mData->GetLayerData(mLayerIndex)); |
121 | 0 | MOZ_ASSERT(mMetadataIndex == 0 || mMetadataIndex < mLayer->GetScrollMetadataCount()); |
122 | 0 | } |
123 | | |
124 | | public: |
125 | | bool IsValid() const |
126 | 0 | { |
127 | 0 | return mLayer != nullptr; |
128 | 0 | } |
129 | | |
130 | | explicit operator bool() const |
131 | 0 | { |
132 | 0 | return IsValid(); |
133 | 0 | } |
134 | | |
135 | | WebRenderScrollDataWrapper GetLastChild() const |
136 | 0 | { |
137 | 0 | MOZ_ASSERT(IsValid()); |
138 | 0 |
|
139 | 0 | if (!AtBottomLayer()) { |
140 | 0 | // If we're still walking around in the virtual container layers created |
141 | 0 | // by the ScrollMetadata array, we just need to update the metadata index |
142 | 0 | // and that's it. |
143 | 0 | return WebRenderScrollDataWrapper(mUpdater, mData, mLayerIndex, |
144 | 0 | mContainingSubtreeLastIndex, mLayer, mMetadataIndex - 1); |
145 | 0 | } |
146 | 0 | |
147 | 0 | // Otherwise, we need to walk to a different WebRenderLayerScrollData in |
148 | 0 | // mData. |
149 | 0 | |
150 | 0 | // Since mData contains the layer in depth-first, last-to-first order, |
151 | 0 | // the index after mLayerIndex must be mLayerIndex's last child, if it |
152 | 0 | // has any children (indicated by GetDescendantCount() > 0). Furthermore |
153 | 0 | // we compute the first index outside the subtree rooted at this node |
154 | 0 | // (in |subtreeLastIndex|) and pass that in to the child wrapper to use as |
155 | 0 | // its mContainingSubtreeLastIndex. |
156 | 0 | if (mLayer->GetDescendantCount() > 0) { |
157 | 0 | size_t prevSiblingIndex = mLayerIndex + 1 + mLayer->GetDescendantCount(); |
158 | 0 | size_t subtreeLastIndex = std::min(mContainingSubtreeLastIndex, prevSiblingIndex); |
159 | 0 | return WebRenderScrollDataWrapper(mUpdater, mData, mLayerIndex + 1, subtreeLastIndex); |
160 | 0 | } |
161 | 0 | |
162 | 0 | // We've run out of descendants. But! If the original layer was a RefLayer, |
163 | 0 | // then it connects to another layer tree and we need to traverse that too. |
164 | 0 | // So return a WebRenderScrollDataWrapper for the root of the child layer |
165 | 0 | // tree. |
166 | 0 | if (mLayer->GetReferentId()) { |
167 | 0 | return WebRenderScrollDataWrapper(*mUpdater, |
168 | 0 | mUpdater->GetScrollData(*mLayer->GetReferentId())); |
169 | 0 | } |
170 | 0 | |
171 | 0 | return WebRenderScrollDataWrapper(*mUpdater); |
172 | 0 | } |
173 | | |
174 | | WebRenderScrollDataWrapper GetPrevSibling() const |
175 | 0 | { |
176 | 0 | MOZ_ASSERT(IsValid()); |
177 | 0 |
|
178 | 0 | if (!AtTopLayer()) { |
179 | 0 | // The virtual container layers don't have siblings |
180 | 0 | return WebRenderScrollDataWrapper(*mUpdater); |
181 | 0 | } |
182 | 0 | |
183 | 0 | // Skip past the descendants to get to the previous sibling. However, we |
184 | 0 | // might be at the last sibling already. |
185 | 0 | size_t prevSiblingIndex = mLayerIndex + 1 + mLayer->GetDescendantCount(); |
186 | 0 | if (prevSiblingIndex < mContainingSubtreeLastIndex) { |
187 | 0 | return WebRenderScrollDataWrapper(mUpdater, mData, prevSiblingIndex, mContainingSubtreeLastIndex); |
188 | 0 | } |
189 | 0 | return WebRenderScrollDataWrapper(*mUpdater); |
190 | 0 | } |
191 | | |
192 | | const ScrollMetadata& Metadata() const |
193 | 0 | { |
194 | 0 | MOZ_ASSERT(IsValid()); |
195 | 0 |
|
196 | 0 | if (mMetadataIndex >= mLayer->GetScrollMetadataCount()) { |
197 | 0 | return *ScrollMetadata::sNullMetadata; |
198 | 0 | } |
199 | 0 | return mLayer->GetScrollMetadata(*mData, mMetadataIndex); |
200 | 0 | } |
201 | | |
202 | | const FrameMetrics& Metrics() const |
203 | 0 | { |
204 | 0 | return Metadata().GetMetrics(); |
205 | 0 | } |
206 | | |
207 | | AsyncPanZoomController* GetApzc() const |
208 | 0 | { |
209 | 0 | return nullptr; |
210 | 0 | } |
211 | | |
212 | | void SetApzc(AsyncPanZoomController* aApzc) const |
213 | 0 | { |
214 | 0 | } |
215 | | |
216 | | const char* Name() const |
217 | 0 | { |
218 | 0 | return "WebRenderScrollDataWrapper"; |
219 | 0 | } |
220 | | |
221 | | gfx::Matrix4x4 GetTransform() const |
222 | 0 | { |
223 | 0 | MOZ_ASSERT(IsValid()); |
224 | 0 |
|
225 | 0 | // See WebRenderLayerScrollData::Initialize for more context. The ancestor |
226 | 0 | // transform is associated with the "topmost" layer, and the transform is |
227 | 0 | // associated with the "bottommost" layer. If there is only one |
228 | 0 | // scrollmetadata on the layer, then it is both "topmost" and "bottommost" |
229 | 0 | // and we combine the two transforms. |
230 | 0 |
|
231 | 0 | gfx::Matrix4x4 transform; |
232 | 0 | if (AtTopLayer()) { |
233 | 0 | transform = mLayer->GetAncestorTransform(); |
234 | 0 | } |
235 | 0 | if (AtBottomLayer()) { |
236 | 0 | transform = transform * mLayer->GetTransform(); |
237 | 0 | } |
238 | 0 | return transform; |
239 | 0 | } |
240 | | |
241 | | CSSTransformMatrix GetTransformTyped() const |
242 | 0 | { |
243 | 0 | return ViewAs<CSSTransformMatrix>(GetTransform()); |
244 | 0 | } |
245 | | |
246 | | bool TransformIsPerspective() const |
247 | 0 | { |
248 | 0 | MOZ_ASSERT(IsValid()); |
249 | 0 |
|
250 | 0 | if (AtBottomLayer()) { |
251 | 0 | return mLayer->GetTransformIsPerspective(); |
252 | 0 | } |
253 | 0 | return false; |
254 | 0 | } |
255 | | |
256 | | EventRegions GetEventRegions() const |
257 | 0 | { |
258 | 0 | MOZ_ASSERT(IsValid()); |
259 | 0 |
|
260 | 0 | if (AtBottomLayer()) { |
261 | 0 | return mLayer->GetEventRegions(); |
262 | 0 | } |
263 | 0 | return EventRegions(); |
264 | 0 | } |
265 | | |
266 | | LayerIntRegion GetVisibleRegion() const |
267 | 0 | { |
268 | 0 | MOZ_ASSERT(IsValid()); |
269 | 0 |
|
270 | 0 | if (AtBottomLayer()) { |
271 | 0 | return mLayer->GetVisibleRegion(); |
272 | 0 | } |
273 | 0 | |
274 | 0 | return ViewAs<LayerPixel>( |
275 | 0 | TransformBy(mLayer->GetTransformTyped(), mLayer->GetVisibleRegion()), |
276 | 0 | PixelCastJustification::MovingDownToChildren); |
277 | 0 | } |
278 | | |
279 | | Maybe<LayersId> GetReferentId() const |
280 | 0 | { |
281 | 0 | MOZ_ASSERT(IsValid()); |
282 | 0 |
|
283 | 0 | if (AtBottomLayer()) { |
284 | 0 | return mLayer->GetReferentId(); |
285 | 0 | } |
286 | 0 | return Nothing(); |
287 | 0 | } |
288 | | |
289 | | Maybe<ParentLayerIntRect> GetClipRect() const |
290 | 0 | { |
291 | 0 | // TODO |
292 | 0 | return Nothing(); |
293 | 0 | } |
294 | | |
295 | | EventRegionsOverride GetEventRegionsOverride() const |
296 | 0 | { |
297 | 0 | MOZ_ASSERT(IsValid()); |
298 | 0 | return mLayer->GetEventRegionsOverride(); |
299 | 0 | } |
300 | | |
301 | | const ScrollbarData& GetScrollbarData() const |
302 | 0 | { |
303 | 0 | MOZ_ASSERT(IsValid()); |
304 | 0 | return mLayer->GetScrollbarData(); |
305 | 0 | } |
306 | | |
307 | | uint64_t GetScrollbarAnimationId() const |
308 | 0 | { |
309 | 0 | MOZ_ASSERT(IsValid()); |
310 | 0 | return mLayer->GetScrollbarAnimationId(); |
311 | 0 | } |
312 | | |
313 | | FrameMetrics::ViewID GetFixedPositionScrollContainerId() const |
314 | 0 | { |
315 | 0 | MOZ_ASSERT(IsValid()); |
316 | 0 | return mLayer->GetFixedPositionScrollContainerId(); |
317 | 0 | } |
318 | | |
319 | | bool IsBackfaceHidden() const |
320 | 0 | { |
321 | 0 | // This is only used by APZCTM hit testing, and WR does its own |
322 | 0 | // hit testing, so no need to implement this. |
323 | 0 | return false; |
324 | 0 | } |
325 | | |
326 | | const void* GetLayer() const |
327 | 0 | { |
328 | 0 | MOZ_ASSERT(IsValid()); |
329 | 0 | return mLayer; |
330 | 0 | } |
331 | | |
332 | | private: |
333 | | bool AtBottomLayer() const |
334 | 0 | { |
335 | 0 | return mMetadataIndex == 0; |
336 | 0 | } |
337 | | |
338 | | bool AtTopLayer() const |
339 | 0 | { |
340 | 0 | return mLayer->GetScrollMetadataCount() == 0 || mMetadataIndex == mLayer->GetScrollMetadataCount() - 1; |
341 | 0 | } |
342 | | |
343 | | private: |
344 | | const APZUpdater* mUpdater; |
345 | | const WebRenderScrollData* mData; |
346 | | // The index (in mData->mLayerScrollData) of the WebRenderLayerScrollData this |
347 | | // wrapper is pointing to. |
348 | | size_t mLayerIndex; |
349 | | // The upper bound on the set of valid indices inside the subtree rooted at |
350 | | // the parent of this "layer". That is, any layer index |i| in the range |
351 | | // mLayerIndex <= i < mContainingSubtreeLastIndex is guaranteed to point to |
352 | | // a layer that is a descendant of "parent", where "parent" is the parent |
353 | | // layer of the layer at mLayerIndex. This is needed in order to implement |
354 | | // GetPrevSibling() correctly. |
355 | | size_t mContainingSubtreeLastIndex; |
356 | | // The WebRenderLayerScrollData this wrapper is pointing to. |
357 | | const WebRenderLayerScrollData* mLayer; |
358 | | // The index of the scroll metadata within mLayer that this wrapper is |
359 | | // pointing to. |
360 | | uint32_t mMetadataIndex; |
361 | | }; |
362 | | |
363 | | } // namespace layers |
364 | | } // namespace mozilla |
365 | | |
366 | | #endif /* GFX_WEBRENDERSCROLLDATAWRAPPER_H */ |