/work/obj-fuzz/dist/include/mozilla/layers/TiledContentClient.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 MOZILLA_GFX_TILEDCONTENTCLIENT_H |
8 | | #define MOZILLA_GFX_TILEDCONTENTCLIENT_H |
9 | | |
10 | | #include <stddef.h> // for size_t |
11 | | #include <stdint.h> // for uint16_t |
12 | | #include <algorithm> // for swap |
13 | | #include <limits> |
14 | | #include "Layers.h" // for LayerManager, etc |
15 | | #include "TiledLayerBuffer.h" // for TiledLayerBuffer |
16 | | #include "Units.h" // for CSSPoint |
17 | | #include "gfxTypes.h" |
18 | | #include "mozilla/Attributes.h" // for override |
19 | | #include "mozilla/gfx/2D.h" // for gfx::Tile |
20 | | #include "mozilla/RefPtr.h" // for RefPtr |
21 | | #include "mozilla/ipc/Shmem.h" // for Shmem |
22 | | #include "mozilla/ipc/SharedMemory.h" // for SharedMemory |
23 | | #include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform |
24 | | #include "mozilla/layers/CompositableClient.h" // for CompositableClient |
25 | | #include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc |
26 | | #include "mozilla/layers/LayersMessages.h" // for TileDescriptor |
27 | | #include "mozilla/layers/LayersTypes.h" // for TextureDumpMode |
28 | | #include "mozilla/layers/PaintThread.h" // for CapturedTiledPaintState |
29 | | #include "mozilla/layers/TextureClient.h" |
30 | | #include "mozilla/layers/TextureClientPool.h" |
31 | | #include "ClientLayerManager.h" |
32 | | #include "mozilla/mozalloc.h" // for operator delete |
33 | | #include "nsISupportsImpl.h" // for MOZ_COUNT_DTOR |
34 | | #include "nsPoint.h" // for nsIntPoint |
35 | | #include "nsRect.h" // for mozilla::gfx::IntRect |
36 | | #include "nsRegion.h" // for nsIntRegion |
37 | | #include "nsTArray.h" // for nsTArray, nsTArray_Impl, etc |
38 | | #include "nsExpirationTracker.h" |
39 | | #include "mozilla/layers/ISurfaceAllocator.h" |
40 | | |
41 | | namespace mozilla { |
42 | | namespace layers { |
43 | | |
44 | | class ClientTiledPaintedLayer; |
45 | | class ClientLayerManager; |
46 | | |
47 | | enum class TilePaintFlags : uint8_t { |
48 | | None = 0x0, |
49 | | Async = 0x1, |
50 | | Progressive = 0x2, |
51 | | }; |
52 | | MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(TilePaintFlags) |
53 | | |
54 | | struct AcquiredBackBuffer |
55 | | { |
56 | | AcquiredBackBuffer(gfx::DrawTarget* aTarget, |
57 | | gfx::DrawTargetCapture* aCapture, |
58 | | gfx::DrawTarget* aBackBuffer, |
59 | | const gfx::IntRect& aUpdatedRect, |
60 | | AutoTArray<RefPtr<TextureClient>, 4>&& aTextureClients) |
61 | | : mTarget(aTarget) |
62 | | , mCapture(aCapture) |
63 | | , mBackBuffer(aBackBuffer) |
64 | | , mUpdatedRect(aUpdatedRect) |
65 | | , mTextureClients(aTextureClients) |
66 | 0 | {} |
67 | | |
68 | | AcquiredBackBuffer(const AcquiredBackBuffer&) = delete; |
69 | | AcquiredBackBuffer& operator=(const AcquiredBackBuffer&) = delete; |
70 | | |
71 | 0 | AcquiredBackBuffer(AcquiredBackBuffer&&) = default; |
72 | 0 | AcquiredBackBuffer& operator=(AcquiredBackBuffer&&) = default; |
73 | | |
74 | | RefPtr<gfx::DrawTarget> mTarget; |
75 | | RefPtr<gfx::DrawTargetCapture> mCapture; |
76 | | RefPtr<gfx::DrawTarget> mBackBuffer; |
77 | | gfx::IntRect mUpdatedRect; |
78 | | AutoTArray<RefPtr<TextureClient>, 4> mTextureClients; |
79 | | }; |
80 | | |
81 | | /** |
82 | | * Represent a single tile in tiled buffer. The buffer keeps tiles, |
83 | | * each tile keeps a reference to a texture client and a read-lock. This |
84 | | * read-lock is used to help implement a copy-on-write mechanism. The tile |
85 | | * should be locked before being sent to the compositor. The compositor should |
86 | | * unlock the read-lock as soon as it has finished with the buffer in the |
87 | | * TextureHost to prevent more textures being created than is necessary. |
88 | | * Ideal place to store per tile debug information. |
89 | | */ |
90 | | struct TileClient |
91 | | { |
92 | | // Placeholder |
93 | | TileClient(); |
94 | | ~TileClient(); |
95 | | |
96 | | TileClient(const TileClient& o); |
97 | | |
98 | | TileClient& operator=(const TileClient& o); |
99 | | |
100 | | bool operator== (const TileClient& o) const |
101 | 0 | { |
102 | 0 | return mFrontBuffer == o.mFrontBuffer; |
103 | 0 | } |
104 | | |
105 | | bool operator!= (const TileClient& o) const |
106 | 0 | { |
107 | 0 | return mFrontBuffer != o.mFrontBuffer; |
108 | 0 | } |
109 | | |
110 | | void SetTextureAllocator(TextureClientAllocator* aAllocator) |
111 | 0 | { |
112 | 0 | mAllocator = aAllocator; |
113 | 0 | } |
114 | | |
115 | | bool IsPlaceholderTile() const |
116 | 0 | { |
117 | 0 | return mBackBuffer == nullptr && mFrontBuffer == nullptr; |
118 | 0 | } |
119 | | |
120 | | void DiscardBuffers() |
121 | 0 | { |
122 | 0 | DiscardFrontBuffer(); |
123 | 0 | DiscardBackBuffer(); |
124 | 0 | } |
125 | | |
126 | 0 | nsExpirationState *GetExpirationState() { return &mExpirationState; } |
127 | | |
128 | | TileDescriptor GetTileDescriptor(); |
129 | | |
130 | | /** |
131 | | * For debugging. |
132 | | */ |
133 | | void Dump(std::stringstream& aStream); |
134 | | |
135 | | /** |
136 | | * Swaps the front and back buffers. |
137 | | */ |
138 | | void Flip(); |
139 | | |
140 | 0 | void DumpTexture(std::stringstream& aStream, TextureDumpMode aCompress) { |
141 | 0 | // TODO We should combine the OnWhite/OnBlack here an just output a single image. |
142 | 0 | CompositableClient::DumpTextureClient(aStream, mFrontBuffer, aCompress); |
143 | 0 | } |
144 | | |
145 | | void GetSyncTextureSerials(SurfaceMode aMode, nsTArray<uint64_t>& aSerials); |
146 | | |
147 | | /** |
148 | | * Returns an unlocked TextureClient that can be used for writing new |
149 | | * data to the tile. This may flip the front-buffer to the back-buffer if |
150 | | * the front-buffer is still locked by the host, or does not have an |
151 | | * internal buffer (and so will always be locked). |
152 | | * |
153 | | * If getting the back buffer required copying pixels from the front buffer |
154 | | * then the copied region is stored in aAddPaintedRegion so the host side |
155 | | * knows to upload it. |
156 | | * |
157 | | * If nullptr is returned, aTextureClientOnWhite is undefined. |
158 | | */ |
159 | | Maybe<AcquiredBackBuffer> AcquireBackBuffer(CompositableClient&, |
160 | | const nsIntRegion& aDirtyRegion, |
161 | | const nsIntRegion& aVisibleRegion, |
162 | | gfxContentType aContent, |
163 | | SurfaceMode aMode, |
164 | | TilePaintFlags aFlags); |
165 | | |
166 | | void DiscardFrontBuffer(); |
167 | | |
168 | | void DiscardBackBuffer(); |
169 | | |
170 | | /* We wrap the back buffer in a class that disallows assignment |
171 | | * so that we can track when ever it changes so that we can update |
172 | | * the expiry tracker for expiring the back buffers */ |
173 | | class PrivateProtector { |
174 | | public: |
175 | | void Set(TileClient * container, RefPtr<TextureClient>); |
176 | | void Set(TileClient * container, TextureClient*); |
177 | | // Implicitly convert to TextureClient* because we can't chain |
178 | | // implicit conversion that would happen on RefPtr<TextureClient> |
179 | 0 | operator TextureClient*() const { return mBuffer; } |
180 | 0 | RefPtr<TextureClient> operator ->() { return mBuffer; } |
181 | | private: |
182 | | PrivateProtector& operator=(const PrivateProtector &); |
183 | | RefPtr<TextureClient> mBuffer; |
184 | | } mBackBuffer; |
185 | | RefPtr<TextureClient> mBackBufferOnWhite; |
186 | | RefPtr<TextureClient> mFrontBuffer; |
187 | | RefPtr<TextureClient> mFrontBufferOnWhite; |
188 | | RefPtr<TextureClientAllocator> mAllocator; |
189 | | gfx::IntRect mUpdateRect; |
190 | | bool mWasPlaceholder; |
191 | | #ifdef GFX_TILEDLAYER_DEBUG_OVERLAY |
192 | | TimeStamp mLastUpdate; |
193 | | #endif |
194 | | nsIntRegion mInvalidFront; |
195 | | nsIntRegion mInvalidBack; |
196 | | nsExpirationState mExpirationState; |
197 | | private: |
198 | | /* |
199 | | * Copies dirty pixels from the front buffer into the back buffer, |
200 | | * and records the copied region in aAddPaintedRegion. |
201 | | */ |
202 | | void ValidateFromFront(const nsIntRegion& aDirtyRegion, |
203 | | const nsIntRegion& aVisibleRegion, |
204 | | gfx::DrawTarget* aBackBuffer, |
205 | | TilePaintFlags aFlags, |
206 | | gfx::IntRect* aCopiedRegion, |
207 | | AutoTArray<RefPtr<TextureClient>, 4>* aClients); |
208 | | }; |
209 | | |
210 | | /** |
211 | | * This struct stores all the data necessary to perform a paint so that it |
212 | | * doesn't need to be recalculated on every repeated transaction. |
213 | | */ |
214 | | struct BasicTiledLayerPaintData { |
215 | | /* |
216 | | * The scroll offset of the content from the nearest ancestor layer that |
217 | | * represents scrollable content with a display port set. |
218 | | */ |
219 | | ParentLayerPoint mScrollOffset; |
220 | | |
221 | | /* |
222 | | * The scroll offset of the content from the nearest ancestor layer that |
223 | | * represents scrollable content with a display port set, for the last |
224 | | * layer update transaction. |
225 | | */ |
226 | | ParentLayerPoint mLastScrollOffset; |
227 | | |
228 | | /* |
229 | | * The transform matrix to go from this layer's Layer units to |
230 | | * the scroll ancestor's ParentLayer units. The "scroll ancestor" is |
231 | | * the closest ancestor layer which scrolls, and is used to obtain |
232 | | * the composition bounds that are relevant for this layer. |
233 | | */ |
234 | | LayerToParentLayerMatrix4x4 mTransformToCompBounds; |
235 | | |
236 | | /* |
237 | | * The critical displayport of the content from the nearest ancestor layer |
238 | | * that represents scrollable content with a display port set. isNothing() |
239 | | * if a critical displayport is not set. |
240 | | */ |
241 | | Maybe<LayerIntRect> mCriticalDisplayPort; |
242 | | |
243 | | /* |
244 | | * The render resolution of the document that the content this layer |
245 | | * represents is in. |
246 | | */ |
247 | | CSSToParentLayerScale2D mResolution; |
248 | | |
249 | | /* |
250 | | * The composition bounds of the layer, in Layer coordinates. This is |
251 | | * used to make sure that tiled updates to regions that are visible to the |
252 | | * user are grouped coherently. |
253 | | */ |
254 | | LayerRect mCompositionBounds; |
255 | | |
256 | | /* |
257 | | * Low precision updates are always executed a tile at a time in repeated |
258 | | * transactions. This counter is set to 1 on the first transaction of a low |
259 | | * precision update, and incremented for each subsequent transaction. |
260 | | */ |
261 | | uint16_t mLowPrecisionPaintCount; |
262 | | |
263 | | /* |
264 | | * Whether this is the first time this layer is painting |
265 | | */ |
266 | | bool mFirstPaint : 1; |
267 | | |
268 | | /* |
269 | | * Whether there is further work to complete this paint. This is used to |
270 | | * determine whether or not to repeat the transaction when painting |
271 | | * progressively. |
272 | | */ |
273 | | bool mPaintFinished : 1; |
274 | | |
275 | | /* |
276 | | * Whether or not there is an async transform animation active |
277 | | */ |
278 | | bool mHasTransformAnimation : 1; |
279 | | |
280 | | /* |
281 | | * Initializes/clears data to prepare for paint action. |
282 | | */ |
283 | | void ResetPaintData(); |
284 | | }; |
285 | | |
286 | | class SharedFrameMetricsHelper |
287 | | { |
288 | | public: |
289 | | SharedFrameMetricsHelper(); |
290 | | ~SharedFrameMetricsHelper(); |
291 | | |
292 | | /** |
293 | | * This is called by the BasicTileLayer to determine if it is still interested |
294 | | * in the update of this display-port to continue. We can return true here |
295 | | * to abort the current update and continue with any subsequent ones. This |
296 | | * is useful for slow-to-render pages when the display-port starts lagging |
297 | | * behind enough that continuing to draw it is wasted effort. |
298 | | */ |
299 | | bool UpdateFromCompositorFrameMetrics(const LayerMetricsWrapper& aLayer, |
300 | | bool aHasPendingNewThebesContent, |
301 | | bool aLowPrecision, |
302 | | AsyncTransform& aViewTransform); |
303 | | |
304 | | /** |
305 | | * Determines if the compositor's upcoming composition bounds has fallen |
306 | | * outside of the contents display port. If it has then the compositor |
307 | | * will start to checker board. Checker boarding is when the compositor |
308 | | * tries to composite a tile and it is not available. Historically |
309 | | * a tile with a checker board pattern was used. Now a blank tile is used. |
310 | | */ |
311 | | bool AboutToCheckerboard(const FrameMetrics& aContentMetrics, |
312 | | const FrameMetrics& aCompositorMetrics); |
313 | | private: |
314 | | bool mLastProgressiveUpdateWasLowPrecision; |
315 | | bool mProgressiveUpdateWasInDanger; |
316 | | }; |
317 | | |
318 | | /** |
319 | | * Provide an instance of TiledLayerBuffer backed by drawable TextureClients. |
320 | | * This buffer provides an implementation of ValidateTile using a |
321 | | * thebes callback and can support painting using a single paint buffer. |
322 | | * Whether a single paint buffer is used is controlled by |
323 | | * gfxPrefs::PerTileDrawing(). |
324 | | */ |
325 | | class ClientTiledLayerBuffer |
326 | | { |
327 | | public: |
328 | | ClientTiledLayerBuffer(ClientTiledPaintedLayer& aPaintedLayer, |
329 | | CompositableClient& aCompositableClient) |
330 | | : mPaintedLayer(aPaintedLayer) |
331 | | , mCompositableClient(aCompositableClient) |
332 | | , mLastPaintContentType(gfxContentType::COLOR) |
333 | | , mLastPaintSurfaceMode(SurfaceMode::SURFACE_OPAQUE) |
334 | | , mWasLastPaintProgressive(false) |
335 | 0 | {} |
336 | | |
337 | | virtual void PaintThebes(const nsIntRegion& aNewValidRegion, |
338 | | const nsIntRegion& aPaintRegion, |
339 | | const nsIntRegion& aDirtyRegion, |
340 | | LayerManager::DrawPaintedLayerCallback aCallback, |
341 | | void* aCallbackData, |
342 | | TilePaintFlags aFlags) = 0; |
343 | | virtual void GetSyncTextureSerials(const nsIntRegion& aPaintRegion, |
344 | | const nsIntRegion& aDirtyRegion, |
345 | 0 | nsTArray<uint64_t>& aSerials) { return; } |
346 | | |
347 | | virtual bool SupportsProgressiveUpdate() = 0; |
348 | | virtual bool ProgressiveUpdate(const nsIntRegion& aValidRegion, |
349 | | const nsIntRegion& aInvalidRegion, |
350 | | const nsIntRegion& aOldValidRegion, |
351 | | nsIntRegion& aOutDrawnRegion, |
352 | | BasicTiledLayerPaintData* aPaintData, |
353 | | LayerManager::DrawPaintedLayerCallback aCallback, |
354 | | void* aCallbackData) = 0; |
355 | | virtual void ResetPaintedAndValidState() = 0; |
356 | | |
357 | | virtual const nsIntRegion& GetValidRegion() = 0; |
358 | | |
359 | | virtual bool IsLowPrecision() const = 0; |
360 | | |
361 | | virtual void Dump(std::stringstream& aStream, |
362 | | const char* aPrefix, |
363 | | bool aDumpHtml, |
364 | 0 | TextureDumpMode aCompress) {} |
365 | | |
366 | 0 | const CSSToParentLayerScale2D& GetFrameResolution() { return mFrameResolution; } |
367 | 0 | void SetFrameResolution(const CSSToParentLayerScale2D& aResolution) { mFrameResolution = aResolution; } |
368 | | |
369 | | bool HasFormatChanged() const; |
370 | | |
371 | | protected: |
372 | | void UnlockTile(TileClient& aTile); |
373 | | gfxContentType GetContentType(SurfaceMode* aMode = nullptr) const; |
374 | | |
375 | | ClientTiledPaintedLayer& mPaintedLayer; |
376 | | CompositableClient& mCompositableClient; |
377 | | |
378 | | gfxContentType mLastPaintContentType; |
379 | | SurfaceMode mLastPaintSurfaceMode; |
380 | | CSSToParentLayerScale2D mFrameResolution; |
381 | | |
382 | | bool mWasLastPaintProgressive; |
383 | | }; |
384 | | |
385 | | class TiledContentClient : public CompositableClient |
386 | | { |
387 | | public: |
388 | | TiledContentClient(ClientLayerManager* aManager, |
389 | | const char* aName = "") |
390 | | : CompositableClient(aManager->AsShadowForwarder()) |
391 | | , mName(aName) |
392 | 0 | {} |
393 | | |
394 | | protected: |
395 | | ~TiledContentClient() |
396 | 0 | {} |
397 | | |
398 | | public: |
399 | | virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix); |
400 | | |
401 | | virtual void Dump(std::stringstream& aStream, |
402 | | const char* aPrefix="", |
403 | | bool aDumpHtml=false, |
404 | | TextureDumpMode aCompress=TextureDumpMode::Compress) override; |
405 | | |
406 | | virtual TextureInfo GetTextureInfo() const override |
407 | 0 | { |
408 | 0 | return TextureInfo(CompositableType::CONTENT_TILED); |
409 | 0 | } |
410 | | |
411 | | |
412 | | virtual ClientTiledLayerBuffer* GetTiledBuffer() = 0; |
413 | | virtual ClientTiledLayerBuffer* GetLowPrecisionTiledBuffer() = 0; |
414 | | |
415 | | enum TiledBufferType { |
416 | | TILED_BUFFER, |
417 | | LOW_PRECISION_TILED_BUFFER |
418 | | }; |
419 | | virtual void UpdatedBuffer(TiledBufferType aType) = 0; |
420 | | |
421 | | private: |
422 | | const char* mName; |
423 | | }; |
424 | | |
425 | | } // namespace layers |
426 | | } // namespace mozilla |
427 | | |
428 | | #endif // MOZILLA_GFX_TILEDCONTENTCLIENT_H |