Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/ipc/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
0
  bool HasShadowManager() const { return !!mShadowManager; }
287
  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
  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
0
  void SetIsFirstPaint() { mIsFirstPaint = true; }
340
341
  /**
342
   * Set the current focus target to be sent with the next paint.
343
   */
344
0
  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
  bool InForwarderThread() override {
370
    return NS_IsMainThread();
371
  }
372
373
0
  PaintTiming& GetPaintTiming() {
374
0
    return mPaintTiming;
375
0
  }
376
377
  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
  TextureForwarder* GetTextureForwarder() override { return GetCompositorBridgeChild(); }
385
  LayersIPCActor* GetLayersIPCActor() override { return this; }
386
387
  ActiveResourceTracker* GetActiveResourceTracker() override { return mActiveResourceTracker.get(); }
388
389
  CompositorBridgeChild* GetCompositorBridgeChild();
390
391
0
  nsIEventTarget* GetEventTarget() { return mEventTarget; };
392
393
  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
0
  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
0
  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
  const LayerHandle& GetShadow() { return mShadow; }
463
464
0
  void SetShadow(ShadowLayerForwarder* aForwarder, const LayerHandle& aShadow) {
465
0
    MOZ_ASSERT(!mShadow, "can't have two shadows (yet)");
466
0
    mForwarder = aForwarder;
467
0
    mShadow = aShadow;
468
0
  }
469
470
0
  virtual CompositableClient* GetCompositableClient() { return nullptr; }
471
472
protected:
473
0
  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