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