gfx/layers/ipc/ShadowLayers.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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

mercurial