Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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/. */
8 #ifndef mozilla_layers_ShadowLayers_h
9 #define mozilla_layers_ShadowLayers_h 1
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
24 struct nsIntPoint;
25 struct nsIntRect;
27 namespace mozilla {
28 namespace layers {
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;
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 */
133 class ShadowLayerForwarder : public CompositableForwarder
134 {
135 friend class ContentClientIncremental;
136 friend class ClientLayerManager;
138 public:
139 virtual ~ShadowLayerForwarder();
141 /**
142 * Setup the IPDL actor for aCompositable to be part of layers
143 * transactions.
144 */
145 void Connect(CompositableClient* aCompositable);
147 virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
148 TextureFlags aFlags) MOZ_OVERRIDE;
150 virtual void CreatedIncrementalBuffer(CompositableClient* aCompositable,
151 const TextureInfo& aTextureInfo,
152 const nsIntRect& aBufferRect) MOZ_OVERRIDE;
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);
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);
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);
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 */
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);
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);
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);
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);
232 /**
233 * See CompositableForwarder::UseTiledLayerBuffer
234 */
235 virtual void UseTiledLayerBuffer(CompositableClient* aCompositable,
236 const SurfaceDescriptorTiles& aTileLayerDescriptor) MOZ_OVERRIDE;
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);
245 virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable,
246 TextureClient* aTexture) MOZ_OVERRIDE;
248 virtual void RemoveTexture(TextureClient* aTexture) MOZ_OVERRIDE;
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;
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;
265 /**
266 * Communicate the picture rect of an image to the compositor
267 */
268 void UpdatePictureRect(CompositableClient* aCompositable,
269 const nsIntRect& aRect);
271 /**
272 * See CompositableForwarder::UpdatedTexture
273 */
274 virtual void UpdatedTexture(CompositableClient* aCompositable,
275 TextureClient* aTexture,
276 nsIntRegion* aRegion) MOZ_OVERRIDE;
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;
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);
297 /**
298 * Set an actor through which layer updates will be pushed.
299 */
300 void SetShadowManager(PLayerTransactionChild* aShadowManager);
302 /**
303 * True if this is forwarding to a LayerManagerComposite.
304 */
305 bool HasShadowManager() const { return !!mShadowManager; }
306 LayerTransactionChild* GetShadowManager() const { return mShadowManager.get(); }
308 virtual void WindowOverlayChanged() { mWindowOverlayChanged = true; }
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 */
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;
352 virtual bool IPCOpen() const MOZ_OVERRIDE;
353 virtual bool IsSameProcess() const MOZ_OVERRIDE;
355 /**
356 * Construct a shadow of |aLayer| on the "other side", at the
357 * LayerManagerComposite.
358 */
359 PLayerChild* ConstructShadowFor(ShadowableLayer* aLayer);
361 /**
362 * Flag the next paint as the first for a document.
363 */
364 void SetIsFirstPaint() { mIsFirstPaint = true; }
366 static void PlatformSyncBeforeUpdate();
368 protected:
369 ShadowLayerForwarder();
371 #ifdef DEBUG
372 void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const;
373 #else
374 void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const {}
375 #endif
377 RefPtr<LayerTransactionChild> mShadowManager;
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;
386 virtual void DeallocGrallocBuffer(PGrallocBufferChild* aChild) MOZ_OVERRIDE;
387 #endif
389 private:
391 Transaction* mTxn;
392 DiagnosticTypes mDiagnosticTypes;
393 bool mIsFirstPaint;
394 bool mWindowOverlayChanged;
395 };
397 class CompositableClient;
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() {}
411 virtual Layer* AsLayer() = 0;
413 /**
414 * True if this layer has a shadow in a parent process.
415 */
416 bool HasShadow() { return !!mShadow; }
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; }
424 virtual CompositableClient* GetCompositableClient() { return nullptr; }
425 protected:
426 ShadowableLayer() : mShadow(nullptr) {}
428 PLayerChild* mShadow;
429 };
431 } // namespace layers
432 } // namespace mozilla
434 #endif // ifndef mozilla_layers_ShadowLayers_h