|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * vim: sw=2 ts=8 et : |
|
3 */ |
|
4 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
7 |
|
8 #ifndef mozilla_layers_ShadowLayers_h |
|
9 #define mozilla_layers_ShadowLayers_h 1 |
|
10 |
|
11 #include <stddef.h> // for size_t |
|
12 #include <stdint.h> // for uint64_t |
|
13 #include "gfxTypes.h" |
|
14 #include "mozilla/Attributes.h" // for MOZ_OVERRIDE |
|
15 #include "mozilla/WidgetUtils.h" // for ScreenRotation |
|
16 #include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation |
|
17 #include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc |
|
18 #include "mozilla/layers/CompositableForwarder.h" |
|
19 #include "mozilla/layers/CompositorTypes.h" // for OpenMode, etc |
|
20 #include "nsCOMPtr.h" // for already_AddRefed |
|
21 #include "nsRegion.h" // for nsIntRegion |
|
22 #include "nsTArrayForwardDeclare.h" // for InfallibleTArray |
|
23 |
|
24 struct nsIntPoint; |
|
25 struct nsIntRect; |
|
26 |
|
27 namespace mozilla { |
|
28 namespace layers { |
|
29 |
|
30 class ClientTiledLayerBuffer; |
|
31 class CanvasClient; |
|
32 class CanvasLayerComposite; |
|
33 class CanvasSurface; |
|
34 class ColorLayerComposite; |
|
35 class CompositableChild; |
|
36 class ContainerLayerComposite; |
|
37 class ContentClient; |
|
38 class ContentClientRemote; |
|
39 class EditReply; |
|
40 class ImageClient; |
|
41 class ImageLayerComposite; |
|
42 class Layer; |
|
43 class OptionalThebesBuffer; |
|
44 class PLayerChild; |
|
45 class PLayerTransactionChild; |
|
46 class PLayerTransactionParent; |
|
47 class LayerTransactionChild; |
|
48 class RefLayerComposite; |
|
49 class ShadowableLayer; |
|
50 class ShmemTextureClient; |
|
51 class SurfaceDescriptor; |
|
52 class TextureClient; |
|
53 class ThebesLayerComposite; |
|
54 class ThebesBuffer; |
|
55 class ThebesBufferData; |
|
56 class TiledLayerComposer; |
|
57 class Transaction; |
|
58 |
|
59 |
|
60 /** |
|
61 * We want to share layer trees across thread contexts and address |
|
62 * spaces for several reasons; chief among them |
|
63 * |
|
64 * - a parent process can paint a child process's layer tree while |
|
65 * the child process is blocked, say on content script. This is |
|
66 * important on mobile devices where UI responsiveness is key. |
|
67 * |
|
68 * - a dedicated "compositor" process can asynchronously (wrt the |
|
69 * browser process) composite and animate layer trees, allowing a |
|
70 * form of pipeline parallelism between compositor/browser/content |
|
71 * |
|
72 * - a dedicated "compositor" process can take all responsibility for |
|
73 * accessing the GPU, which is desirable on systems with |
|
74 * buggy/leaky drivers because the compositor process can die while |
|
75 * browser and content live on (and failover mechanisms can be |
|
76 * installed to quickly bring up a replacement compositor) |
|
77 * |
|
78 * The Layers model has a crisply defined API, which makes it easy to |
|
79 * safely "share" layer trees. The ShadowLayers API extends Layers to |
|
80 * allow a remote, parent process to access a child process's layer |
|
81 * tree. |
|
82 * |
|
83 * ShadowLayerForwarder publishes a child context's layer tree to a |
|
84 * parent context. This comprises recording layer-tree modifications |
|
85 * into atomic transactions and pushing them over IPC. |
|
86 * |
|
87 * LayerManagerComposite grafts layer subtrees published by child-context |
|
88 * ShadowLayerForwarder(s) into a parent-context layer tree. |
|
89 * |
|
90 * (Advanced note: because our process tree may have a height >2, a |
|
91 * non-leaf subprocess may both receive updates from child processes |
|
92 * and publish them to parent processes. Put another way, |
|
93 * LayerManagers may be both LayerManagerComposites and |
|
94 * ShadowLayerForwarders.) |
|
95 * |
|
96 * There are only shadow types for layers that have different shadow |
|
97 * vs. not-shadow behavior. ColorLayers and ContainerLayers behave |
|
98 * the same way in both regimes (so far). |
|
99 * |
|
100 * |
|
101 * The mecanism to shadow the layer tree on the compositor through IPC works as |
|
102 * follows: |
|
103 * The layer tree is managed on the content thread, and shadowed in the compositor |
|
104 * thread. The shadow layer tree is only kept in sync with whatever happens in |
|
105 * the content thread. To do this we use IPDL protocols. IPDL is a domain |
|
106 * specific language that describes how two processes or thread should |
|
107 * communicate. C++ code is generated from .ipdl files to implement the message |
|
108 * passing, synchronization and serialization logic. To use the generated code |
|
109 * we implement classes that inherit the generated IPDL actor. the ipdl actors |
|
110 * of a protocol PX are PXChild or PXParent (the generated class), and we |
|
111 * conventionally implement XChild and XParent. The Parent side of the protocol |
|
112 * is the one that lives on the compositor thread. Think of IPDL actors as |
|
113 * endpoints of communication. they are useful to send messages and also to |
|
114 * dispatch the message to the right actor on the other side. One nice property |
|
115 * of an IPDL actor is that when an actor, say PXChild is sent in a message, the |
|
116 * PXParent comes out in the other side. we use this property a lot to dispatch |
|
117 * messages to the right layers and compositable, each of which have their own |
|
118 * ipdl actor on both side. |
|
119 * |
|
120 * Most of the synchronization logic happens in layer transactions and |
|
121 * compositable transactions. |
|
122 * A transaction is a set of changes to the layers and/or the compositables |
|
123 * that are sent and applied together to the compositor thread to keep the |
|
124 * LayerComposite in a coherent state. |
|
125 * Layer transactions maintain the shape of the shadow layer tree, and |
|
126 * synchronize the texture data held by compositables. Layer transactions |
|
127 * are always between the content thread and the compositor thread. |
|
128 * Compositable transactions are subset of a layer transaction with which only |
|
129 * compositables and textures can be manipulated, and does not always originate |
|
130 * from the content thread. (See CompositableForwarder.h and ImageBridgeChild.h) |
|
131 */ |
|
132 |
|
133 class ShadowLayerForwarder : public CompositableForwarder |
|
134 { |
|
135 friend class ContentClientIncremental; |
|
136 friend class ClientLayerManager; |
|
137 |
|
138 public: |
|
139 virtual ~ShadowLayerForwarder(); |
|
140 |
|
141 /** |
|
142 * Setup the IPDL actor for aCompositable to be part of layers |
|
143 * transactions. |
|
144 */ |
|
145 void Connect(CompositableClient* aCompositable); |
|
146 |
|
147 virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData, |
|
148 TextureFlags aFlags) MOZ_OVERRIDE; |
|
149 |
|
150 virtual void CreatedIncrementalBuffer(CompositableClient* aCompositable, |
|
151 const TextureInfo& aTextureInfo, |
|
152 const nsIntRect& aBufferRect) MOZ_OVERRIDE; |
|
153 |
|
154 /** |
|
155 * Adds an edit in the layers transaction in order to attach |
|
156 * the corresponding compositable and layer on the compositor side. |
|
157 * Connect must have been called on aCompositable beforehand. |
|
158 */ |
|
159 void Attach(CompositableClient* aCompositable, |
|
160 ShadowableLayer* aLayer); |
|
161 |
|
162 /** |
|
163 * Adds an edit in the transaction in order to attach a Compositable that |
|
164 * is not managed by this ShadowLayerForwarder (for example, by ImageBridge |
|
165 * in the case of async-video). |
|
166 * Since the compositable is not managed by this forwarder, we can't use |
|
167 * the compositable or it's IPDL actor here, so we use an ID instead, that |
|
168 * is matched on the compositor side. |
|
169 */ |
|
170 void AttachAsyncCompositable(uint64_t aCompositableID, |
|
171 ShadowableLayer* aLayer); |
|
172 |
|
173 /** |
|
174 * Begin recording a transaction to be forwarded atomically to a |
|
175 * LayerManagerComposite. |
|
176 */ |
|
177 void BeginTransaction(const nsIntRect& aTargetBounds, |
|
178 ScreenRotation aRotation, |
|
179 const nsIntRect& aClientBounds, |
|
180 mozilla::dom::ScreenOrientation aOrientation); |
|
181 |
|
182 /** |
|
183 * The following methods may only be called after BeginTransaction() |
|
184 * but before EndTransaction(). They mirror the LayerManager |
|
185 * interface in Layers.h. |
|
186 */ |
|
187 |
|
188 /** |
|
189 * Notify the shadow manager that a new, "real" layer has been |
|
190 * created, and a corresponding shadow layer should be created in |
|
191 * the compositing process. |
|
192 */ |
|
193 void CreatedThebesLayer(ShadowableLayer* aThebes); |
|
194 void CreatedContainerLayer(ShadowableLayer* aContainer); |
|
195 void CreatedImageLayer(ShadowableLayer* aImage); |
|
196 void CreatedColorLayer(ShadowableLayer* aColor); |
|
197 void CreatedCanvasLayer(ShadowableLayer* aCanvas); |
|
198 void CreatedRefLayer(ShadowableLayer* aRef); |
|
199 |
|
200 /** |
|
201 * At least one attribute of |aMutant| has changed, and |aMutant| |
|
202 * needs to sync to its shadow layer. This initial implementation |
|
203 * forwards all attributes when any is mutated. |
|
204 */ |
|
205 void Mutated(ShadowableLayer* aMutant); |
|
206 |
|
207 void SetRoot(ShadowableLayer* aRoot); |
|
208 /** |
|
209 * Insert |aChild| after |aAfter| in |aContainer|. |aAfter| can be |
|
210 * nullptr to indicated that |aChild| should be appended to the end of |
|
211 * |aContainer|'s child list. |
|
212 */ |
|
213 void InsertAfter(ShadowableLayer* aContainer, |
|
214 ShadowableLayer* aChild, |
|
215 ShadowableLayer* aAfter = nullptr); |
|
216 void RemoveChild(ShadowableLayer* aContainer, |
|
217 ShadowableLayer* aChild); |
|
218 void RepositionChild(ShadowableLayer* aContainer, |
|
219 ShadowableLayer* aChild, |
|
220 ShadowableLayer* aAfter = nullptr); |
|
221 |
|
222 /** |
|
223 * Set aMaskLayer as the mask on aLayer. |
|
224 * Note that only image layers are properly supported |
|
225 * LayerTransactionParent::UpdateMask and accompanying ipdl |
|
226 * will need changing to update properties for other kinds |
|
227 * of mask layer. |
|
228 */ |
|
229 void SetMask(ShadowableLayer* aLayer, |
|
230 ShadowableLayer* aMaskLayer); |
|
231 |
|
232 /** |
|
233 * See CompositableForwarder::UseTiledLayerBuffer |
|
234 */ |
|
235 virtual void UseTiledLayerBuffer(CompositableClient* aCompositable, |
|
236 const SurfaceDescriptorTiles& aTileLayerDescriptor) MOZ_OVERRIDE; |
|
237 |
|
238 /** |
|
239 * Notify the compositor that a compositable will be updated asynchronously |
|
240 * through ImageBridge, using an ID to connect the protocols on the |
|
241 * compositor side. |
|
242 */ |
|
243 void AttachAsyncCompositable(PLayerTransactionChild* aLayer, uint64_t aID); |
|
244 |
|
245 virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable, |
|
246 TextureClient* aTexture) MOZ_OVERRIDE; |
|
247 |
|
248 virtual void RemoveTexture(TextureClient* aTexture) MOZ_OVERRIDE; |
|
249 |
|
250 /** |
|
251 * Communicate to the compositor that aRegion in the texture identified by aLayer |
|
252 * and aIdentifier has been updated to aThebesBuffer. |
|
253 */ |
|
254 virtual void UpdateTextureRegion(CompositableClient* aCompositable, |
|
255 const ThebesBufferData& aThebesBufferData, |
|
256 const nsIntRegion& aUpdatedRegion) MOZ_OVERRIDE; |
|
257 |
|
258 virtual void UpdateTextureIncremental(CompositableClient* aCompositable, |
|
259 TextureIdentifier aTextureId, |
|
260 SurfaceDescriptor& aDescriptor, |
|
261 const nsIntRegion& aUpdatedRegion, |
|
262 const nsIntRect& aBufferRect, |
|
263 const nsIntPoint& aBufferRotation) MOZ_OVERRIDE; |
|
264 |
|
265 /** |
|
266 * Communicate the picture rect of an image to the compositor |
|
267 */ |
|
268 void UpdatePictureRect(CompositableClient* aCompositable, |
|
269 const nsIntRect& aRect); |
|
270 |
|
271 /** |
|
272 * See CompositableForwarder::UpdatedTexture |
|
273 */ |
|
274 virtual void UpdatedTexture(CompositableClient* aCompositable, |
|
275 TextureClient* aTexture, |
|
276 nsIntRegion* aRegion) MOZ_OVERRIDE; |
|
277 |
|
278 /** |
|
279 * See CompositableForwarder::UseTexture |
|
280 */ |
|
281 virtual void UseTexture(CompositableClient* aCompositable, |
|
282 TextureClient* aClient) MOZ_OVERRIDE; |
|
283 virtual void UseComponentAlphaTextures(CompositableClient* aCompositable, |
|
284 TextureClient* aClientOnBlack, |
|
285 TextureClient* aClientOnWhite) MOZ_OVERRIDE; |
|
286 |
|
287 /** |
|
288 * End the current transaction and forward it to LayerManagerComposite. |
|
289 * |aReplies| are directions from the LayerManagerComposite to the |
|
290 * caller of EndTransaction(). |
|
291 */ |
|
292 bool EndTransaction(InfallibleTArray<EditReply>* aReplies, |
|
293 const nsIntRegion& aRegionToClear, |
|
294 bool aScheduleComposite, |
|
295 bool* aSent); |
|
296 |
|
297 /** |
|
298 * Set an actor through which layer updates will be pushed. |
|
299 */ |
|
300 void SetShadowManager(PLayerTransactionChild* aShadowManager); |
|
301 |
|
302 /** |
|
303 * True if this is forwarding to a LayerManagerComposite. |
|
304 */ |
|
305 bool HasShadowManager() const { return !!mShadowManager; } |
|
306 LayerTransactionChild* GetShadowManager() const { return mShadowManager.get(); } |
|
307 |
|
308 virtual void WindowOverlayChanged() { mWindowOverlayChanged = true; } |
|
309 |
|
310 /** |
|
311 * The following Alloc/Open/Destroy interfaces abstract over the |
|
312 * details of working with surfaces that are shared across |
|
313 * processes. They provide the glue between C++ Layers and the |
|
314 * LayerComposite IPC system. |
|
315 * |
|
316 * The basic lifecycle is |
|
317 * |
|
318 * - a Layer needs a buffer. Its ShadowableLayer subclass calls |
|
319 * AllocBuffer(), then calls one of the Created*Buffer() methods |
|
320 * above to transfer the (temporary) front buffer to its |
|
321 * LayerComposite in the other process. The Layer needs a |
|
322 * gfxASurface to paint, so the ShadowableLayer uses |
|
323 * OpenDescriptor(backBuffer) to get that surface, and hands it |
|
324 * out to the Layer. |
|
325 * |
|
326 * - a Layer has painted new pixels. Its ShadowableLayer calls one |
|
327 * of the Painted*Buffer() methods above with the back buffer |
|
328 * descriptor. This notification is forwarded to the LayerComposite, |
|
329 * which uses OpenDescriptor() to access the newly-painted pixels. |
|
330 * The LayerComposite then updates its front buffer in a Layer- and |
|
331 * platform-dependent way, and sends a surface descriptor back to |
|
332 * the ShadowableLayer that becomes its new back back buffer. |
|
333 * |
|
334 * - a Layer wants to destroy its buffers. Its ShadowableLayer |
|
335 * calls Destroyed*Buffer(), which gives up control of the back |
|
336 * buffer descriptor. The actual back buffer surface is then |
|
337 * destroyed using DestroySharedSurface() just before notifying |
|
338 * the parent process. When the parent process is notified, the |
|
339 * LayerComposite also calls DestroySharedSurface() on its front |
|
340 * buffer, and the double-buffer pair is gone. |
|
341 */ |
|
342 |
|
343 // ISurfaceAllocator |
|
344 virtual bool AllocUnsafeShmem(size_t aSize, |
|
345 mozilla::ipc::SharedMemory::SharedMemoryType aType, |
|
346 mozilla::ipc::Shmem* aShmem) MOZ_OVERRIDE; |
|
347 virtual bool AllocShmem(size_t aSize, |
|
348 mozilla::ipc::SharedMemory::SharedMemoryType aType, |
|
349 mozilla::ipc::Shmem* aShmem) MOZ_OVERRIDE; |
|
350 virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem) MOZ_OVERRIDE; |
|
351 |
|
352 virtual bool IPCOpen() const MOZ_OVERRIDE; |
|
353 virtual bool IsSameProcess() const MOZ_OVERRIDE; |
|
354 |
|
355 /** |
|
356 * Construct a shadow of |aLayer| on the "other side", at the |
|
357 * LayerManagerComposite. |
|
358 */ |
|
359 PLayerChild* ConstructShadowFor(ShadowableLayer* aLayer); |
|
360 |
|
361 /** |
|
362 * Flag the next paint as the first for a document. |
|
363 */ |
|
364 void SetIsFirstPaint() { mIsFirstPaint = true; } |
|
365 |
|
366 static void PlatformSyncBeforeUpdate(); |
|
367 |
|
368 protected: |
|
369 ShadowLayerForwarder(); |
|
370 |
|
371 #ifdef DEBUG |
|
372 void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const; |
|
373 #else |
|
374 void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const {} |
|
375 #endif |
|
376 |
|
377 RefPtr<LayerTransactionChild> mShadowManager; |
|
378 |
|
379 #ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC |
|
380 // from ISurfaceAllocator |
|
381 virtual PGrallocBufferChild* AllocGrallocBuffer(const gfx::IntSize& aSize, |
|
382 uint32_t aFormat, |
|
383 uint32_t aUsage, |
|
384 MaybeMagicGrallocBufferHandle* aHandle) MOZ_OVERRIDE; |
|
385 |
|
386 virtual void DeallocGrallocBuffer(PGrallocBufferChild* aChild) MOZ_OVERRIDE; |
|
387 #endif |
|
388 |
|
389 private: |
|
390 |
|
391 Transaction* mTxn; |
|
392 DiagnosticTypes mDiagnosticTypes; |
|
393 bool mIsFirstPaint; |
|
394 bool mWindowOverlayChanged; |
|
395 }; |
|
396 |
|
397 class CompositableClient; |
|
398 |
|
399 /** |
|
400 * A ShadowableLayer is a Layer can be shared with a parent context |
|
401 * through a ShadowLayerForwarder. A ShadowableLayer maps to a |
|
402 * Shadow*Layer in a parent context. |
|
403 * |
|
404 * Note that ShadowLayers can themselves be ShadowableLayers. |
|
405 */ |
|
406 class ShadowableLayer |
|
407 { |
|
408 public: |
|
409 virtual ~ShadowableLayer() {} |
|
410 |
|
411 virtual Layer* AsLayer() = 0; |
|
412 |
|
413 /** |
|
414 * True if this layer has a shadow in a parent process. |
|
415 */ |
|
416 bool HasShadow() { return !!mShadow; } |
|
417 |
|
418 /** |
|
419 * Return the IPC handle to a Shadow*Layer referring to this if one |
|
420 * exists, nullptr if not. |
|
421 */ |
|
422 PLayerChild* GetShadow() { return mShadow; } |
|
423 |
|
424 virtual CompositableClient* GetCompositableClient() { return nullptr; } |
|
425 protected: |
|
426 ShadowableLayer() : mShadow(nullptr) {} |
|
427 |
|
428 PLayerChild* mShadow; |
|
429 }; |
|
430 |
|
431 } // namespace layers |
|
432 } // namespace mozilla |
|
433 |
|
434 #endif // ifndef mozilla_layers_ShadowLayers_h |