/work/obj-fuzz/dist/include/mozilla/layers/ShadowLayers.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_layers_ShadowLayers_h |
8 | | #define mozilla_layers_ShadowLayers_h 1 |
9 | | |
10 | | #include <stddef.h> // for size_t |
11 | | #include <stdint.h> // for uint64_t |
12 | | #include "gfxTypes.h" |
13 | | #include "mozilla/Attributes.h" // for override |
14 | | #include "mozilla/gfx/Rect.h" |
15 | | #include "mozilla/WidgetUtils.h" // for ScreenRotation |
16 | | #include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc |
17 | | #include "mozilla/HalScreenConfiguration.h" // for ScreenOrientation |
18 | | #include "mozilla/layers/CompositableForwarder.h" |
19 | | #include "mozilla/layers/FocusTarget.h" |
20 | | #include "mozilla/layers/LayersTypes.h" |
21 | | #include "mozilla/layers/TextureForwarder.h" |
22 | | #include "mozilla/layers/CompositorTypes.h" // for OpenMode, etc |
23 | | #include "mozilla/layers/CompositorBridgeChild.h" |
24 | | #include "nsCOMPtr.h" // for already_AddRefed |
25 | | #include "nsRegion.h" // for nsIntRegion |
26 | | #include "nsTArrayForwardDeclare.h" // for InfallibleTArray |
27 | | #include "nsIWidget.h" |
28 | | #include <vector> |
29 | | |
30 | | namespace mozilla { |
31 | | namespace layers { |
32 | | |
33 | | class ClientLayerManager; |
34 | | class CompositorBridgeChild; |
35 | | class FixedSizeSmallShmemSectionAllocator; |
36 | | class ImageContainer; |
37 | | class Layer; |
38 | | class PLayerTransactionChild; |
39 | | class LayerTransactionChild; |
40 | | class ShadowableLayer; |
41 | | class SurfaceDescriptor; |
42 | | class TextureClient; |
43 | | class ThebesBuffer; |
44 | | class ThebesBufferData; |
45 | | class Transaction; |
46 | | |
47 | | /** |
48 | | * We want to share layer trees across thread contexts and address |
49 | | * spaces for several reasons; chief among them |
50 | | * |
51 | | * - a parent process can paint a child process's layer tree while |
52 | | * the child process is blocked, say on content script. This is |
53 | | * important on mobile devices where UI responsiveness is key. |
54 | | * |
55 | | * - a dedicated "compositor" process can asynchronously (wrt the |
56 | | * browser process) composite and animate layer trees, allowing a |
57 | | * form of pipeline parallelism between compositor/browser/content |
58 | | * |
59 | | * - a dedicated "compositor" process can take all responsibility for |
60 | | * accessing the GPU, which is desirable on systems with |
61 | | * buggy/leaky drivers because the compositor process can die while |
62 | | * browser and content live on (and failover mechanisms can be |
63 | | * installed to quickly bring up a replacement compositor) |
64 | | * |
65 | | * The Layers model has a crisply defined API, which makes it easy to |
66 | | * safely "share" layer trees. The ShadowLayers API extends Layers to |
67 | | * allow a remote, parent process to access a child process's layer |
68 | | * tree. |
69 | | * |
70 | | * ShadowLayerForwarder publishes a child context's layer tree to a |
71 | | * parent context. This comprises recording layer-tree modifications |
72 | | * into atomic transactions and pushing them over IPC. |
73 | | * |
74 | | * LayerManagerComposite grafts layer subtrees published by child-context |
75 | | * ShadowLayerForwarder(s) into a parent-context layer tree. |
76 | | * |
77 | | * (Advanced note: because our process tree may have a height >2, a |
78 | | * non-leaf subprocess may both receive updates from child processes |
79 | | * and publish them to parent processes. Put another way, |
80 | | * LayerManagers may be both LayerManagerComposites and |
81 | | * ShadowLayerForwarders.) |
82 | | * |
83 | | * There are only shadow types for layers that have different shadow |
84 | | * vs. not-shadow behavior. ColorLayers and ContainerLayers behave |
85 | | * the same way in both regimes (so far). |
86 | | * |
87 | | * |
88 | | * The mecanism to shadow the layer tree on the compositor through IPC works as |
89 | | * follows: |
90 | | * The layer tree is managed on the content thread, and shadowed in the compositor |
91 | | * thread. The shadow layer tree is only kept in sync with whatever happens in |
92 | | * the content thread. To do this we use IPDL protocols. IPDL is a domain |
93 | | * specific language that describes how two processes or thread should |
94 | | * communicate. C++ code is generated from .ipdl files to implement the message |
95 | | * passing, synchronization and serialization logic. To use the generated code |
96 | | * we implement classes that inherit the generated IPDL actor. the ipdl actors |
97 | | * of a protocol PX are PXChild or PXParent (the generated class), and we |
98 | | * conventionally implement XChild and XParent. The Parent side of the protocol |
99 | | * is the one that lives on the compositor thread. Think of IPDL actors as |
100 | | * endpoints of communication. they are useful to send messages and also to |
101 | | * dispatch the message to the right actor on the other side. One nice property |
102 | | * of an IPDL actor is that when an actor, say PXChild is sent in a message, the |
103 | | * PXParent comes out in the other side. we use this property a lot to dispatch |
104 | | * messages to the right layers and compositable, each of which have their own |
105 | | * ipdl actor on both side. |
106 | | * |
107 | | * Most of the synchronization logic happens in layer transactions and |
108 | | * compositable transactions. |
109 | | * A transaction is a set of changes to the layers and/or the compositables |
110 | | * that are sent and applied together to the compositor thread to keep the |
111 | | * LayerComposite in a coherent state. |
112 | | * Layer transactions maintain the shape of the shadow layer tree, and |
113 | | * synchronize the texture data held by compositables. Layer transactions |
114 | | * are always between the content thread and the compositor thread. |
115 | | * Compositable transactions are subset of a layer transaction with which only |
116 | | * compositables and textures can be manipulated, and does not always originate |
117 | | * from the content thread. (See CompositableForwarder.h and ImageBridgeChild.h) |
118 | | */ |
119 | | |
120 | | class ShadowLayerForwarder final : public LayersIPCActor |
121 | | , public CompositableForwarder |
122 | | , public LegacySurfaceDescriptorAllocator |
123 | | { |
124 | | friend class ClientLayerManager; |
125 | | |
126 | | public: |
127 | | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ShadowLayerForwarder, override); |
128 | | |
129 | | /** |
130 | | * Setup the IPDL actor for aCompositable to be part of layers |
131 | | * transactions. |
132 | | */ |
133 | | void Connect(CompositableClient* aCompositable, |
134 | | ImageContainer* aImageContainer) override; |
135 | | |
136 | | /** |
137 | | * Adds an edit in the layers transaction in order to attach |
138 | | * the corresponding compositable and layer on the compositor side. |
139 | | * Connect must have been called on aCompositable beforehand. |
140 | | */ |
141 | | void Attach(CompositableClient* aCompositable, |
142 | | ShadowableLayer* aLayer); |
143 | | |
144 | | /** |
145 | | * Adds an edit in the transaction in order to attach a Compositable that |
146 | | * is not managed by this ShadowLayerForwarder (for example, by ImageBridge |
147 | | * in the case of async-video). |
148 | | * Since the compositable is not managed by this forwarder, we can't use |
149 | | * the compositable or it's IPDL actor here, so we use an ID instead, that |
150 | | * is matched on the compositor side. |
151 | | */ |
152 | | void AttachAsyncCompositable(const CompositableHandle& aHandle, |
153 | | ShadowableLayer* aLayer); |
154 | | |
155 | | /** |
156 | | * Begin recording a transaction to be forwarded atomically to a |
157 | | * LayerManagerComposite. |
158 | | */ |
159 | | void BeginTransaction(const gfx::IntRect& aTargetBounds, |
160 | | ScreenRotation aRotation, |
161 | | hal::ScreenOrientation aOrientation); |
162 | | |
163 | | /** |
164 | | * The following methods may only be called after BeginTransaction() |
165 | | * but before EndTransaction(). They mirror the LayerManager |
166 | | * interface in Layers.h. |
167 | | */ |
168 | | |
169 | | /** |
170 | | * Notify the shadow manager that a new, "real" layer has been |
171 | | * created, and a corresponding shadow layer should be created in |
172 | | * the compositing process. |
173 | | */ |
174 | | void CreatedPaintedLayer(ShadowableLayer* aThebes); |
175 | | void CreatedContainerLayer(ShadowableLayer* aContainer); |
176 | | void CreatedImageLayer(ShadowableLayer* aImage); |
177 | | void CreatedColorLayer(ShadowableLayer* aColor); |
178 | | void CreatedCanvasLayer(ShadowableLayer* aCanvas); |
179 | | void CreatedRefLayer(ShadowableLayer* aRef); |
180 | | |
181 | | /** |
182 | | * At least one attribute of |aMutant| has changed, and |aMutant| |
183 | | * needs to sync to its shadow layer. This initial implementation |
184 | | * forwards all attributes when any of the appropriate attribute |
185 | | * set is mutated. |
186 | | */ |
187 | | void Mutated(ShadowableLayer* aMutant); |
188 | | void MutatedSimple(ShadowableLayer* aMutant); |
189 | | |
190 | | void SetRoot(ShadowableLayer* aRoot); |
191 | | /** |
192 | | * Insert |aChild| after |aAfter| in |aContainer|. |aAfter| can be |
193 | | * nullptr to indicated that |aChild| should be appended to the end of |
194 | | * |aContainer|'s child list. |
195 | | */ |
196 | | void InsertAfter(ShadowableLayer* aContainer, |
197 | | ShadowableLayer* aChild, |
198 | | ShadowableLayer* aAfter = nullptr); |
199 | | void RemoveChild(ShadowableLayer* aContainer, |
200 | | ShadowableLayer* aChild); |
201 | | void RepositionChild(ShadowableLayer* aContainer, |
202 | | ShadowableLayer* aChild, |
203 | | ShadowableLayer* aAfter = nullptr); |
204 | | |
205 | | /** |
206 | | * Set aMaskLayer as the mask on aLayer. |
207 | | * Note that only image layers are properly supported |
208 | | * LayerTransactionParent::UpdateMask and accompanying ipdl |
209 | | * will need changing to update properties for other kinds |
210 | | * of mask layer. |
211 | | */ |
212 | | void SetMask(ShadowableLayer* aLayer, |
213 | | ShadowableLayer* aMaskLayer); |
214 | | |
215 | | /** |
216 | | * See CompositableForwarder::UseTiledLayerBuffer |
217 | | */ |
218 | | void UseTiledLayerBuffer(CompositableClient* aCompositable, |
219 | | const SurfaceDescriptorTiles& aTileLayerDescriptor) override; |
220 | | |
221 | | void ReleaseCompositable(const CompositableHandle& aHandle) override; |
222 | | bool DestroyInTransaction(PTextureChild* aTexture) override; |
223 | | bool DestroyInTransaction(const CompositableHandle& aHandle); |
224 | | |
225 | | virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable, |
226 | | TextureClient* aTexture) override; |
227 | | |
228 | | /** |
229 | | * Communicate to the compositor that aRegion in the texture identified by aLayer |
230 | | * and aIdentifier has been updated to aThebesBuffer. |
231 | | */ |
232 | | virtual void UpdateTextureRegion(CompositableClient* aCompositable, |
233 | | const ThebesBufferData& aThebesBufferData, |
234 | | const nsIntRegion& aUpdatedRegion) override; |
235 | | |
236 | | /** |
237 | | * See CompositableForwarder::UseTextures |
238 | | */ |
239 | | virtual void UseTextures(CompositableClient* aCompositable, |
240 | | const nsTArray<TimedTextureClient>& aTextures) override; |
241 | | virtual void UseComponentAlphaTextures(CompositableClient* aCompositable, |
242 | | TextureClient* aClientOnBlack, |
243 | | TextureClient* aClientOnWhite) override; |
244 | | |
245 | | /** |
246 | | * Used for debugging to tell the compositor how long this frame took to paint. |
247 | | */ |
248 | | void SendPaintTime(TransactionId aId, TimeDuration aPaintTime); |
249 | | |
250 | | /** |
251 | | * End the current transaction and forward it to LayerManagerComposite. |
252 | | * |aReplies| are directions from the LayerManagerComposite to the |
253 | | * caller of EndTransaction(). |
254 | | */ |
255 | | bool EndTransaction(const nsIntRegion& aRegionToClear, |
256 | | TransactionId aId, |
257 | | bool aScheduleComposite, |
258 | | uint32_t aPaintSequenceNumber, |
259 | | bool aIsRepeatTransaction, |
260 | | const mozilla::TimeStamp& aRefreshStart, |
261 | | const mozilla::TimeStamp& aTransactionStart, |
262 | | bool* aSent); |
263 | | |
264 | | /** |
265 | | * Set an actor through which layer updates will be pushed. |
266 | | */ |
267 | | void SetShadowManager(PLayerTransactionChild* aShadowManager); |
268 | | |
269 | | /** |
270 | | * Layout calls here to cache current plugin widget configuration |
271 | | * data. We ship this across with the rest of the layer updates when |
272 | | * we update. Chrome handles applying these changes. |
273 | | */ |
274 | | void StorePluginWidgetConfigurations(const nsTArray<nsIWidget::Configuration>& |
275 | | aConfigurations); |
276 | | |
277 | | void StopReceiveAsyncParentMessge(); |
278 | | |
279 | | void ClearCachedResources(); |
280 | | |
281 | | void ScheduleComposite(); |
282 | | |
283 | | /** |
284 | | * True if this is forwarding to a LayerManagerComposite. |
285 | | */ |
286 | | bool HasShadowManager() const { return !!mShadowManager; } |
287 | 0 | LayerTransactionChild* GetShadowManager() const { return mShadowManager.get(); } |
288 | | |
289 | | // Send a synchronous message asking the LayerTransactionParent in the |
290 | | // compositor to shutdown. |
291 | | void SynchronouslyShutdown(); |
292 | | |
293 | 0 | virtual void WindowOverlayChanged() { mWindowOverlayChanged = true; } |
294 | | |
295 | | /** |
296 | | * The following Alloc/Open/Destroy interfaces abstract over the |
297 | | * details of working with surfaces that are shared across |
298 | | * processes. They provide the glue between C++ Layers and the |
299 | | * LayerComposite IPC system. |
300 | | * |
301 | | * The basic lifecycle is |
302 | | * |
303 | | * - a Layer needs a buffer. Its ShadowableLayer subclass calls |
304 | | * AllocBuffer(), then calls one of the Created*Buffer() methods |
305 | | * above to transfer the (temporary) front buffer to its |
306 | | * LayerComposite in the other process. The Layer needs a |
307 | | * gfxASurface to paint, so the ShadowableLayer uses |
308 | | * OpenDescriptor(backBuffer) to get that surface, and hands it |
309 | | * out to the Layer. |
310 | | * |
311 | | * - a Layer has painted new pixels. Its ShadowableLayer calls one |
312 | | * of the Painted*Buffer() methods above with the back buffer |
313 | | * descriptor. This notification is forwarded to the LayerComposite, |
314 | | * which uses OpenDescriptor() to access the newly-painted pixels. |
315 | | * The LayerComposite then updates its front buffer in a Layer- and |
316 | | * platform-dependent way, and sends a surface descriptor back to |
317 | | * the ShadowableLayer that becomes its new back back buffer. |
318 | | * |
319 | | * - a Layer wants to destroy its buffers. Its ShadowableLayer |
320 | | * calls Destroyed*Buffer(), which gives up control of the back |
321 | | * buffer descriptor. The actual back buffer surface is then |
322 | | * destroyed using DestroySharedSurface() just before notifying |
323 | | * the parent process. When the parent process is notified, the |
324 | | * LayerComposite also calls DestroySharedSurface() on its front |
325 | | * buffer, and the double-buffer pair is gone. |
326 | | */ |
327 | | |
328 | | virtual bool IPCOpen() const override; |
329 | | |
330 | | /** |
331 | | * Construct a shadow of |aLayer| on the "other side", at the |
332 | | * LayerManagerComposite. |
333 | | */ |
334 | | LayerHandle ConstructShadowFor(ShadowableLayer* aLayer); |
335 | | |
336 | | /** |
337 | | * Flag the next paint as the first for a document. |
338 | | */ |
339 | | void SetIsFirstPaint() { mIsFirstPaint = true; } |
340 | | |
341 | | /** |
342 | | * Set the current focus target to be sent with the next paint. |
343 | | */ |
344 | | void SetFocusTarget(const FocusTarget& aFocusTarget) { mFocusTarget = aFocusTarget; } |
345 | | |
346 | | void SetLayersObserverEpoch(LayersObserverEpoch aEpoch); |
347 | | |
348 | | static void PlatformSyncBeforeUpdate(); |
349 | | |
350 | | virtual bool AllocSurfaceDescriptor(const gfx::IntSize& aSize, |
351 | | gfxContentType aContent, |
352 | | SurfaceDescriptor* aBuffer) override; |
353 | | |
354 | | virtual bool AllocSurfaceDescriptorWithCaps(const gfx::IntSize& aSize, |
355 | | gfxContentType aContent, |
356 | | uint32_t aCaps, |
357 | | SurfaceDescriptor* aBuffer) override; |
358 | | |
359 | | virtual void DestroySurfaceDescriptor(SurfaceDescriptor* aSurface) override; |
360 | | |
361 | | virtual void UpdateFwdTransactionId() override; |
362 | | virtual uint64_t GetFwdTransactionId() override; |
363 | | |
364 | | void UpdateTextureLocks(); |
365 | | void SyncTextures(const nsTArray<uint64_t>& aSerials); |
366 | | |
367 | | void ReleaseLayer(const LayerHandle& aHandle); |
368 | | |
369 | 0 | bool InForwarderThread() override { |
370 | 0 | return NS_IsMainThread(); |
371 | 0 | } |
372 | | |
373 | | PaintTiming& GetPaintTiming() { |
374 | | return mPaintTiming; |
375 | | } |
376 | | |
377 | 0 | ShadowLayerForwarder* AsLayerForwarder() override { return this; } |
378 | | |
379 | | // Returns true if aSurface wraps a Shmem. |
380 | | static bool IsShmem(SurfaceDescriptor* aSurface); |
381 | | |
382 | | void SyncWithCompositor() override; |
383 | | |
384 | 0 | TextureForwarder* GetTextureForwarder() override { return GetCompositorBridgeChild(); } |
385 | 0 | LayersIPCActor* GetLayersIPCActor() override { return this; } |
386 | | |
387 | 0 | ActiveResourceTracker* GetActiveResourceTracker() override { return mActiveResourceTracker.get(); } |
388 | | |
389 | | CompositorBridgeChild* GetCompositorBridgeChild(); |
390 | | |
391 | | nsIEventTarget* GetEventTarget() { return mEventTarget; }; |
392 | | |
393 | 0 | virtual bool IsThreadSafe() const override { return false; } |
394 | | |
395 | | virtual RefPtr<KnowsCompositor> GetForMedia() override; |
396 | | |
397 | | protected: |
398 | | virtual ~ShadowLayerForwarder(); |
399 | | |
400 | | explicit ShadowLayerForwarder(ClientLayerManager* aClientLayerManager); |
401 | | |
402 | | #ifdef DEBUG |
403 | | void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const; |
404 | | #else |
405 | | void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const {} |
406 | | #endif |
407 | | |
408 | | RefPtr<CompositableClient> FindCompositable(const CompositableHandle& aHandle); |
409 | | |
410 | | bool InWorkerThread(); |
411 | | |
412 | | RefPtr<LayerTransactionChild> mShadowManager; |
413 | | RefPtr<CompositorBridgeChild> mCompositorBridgeChild; |
414 | | |
415 | | private: |
416 | | |
417 | | ClientLayerManager* mClientLayerManager; |
418 | | Transaction* mTxn; |
419 | | MessageLoop* mMessageLoop; |
420 | | DiagnosticTypes mDiagnosticTypes; |
421 | | bool mIsFirstPaint; |
422 | | FocusTarget mFocusTarget; |
423 | | bool mWindowOverlayChanged; |
424 | | InfallibleTArray<PluginWindowData> mPluginWindowData; |
425 | | UniquePtr<ActiveResourceTracker> mActiveResourceTracker; |
426 | | uint64_t mNextLayerHandle; |
427 | | nsDataHashtable<nsUint64HashKey, CompositableClient*> mCompositables; |
428 | | PaintTiming mPaintTiming; |
429 | | /** |
430 | | * ShadowLayerForwarder might dispatch tasks to main while puppet widget and |
431 | | * tabChild don't exist anymore; therefore we hold the event target since its |
432 | | * lifecycle is independent of these objects. |
433 | | */ |
434 | | nsCOMPtr<nsIEventTarget> mEventTarget; |
435 | | }; |
436 | | |
437 | | class CompositableClient; |
438 | | |
439 | | /** |
440 | | * A ShadowableLayer is a Layer can be shared with a parent context |
441 | | * through a ShadowLayerForwarder. A ShadowableLayer maps to a |
442 | | * Shadow*Layer in a parent context. |
443 | | * |
444 | | * Note that ShadowLayers can themselves be ShadowableLayers. |
445 | | */ |
446 | | class ShadowableLayer |
447 | | { |
448 | | public: |
449 | | virtual ~ShadowableLayer(); |
450 | | |
451 | | virtual Layer* AsLayer() = 0; |
452 | | |
453 | | /** |
454 | | * True if this layer has a shadow in a parent process. |
455 | | */ |
456 | | bool HasShadow() { return mShadow.IsValid(); } |
457 | | |
458 | | /** |
459 | | * Return the IPC handle to a Shadow*Layer referring to this if one |
460 | | * exists, nullptr if not. |
461 | | */ |
462 | 0 | const LayerHandle& GetShadow() { return mShadow; } |
463 | | |
464 | | void SetShadow(ShadowLayerForwarder* aForwarder, const LayerHandle& aShadow) { |
465 | | MOZ_ASSERT(!mShadow, "can't have two shadows (yet)"); |
466 | | mForwarder = aForwarder; |
467 | | mShadow = aShadow; |
468 | | } |
469 | | |
470 | | virtual CompositableClient* GetCompositableClient() { return nullptr; } |
471 | | |
472 | | protected: |
473 | | ShadowableLayer() {} |
474 | | |
475 | | private: |
476 | | RefPtr<ShadowLayerForwarder> mForwarder; |
477 | | LayerHandle mShadow; |
478 | | }; |
479 | | |
480 | | } // namespace layers |
481 | | } // namespace mozilla |
482 | | |
483 | | #endif // ifndef mozilla_layers_ShadowLayers_h |