gfx/layers/ipc/ShadowLayers.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/layers/ipc/ShadowLayers.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,434 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 + * vim: sw=2 ts=8 et :
     1.6 + */
     1.7 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    1.10 +
    1.11 +#ifndef mozilla_layers_ShadowLayers_h
    1.12 +#define mozilla_layers_ShadowLayers_h 1
    1.13 +
    1.14 +#include <stddef.h>                     // for size_t
    1.15 +#include <stdint.h>                     // for uint64_t
    1.16 +#include "gfxTypes.h"
    1.17 +#include "mozilla/Attributes.h"         // for MOZ_OVERRIDE
    1.18 +#include "mozilla/WidgetUtils.h"        // for ScreenRotation
    1.19 +#include "mozilla/dom/ScreenOrientation.h"  // for ScreenOrientation
    1.20 +#include "mozilla/ipc/SharedMemory.h"   // for SharedMemory, etc
    1.21 +#include "mozilla/layers/CompositableForwarder.h"
    1.22 +#include "mozilla/layers/CompositorTypes.h"  // for OpenMode, etc
    1.23 +#include "nsCOMPtr.h"                   // for already_AddRefed
    1.24 +#include "nsRegion.h"                   // for nsIntRegion
    1.25 +#include "nsTArrayForwardDeclare.h"     // for InfallibleTArray
    1.26 + 
    1.27 +struct nsIntPoint;
    1.28 +struct nsIntRect;
    1.29 +
    1.30 +namespace mozilla {
    1.31 +namespace layers {
    1.32 +
    1.33 +class ClientTiledLayerBuffer;
    1.34 +class CanvasClient;
    1.35 +class CanvasLayerComposite;
    1.36 +class CanvasSurface;
    1.37 +class ColorLayerComposite;
    1.38 +class CompositableChild;
    1.39 +class ContainerLayerComposite;
    1.40 +class ContentClient;
    1.41 +class ContentClientRemote;
    1.42 +class EditReply;
    1.43 +class ImageClient;
    1.44 +class ImageLayerComposite;
    1.45 +class Layer;
    1.46 +class OptionalThebesBuffer;
    1.47 +class PLayerChild;
    1.48 +class PLayerTransactionChild;
    1.49 +class PLayerTransactionParent;
    1.50 +class LayerTransactionChild;
    1.51 +class RefLayerComposite;
    1.52 +class ShadowableLayer;
    1.53 +class ShmemTextureClient;
    1.54 +class SurfaceDescriptor;
    1.55 +class TextureClient;
    1.56 +class ThebesLayerComposite;
    1.57 +class ThebesBuffer;
    1.58 +class ThebesBufferData;
    1.59 +class TiledLayerComposer;
    1.60 +class Transaction;
    1.61 +
    1.62 +
    1.63 +/**
    1.64 + * We want to share layer trees across thread contexts and address
    1.65 + * spaces for several reasons; chief among them
    1.66 + *
    1.67 + *  - a parent process can paint a child process's layer tree while
    1.68 + *    the child process is blocked, say on content script.  This is
    1.69 + *    important on mobile devices where UI responsiveness is key.
    1.70 + *
    1.71 + *  - a dedicated "compositor" process can asynchronously (wrt the
    1.72 + *    browser process) composite and animate layer trees, allowing a
    1.73 + *    form of pipeline parallelism between compositor/browser/content
    1.74 + *
    1.75 + *  - a dedicated "compositor" process can take all responsibility for
    1.76 + *    accessing the GPU, which is desirable on systems with
    1.77 + *    buggy/leaky drivers because the compositor process can die while
    1.78 + *    browser and content live on (and failover mechanisms can be
    1.79 + *    installed to quickly bring up a replacement compositor)
    1.80 + *
    1.81 + * The Layers model has a crisply defined API, which makes it easy to
    1.82 + * safely "share" layer trees.  The ShadowLayers API extends Layers to
    1.83 + * allow a remote, parent process to access a child process's layer
    1.84 + * tree.
    1.85 + *
    1.86 + * ShadowLayerForwarder publishes a child context's layer tree to a
    1.87 + * parent context.  This comprises recording layer-tree modifications
    1.88 + * into atomic transactions and pushing them over IPC.
    1.89 + *
    1.90 + * LayerManagerComposite grafts layer subtrees published by child-context
    1.91 + * ShadowLayerForwarder(s) into a parent-context layer tree.
    1.92 + *
    1.93 + * (Advanced note: because our process tree may have a height >2, a
    1.94 + * non-leaf subprocess may both receive updates from child processes
    1.95 + * and publish them to parent processes.  Put another way,
    1.96 + * LayerManagers may be both LayerManagerComposites and
    1.97 + * ShadowLayerForwarders.)
    1.98 + *
    1.99 + * There are only shadow types for layers that have different shadow
   1.100 + * vs. not-shadow behavior.  ColorLayers and ContainerLayers behave
   1.101 + * the same way in both regimes (so far).
   1.102 + *
   1.103 + *
   1.104 + * The mecanism to shadow the layer tree on the compositor through IPC works as
   1.105 + * follows:
   1.106 + * The layer tree is managed on the content thread, and shadowed in the compositor
   1.107 + * thread. The shadow layer tree is only kept in sync with whatever happens in
   1.108 + * the content thread. To do this we use IPDL protocols. IPDL is a domain
   1.109 + * specific language that describes how two processes or thread should
   1.110 + * communicate. C++ code is generated from .ipdl files to implement the message
   1.111 + * passing, synchronization and serialization logic. To use the generated code
   1.112 + * we implement classes that inherit the generated IPDL actor. the ipdl actors
   1.113 + * of a protocol PX are PXChild or PXParent (the generated class), and we
   1.114 + * conventionally implement XChild and XParent. The Parent side of the protocol
   1.115 + * is the one that lives on the compositor thread. Think of IPDL actors as
   1.116 + * endpoints of communication. they are useful to send messages and also to
   1.117 + * dispatch the message to the right actor on the other side. One nice property
   1.118 + * of an IPDL actor is that when an actor, say PXChild is sent in a message, the
   1.119 + * PXParent comes out in the other side. we use this property a lot to dispatch
   1.120 + * messages to the right layers and compositable, each of which have their own
   1.121 + * ipdl actor on both side.
   1.122 + *
   1.123 + * Most of the synchronization logic happens in layer transactions and
   1.124 + * compositable transactions.
   1.125 + * A transaction is a set of changes to the layers and/or the compositables
   1.126 + * that are sent and applied together to the compositor thread to keep the
   1.127 + * LayerComposite in a coherent state.
   1.128 + * Layer transactions maintain the shape of the shadow layer tree, and
   1.129 + * synchronize the texture data held by compositables. Layer transactions
   1.130 + * are always between the content thread and the compositor thread.
   1.131 + * Compositable transactions are subset of a layer transaction with which only
   1.132 + * compositables and textures can be manipulated, and does not always originate
   1.133 + * from the content thread. (See CompositableForwarder.h and ImageBridgeChild.h)
   1.134 + */
   1.135 +
   1.136 +class ShadowLayerForwarder : public CompositableForwarder
   1.137 +{
   1.138 +  friend class ContentClientIncremental;
   1.139 +  friend class ClientLayerManager;
   1.140 +
   1.141 +public:
   1.142 +  virtual ~ShadowLayerForwarder();
   1.143 +
   1.144 +  /**
   1.145 +   * Setup the IPDL actor for aCompositable to be part of layers
   1.146 +   * transactions.
   1.147 +   */
   1.148 +  void Connect(CompositableClient* aCompositable);
   1.149 +
   1.150 +  virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
   1.151 +                                       TextureFlags aFlags) MOZ_OVERRIDE;
   1.152 +
   1.153 +  virtual void CreatedIncrementalBuffer(CompositableClient* aCompositable,
   1.154 +                                        const TextureInfo& aTextureInfo,
   1.155 +                                        const nsIntRect& aBufferRect) MOZ_OVERRIDE;
   1.156 +
   1.157 +  /**
   1.158 +   * Adds an edit in the layers transaction in order to attach
   1.159 +   * the corresponding compositable and layer on the compositor side.
   1.160 +   * Connect must have been called on aCompositable beforehand.
   1.161 +   */
   1.162 +  void Attach(CompositableClient* aCompositable,
   1.163 +              ShadowableLayer* aLayer);
   1.164 +
   1.165 +  /**
   1.166 +   * Adds an edit in the transaction in order to attach a Compositable that
   1.167 +   * is not managed by this ShadowLayerForwarder (for example, by ImageBridge
   1.168 +   * in the case of async-video).
   1.169 +   * Since the compositable is not managed by this forwarder, we can't use
   1.170 +   * the compositable or it's IPDL actor here, so we use an ID instead, that
   1.171 +   * is matched on the compositor side.
   1.172 +   */
   1.173 +  void AttachAsyncCompositable(uint64_t aCompositableID,
   1.174 +                               ShadowableLayer* aLayer);
   1.175 +
   1.176 +  /**
   1.177 +   * Begin recording a transaction to be forwarded atomically to a
   1.178 +   * LayerManagerComposite.
   1.179 +   */
   1.180 +  void BeginTransaction(const nsIntRect& aTargetBounds,
   1.181 +                        ScreenRotation aRotation,
   1.182 +                        const nsIntRect& aClientBounds,
   1.183 +                        mozilla::dom::ScreenOrientation aOrientation);
   1.184 +
   1.185 +  /**
   1.186 +   * The following methods may only be called after BeginTransaction()
   1.187 +   * but before EndTransaction().  They mirror the LayerManager
   1.188 +   * interface in Layers.h.
   1.189 +   */
   1.190 +
   1.191 +  /**
   1.192 +   * Notify the shadow manager that a new, "real" layer has been
   1.193 +   * created, and a corresponding shadow layer should be created in
   1.194 +   * the compositing process.
   1.195 +   */
   1.196 +  void CreatedThebesLayer(ShadowableLayer* aThebes);
   1.197 +  void CreatedContainerLayer(ShadowableLayer* aContainer);
   1.198 +  void CreatedImageLayer(ShadowableLayer* aImage);
   1.199 +  void CreatedColorLayer(ShadowableLayer* aColor);
   1.200 +  void CreatedCanvasLayer(ShadowableLayer* aCanvas);
   1.201 +  void CreatedRefLayer(ShadowableLayer* aRef);
   1.202 +
   1.203 +  /**
   1.204 +   * At least one attribute of |aMutant| has changed, and |aMutant|
   1.205 +   * needs to sync to its shadow layer.  This initial implementation
   1.206 +   * forwards all attributes when any is mutated.
   1.207 +   */
   1.208 +  void Mutated(ShadowableLayer* aMutant);
   1.209 +
   1.210 +  void SetRoot(ShadowableLayer* aRoot);
   1.211 +  /**
   1.212 +   * Insert |aChild| after |aAfter| in |aContainer|.  |aAfter| can be
   1.213 +   * nullptr to indicated that |aChild| should be appended to the end of
   1.214 +   * |aContainer|'s child list.
   1.215 +   */
   1.216 +  void InsertAfter(ShadowableLayer* aContainer,
   1.217 +                   ShadowableLayer* aChild,
   1.218 +                   ShadowableLayer* aAfter = nullptr);
   1.219 +  void RemoveChild(ShadowableLayer* aContainer,
   1.220 +                   ShadowableLayer* aChild);
   1.221 +  void RepositionChild(ShadowableLayer* aContainer,
   1.222 +                       ShadowableLayer* aChild,
   1.223 +                       ShadowableLayer* aAfter = nullptr);
   1.224 +
   1.225 +  /**
   1.226 +   * Set aMaskLayer as the mask on aLayer.
   1.227 +   * Note that only image layers are properly supported
   1.228 +   * LayerTransactionParent::UpdateMask and accompanying ipdl
   1.229 +   * will need changing to update properties for other kinds
   1.230 +   * of mask layer.
   1.231 +   */
   1.232 +  void SetMask(ShadowableLayer* aLayer,
   1.233 +               ShadowableLayer* aMaskLayer);
   1.234 +
   1.235 +  /**
   1.236 +   * See CompositableForwarder::UseTiledLayerBuffer
   1.237 +   */
   1.238 +  virtual void UseTiledLayerBuffer(CompositableClient* aCompositable,
   1.239 +                                   const SurfaceDescriptorTiles& aTileLayerDescriptor) MOZ_OVERRIDE;
   1.240 +
   1.241 +  /**
   1.242 +   * Notify the compositor that a compositable will be updated asynchronously
   1.243 +   * through ImageBridge, using an ID to connect the protocols on the
   1.244 +   * compositor side.
   1.245 +   */
   1.246 +  void AttachAsyncCompositable(PLayerTransactionChild* aLayer, uint64_t aID);
   1.247 +
   1.248 +  virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable,
   1.249 +                                             TextureClient* aTexture) MOZ_OVERRIDE;
   1.250 +
   1.251 +  virtual void RemoveTexture(TextureClient* aTexture) MOZ_OVERRIDE;
   1.252 +
   1.253 +  /**
   1.254 +   * Communicate to the compositor that aRegion in the texture identified by aLayer
   1.255 +   * and aIdentifier has been updated to aThebesBuffer.
   1.256 +   */
   1.257 +  virtual void UpdateTextureRegion(CompositableClient* aCompositable,
   1.258 +                                   const ThebesBufferData& aThebesBufferData,
   1.259 +                                   const nsIntRegion& aUpdatedRegion) MOZ_OVERRIDE;
   1.260 +
   1.261 +  virtual void UpdateTextureIncremental(CompositableClient* aCompositable,
   1.262 +                                        TextureIdentifier aTextureId,
   1.263 +                                        SurfaceDescriptor& aDescriptor,
   1.264 +                                        const nsIntRegion& aUpdatedRegion,
   1.265 +                                        const nsIntRect& aBufferRect,
   1.266 +                                        const nsIntPoint& aBufferRotation) MOZ_OVERRIDE;
   1.267 +
   1.268 +  /**
   1.269 +   * Communicate the picture rect of an image to the compositor
   1.270 +   */
   1.271 +  void UpdatePictureRect(CompositableClient* aCompositable,
   1.272 +                         const nsIntRect& aRect);
   1.273 +
   1.274 +  /**
   1.275 +   * See CompositableForwarder::UpdatedTexture
   1.276 +   */
   1.277 +  virtual void UpdatedTexture(CompositableClient* aCompositable,
   1.278 +                              TextureClient* aTexture,
   1.279 +                              nsIntRegion* aRegion) MOZ_OVERRIDE;
   1.280 +
   1.281 +  /**
   1.282 +   * See CompositableForwarder::UseTexture
   1.283 +   */
   1.284 +  virtual void UseTexture(CompositableClient* aCompositable,
   1.285 +                          TextureClient* aClient) MOZ_OVERRIDE;
   1.286 +  virtual void UseComponentAlphaTextures(CompositableClient* aCompositable,
   1.287 +                                         TextureClient* aClientOnBlack,
   1.288 +                                         TextureClient* aClientOnWhite) MOZ_OVERRIDE;
   1.289 +
   1.290 +  /**
   1.291 +   * End the current transaction and forward it to LayerManagerComposite.
   1.292 +   * |aReplies| are directions from the LayerManagerComposite to the
   1.293 +   * caller of EndTransaction().
   1.294 +   */
   1.295 +  bool EndTransaction(InfallibleTArray<EditReply>* aReplies,
   1.296 +                      const nsIntRegion& aRegionToClear,
   1.297 +                      bool aScheduleComposite,
   1.298 +                      bool* aSent);
   1.299 +
   1.300 +  /**
   1.301 +   * Set an actor through which layer updates will be pushed.
   1.302 +   */
   1.303 +  void SetShadowManager(PLayerTransactionChild* aShadowManager);
   1.304 +
   1.305 +  /**
   1.306 +   * True if this is forwarding to a LayerManagerComposite.
   1.307 +   */
   1.308 +  bool HasShadowManager() const { return !!mShadowManager; }
   1.309 +  LayerTransactionChild* GetShadowManager() const { return mShadowManager.get(); }
   1.310 +
   1.311 +  virtual void WindowOverlayChanged() { mWindowOverlayChanged = true; }
   1.312 +
   1.313 +  /**
   1.314 +   * The following Alloc/Open/Destroy interfaces abstract over the
   1.315 +   * details of working with surfaces that are shared across
   1.316 +   * processes.  They provide the glue between C++ Layers and the
   1.317 +   * LayerComposite IPC system.
   1.318 +   *
   1.319 +   * The basic lifecycle is
   1.320 +   *
   1.321 +   *  - a Layer needs a buffer.  Its ShadowableLayer subclass calls
   1.322 +   *    AllocBuffer(), then calls one of the Created*Buffer() methods
   1.323 +   *    above to transfer the (temporary) front buffer to its
   1.324 +   *    LayerComposite in the other process.  The Layer needs a
   1.325 +   *    gfxASurface to paint, so the ShadowableLayer uses
   1.326 +   *    OpenDescriptor(backBuffer) to get that surface, and hands it
   1.327 +   *    out to the Layer.
   1.328 +   *
   1.329 +   * - a Layer has painted new pixels.  Its ShadowableLayer calls one
   1.330 +   *   of the Painted*Buffer() methods above with the back buffer
   1.331 +   *   descriptor.  This notification is forwarded to the LayerComposite,
   1.332 +   *   which uses OpenDescriptor() to access the newly-painted pixels.
   1.333 +   *   The LayerComposite then updates its front buffer in a Layer- and
   1.334 +   *   platform-dependent way, and sends a surface descriptor back to
   1.335 +   *   the ShadowableLayer that becomes its new back back buffer.
   1.336 +   *
   1.337 +   * - a Layer wants to destroy its buffers.  Its ShadowableLayer
   1.338 +   *   calls Destroyed*Buffer(), which gives up control of the back
   1.339 +   *   buffer descriptor.  The actual back buffer surface is then
   1.340 +   *   destroyed using DestroySharedSurface() just before notifying
   1.341 +   *   the parent process.  When the parent process is notified, the
   1.342 +   *   LayerComposite also calls DestroySharedSurface() on its front
   1.343 +   *   buffer, and the double-buffer pair is gone.
   1.344 +   */
   1.345 +
   1.346 +  // ISurfaceAllocator
   1.347 +  virtual bool AllocUnsafeShmem(size_t aSize,
   1.348 +                                mozilla::ipc::SharedMemory::SharedMemoryType aType,
   1.349 +                                mozilla::ipc::Shmem* aShmem) MOZ_OVERRIDE;
   1.350 +  virtual bool AllocShmem(size_t aSize,
   1.351 +                          mozilla::ipc::SharedMemory::SharedMemoryType aType,
   1.352 +                          mozilla::ipc::Shmem* aShmem) MOZ_OVERRIDE;
   1.353 +  virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem) MOZ_OVERRIDE;
   1.354 +
   1.355 +  virtual bool IPCOpen() const MOZ_OVERRIDE;
   1.356 +  virtual bool IsSameProcess() const MOZ_OVERRIDE;
   1.357 +
   1.358 +  /**
   1.359 +   * Construct a shadow of |aLayer| on the "other side", at the
   1.360 +   * LayerManagerComposite.
   1.361 +   */
   1.362 +  PLayerChild* ConstructShadowFor(ShadowableLayer* aLayer);
   1.363 +
   1.364 +  /**
   1.365 +   * Flag the next paint as the first for a document.
   1.366 +   */
   1.367 +  void SetIsFirstPaint() { mIsFirstPaint = true; }
   1.368 +
   1.369 +  static void PlatformSyncBeforeUpdate();
   1.370 +
   1.371 +protected:
   1.372 +  ShadowLayerForwarder();
   1.373 +
   1.374 +#ifdef DEBUG
   1.375 +  void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const;
   1.376 +#else
   1.377 +  void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const {}
   1.378 +#endif
   1.379 +
   1.380 +  RefPtr<LayerTransactionChild> mShadowManager;
   1.381 +
   1.382 +#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
   1.383 +  // from ISurfaceAllocator
   1.384 +  virtual PGrallocBufferChild* AllocGrallocBuffer(const gfx::IntSize& aSize,
   1.385 +                                                  uint32_t aFormat,
   1.386 +                                                  uint32_t aUsage,
   1.387 +                                                  MaybeMagicGrallocBufferHandle* aHandle) MOZ_OVERRIDE;
   1.388 +
   1.389 +  virtual void DeallocGrallocBuffer(PGrallocBufferChild* aChild) MOZ_OVERRIDE;
   1.390 +#endif
   1.391 +
   1.392 +private:
   1.393 +
   1.394 +  Transaction* mTxn;
   1.395 +  DiagnosticTypes mDiagnosticTypes;
   1.396 +  bool mIsFirstPaint;
   1.397 +  bool mWindowOverlayChanged;
   1.398 +};
   1.399 +
   1.400 +class CompositableClient;
   1.401 +
   1.402 +/**
   1.403 + * A ShadowableLayer is a Layer can be shared with a parent context
   1.404 + * through a ShadowLayerForwarder.  A ShadowableLayer maps to a
   1.405 + * Shadow*Layer in a parent context.
   1.406 + *
   1.407 + * Note that ShadowLayers can themselves be ShadowableLayers.
   1.408 + */
   1.409 +class ShadowableLayer
   1.410 +{
   1.411 +public:
   1.412 +  virtual ~ShadowableLayer() {}
   1.413 +
   1.414 +  virtual Layer* AsLayer() = 0;
   1.415 +
   1.416 +  /**
   1.417 +   * True if this layer has a shadow in a parent process.
   1.418 +   */
   1.419 +  bool HasShadow() { return !!mShadow; }
   1.420 +
   1.421 +  /**
   1.422 +   * Return the IPC handle to a Shadow*Layer referring to this if one
   1.423 +   * exists, nullptr if not.
   1.424 +   */
   1.425 +  PLayerChild* GetShadow() { return mShadow; }
   1.426 +
   1.427 +  virtual CompositableClient* GetCompositableClient() { return nullptr; }
   1.428 +protected:
   1.429 +  ShadowableLayer() : mShadow(nullptr) {}
   1.430 +
   1.431 +  PLayerChild* mShadow;
   1.432 +};
   1.433 +
   1.434 +} // namespace layers
   1.435 +} // namespace mozilla
   1.436 +
   1.437 +#endif // ifndef mozilla_layers_ShadowLayers_h

mercurial