1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/ipc/ImageBridgeChild.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,331 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef MOZILLA_GFX_IMAGEBRIDGECHILD_H 1.10 +#define MOZILLA_GFX_IMAGEBRIDGECHILD_H 1.11 + 1.12 +#include <stddef.h> // for size_t 1.13 +#include <stdint.h> // for uint32_t, uint64_t 1.14 +#include "mozilla/Attributes.h" // for MOZ_OVERRIDE 1.15 +#include "mozilla/RefPtr.h" // for TemporaryRef 1.16 +#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc 1.17 +#include "mozilla/layers/CompositableForwarder.h" 1.18 +#include "mozilla/layers/CompositorTypes.h" // for TextureIdentifier, etc 1.19 +#include "mozilla/layers/LayersSurfaces.h" // for PGrallocBufferChild 1.20 +#include "mozilla/layers/PImageBridgeChild.h" 1.21 +#include "nsDebug.h" // for NS_RUNTIMEABORT 1.22 +#include "nsRegion.h" // for nsIntRegion 1.23 +class MessageLoop; 1.24 +struct nsIntPoint; 1.25 +struct nsIntRect; 1.26 + 1.27 +namespace base { 1.28 +class Thread; 1.29 +} 1.30 + 1.31 +namespace mozilla { 1.32 +namespace ipc { 1.33 +class Shmem; 1.34 +} 1.35 + 1.36 +namespace layers { 1.37 + 1.38 +class ClientTiledLayerBuffer; 1.39 +class ImageClient; 1.40 +class ImageContainer; 1.41 +class ImageBridgeParent; 1.42 +class CompositableClient; 1.43 +class CompositableTransaction; 1.44 +class Image; 1.45 +class TextureClient; 1.46 + 1.47 +/** 1.48 + * Returns true if the current thread is the ImageBrdigeChild's thread. 1.49 + * 1.50 + * Can be called from any thread. 1.51 + */ 1.52 +bool InImageBridgeChildThread(); 1.53 + 1.54 +/** 1.55 + * The ImageBridge protocol is meant to allow ImageContainers to forward images 1.56 + * directly to the compositor thread/process without using the main thread. 1.57 + * 1.58 + * ImageBridgeChild is a CompositableForwarder just like ShadowLayerForwarder. 1.59 + * This means it also does transactions with the compositor thread/process, 1.60 + * except that the transactions are restricted to operations on the Compositables 1.61 + * and cannot contain messages affecting layers directly. 1.62 + * 1.63 + * ImageBridgeChild is also a ISurfaceAllocator. It can be used to allocate or 1.64 + * deallocate data that is shared with the compositor. The main differerence 1.65 + * with other ISurfaceAllocators is that some of its overriden methods can be 1.66 + * invoked from any thread. 1.67 + * 1.68 + * There are three important phases in the ImageBridge protocol. These three steps 1.69 + * can do different things depending if (A) the ImageContainer uses ImageBridge 1.70 + * or (B) it does not use ImageBridge: 1.71 + * 1.72 + * - When an ImageContainer calls its method SetCurrentImage: 1.73 + * - (A) The image is sent directly to the compositor process through the 1.74 + * ImageBridge IPDL protocol. 1.75 + * On the compositor side the image is stored in a global table that associates 1.76 + * the image with an ID corresponding to the ImageContainer, and a composition is 1.77 + * triggered. 1.78 + * - (B) Since it does not have an ImageBridge, the image is not sent yet. 1.79 + * instead the will be sent to the compositor during the next layer transaction 1.80 + * (on the main thread). 1.81 + * 1.82 + * - During a Layer transaction: 1.83 + * - (A) The ImageContainer uses ImageBridge. The image is already available to the 1.84 + * compositor process because it has been sent with SetCurrentImage. Yet, the 1.85 + * CompositableHost on the compositor side will needs the ID referring to the 1.86 + * ImageContainer to access the Image. So during the Swap operation that happens 1.87 + * in the transaction, we swap the container ID rather than the image data. 1.88 + * - (B) Since the ImageContainer does not use ImageBridge, the image data is swaped. 1.89 + * 1.90 + * - During composition: 1.91 + * - (A) The CompositableHost has an AsyncID, it looks up the ID in the 1.92 + * global table to see if there is an image. If there is no image, nothing is rendered. 1.93 + * - (B) The CompositableHost has image data rather than an ID (meaning it is not 1.94 + * using ImageBridge), then it just composites the image data normally. 1.95 + * 1.96 + * This means that there might be a possibility for the ImageBridge to send the first 1.97 + * frame before the first layer transaction that will pass the container ID to the 1.98 + * CompositableHost happens. In this (unlikely) case the layer is not composited 1.99 + * until the layer transaction happens. This means this scenario is not harmful. 1.100 + * 1.101 + * Since sending an image through imageBridge triggers compositing, the main thread is 1.102 + * not used at all (except for the very first transaction that provides the 1.103 + * CompositableHost with an AsyncID). 1.104 + */ 1.105 +class ImageBridgeChild : public PImageBridgeChild 1.106 + , public CompositableForwarder 1.107 +{ 1.108 + friend class ImageContainer; 1.109 +public: 1.110 + 1.111 + /** 1.112 + * Creates the image bridge with a dedicated thread for ImageBridgeChild. 1.113 + * 1.114 + * We may want to use a specifi thread in the future. In this case, use 1.115 + * CreateWithThread instead. 1.116 + */ 1.117 + static void StartUp(); 1.118 + 1.119 + static PImageBridgeChild* 1.120 + StartUpInChildProcess(Transport* aTransport, ProcessId aOtherProcess); 1.121 + 1.122 + /** 1.123 + * Destroys the image bridge by calling DestroyBridge, and destroys the 1.124 + * ImageBridge's thread. 1.125 + * 1.126 + * If you don't want to destroy the thread, call DestroyBridge directly 1.127 + * instead. 1.128 + */ 1.129 + static void ShutDown(); 1.130 + 1.131 + /** 1.132 + * Creates the ImageBridgeChild manager protocol. 1.133 + */ 1.134 + static bool StartUpOnThread(base::Thread* aThread); 1.135 + 1.136 + /** 1.137 + * Returns true if the singleton has been created. 1.138 + * 1.139 + * Can be called from any thread. 1.140 + */ 1.141 + static bool IsCreated(); 1.142 + 1.143 + /** 1.144 + * returns the singleton instance. 1.145 + * 1.146 + * can be called from any thread. 1.147 + */ 1.148 + static ImageBridgeChild* GetSingleton(); 1.149 + 1.150 + 1.151 + /** 1.152 + * Dispatches a task to the ImageBridgeChild thread to do the connection 1.153 + */ 1.154 + void ConnectAsync(ImageBridgeParent* aParent); 1.155 + 1.156 + static void IdentifyCompositorTextureHost(const TextureFactoryIdentifier& aIdentifier); 1.157 + 1.158 + void BeginTransaction(); 1.159 + void EndTransaction(); 1.160 + 1.161 + /** 1.162 + * Returns the ImageBridgeChild's thread. 1.163 + * 1.164 + * Can be called from any thread. 1.165 + */ 1.166 + base::Thread * GetThread() const; 1.167 + 1.168 + /** 1.169 + * Returns the ImageBridgeChild's message loop. 1.170 + * 1.171 + * Can be called from any thread. 1.172 + */ 1.173 + MessageLoop * GetMessageLoop() const; 1.174 + 1.175 + PCompositableChild* AllocPCompositableChild(const TextureInfo& aInfo, uint64_t* aID) MOZ_OVERRIDE; 1.176 + bool DeallocPCompositableChild(PCompositableChild* aActor) MOZ_OVERRIDE; 1.177 + 1.178 + /** 1.179 + * This must be called by the static function DeleteImageBridgeSync defined 1.180 + * in ImageBridgeChild.cpp ONLY. 1.181 + */ 1.182 + ~ImageBridgeChild(); 1.183 + 1.184 + virtual PGrallocBufferChild* 1.185 + AllocPGrallocBufferChild(const gfx::IntSize&, const uint32_t&, const uint32_t&, 1.186 + MaybeMagicGrallocBufferHandle*) MOZ_OVERRIDE; 1.187 + 1.188 + virtual bool 1.189 + DeallocPGrallocBufferChild(PGrallocBufferChild* actor) MOZ_OVERRIDE; 1.190 + 1.191 + virtual PTextureChild* 1.192 + AllocPTextureChild(const SurfaceDescriptor& aSharedData, const TextureFlags& aFlags) MOZ_OVERRIDE; 1.193 + 1.194 + virtual bool 1.195 + DeallocPTextureChild(PTextureChild* actor) MOZ_OVERRIDE; 1.196 + 1.197 + TemporaryRef<ImageClient> CreateImageClient(CompositableType aType); 1.198 + TemporaryRef<ImageClient> CreateImageClientNow(CompositableType aType); 1.199 + 1.200 + static void DispatchReleaseImageClient(ImageClient* aClient); 1.201 + static void DispatchReleaseTextureClient(TextureClient* aClient); 1.202 + static void DispatchImageClientUpdate(ImageClient* aClient, ImageContainer* aContainer); 1.203 + 1.204 + /** 1.205 + * Flush all Images sent to CompositableHost. 1.206 + */ 1.207 + static void FlushAllImages(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront); 1.208 + 1.209 + /** 1.210 + * Must be called on the ImageBridgeChild's thread. 1.211 + */ 1.212 + static void FlushAllImagesNow(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront); 1.213 + 1.214 + // CompositableForwarder 1.215 + 1.216 + virtual void Connect(CompositableClient* aCompositable) MOZ_OVERRIDE; 1.217 + 1.218 + /** 1.219 + * See CompositableForwarder::UpdatedTexture 1.220 + */ 1.221 + virtual void UpdatedTexture(CompositableClient* aCompositable, 1.222 + TextureClient* aTexture, 1.223 + nsIntRegion* aRegion) MOZ_OVERRIDE; 1.224 + 1.225 + /** 1.226 + * See CompositableForwarder::UseTexture 1.227 + */ 1.228 + virtual void UseTexture(CompositableClient* aCompositable, 1.229 + TextureClient* aClient) MOZ_OVERRIDE; 1.230 + virtual void UseComponentAlphaTextures(CompositableClient* aCompositable, 1.231 + TextureClient* aClientOnBlack, 1.232 + TextureClient* aClientOnWhite) MOZ_OVERRIDE; 1.233 + 1.234 + virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable, 1.235 + TextureClient* aTexture) MOZ_OVERRIDE; 1.236 + 1.237 + virtual void RemoveTexture(TextureClient* aTexture) MOZ_OVERRIDE; 1.238 + 1.239 + virtual void UseTiledLayerBuffer(CompositableClient* aCompositable, 1.240 + const SurfaceDescriptorTiles& aTileLayerDescriptor) MOZ_OVERRIDE 1.241 + { 1.242 + NS_RUNTIMEABORT("should not be called"); 1.243 + } 1.244 + 1.245 + virtual void UpdateTextureIncremental(CompositableClient* aCompositable, 1.246 + TextureIdentifier aTextureId, 1.247 + SurfaceDescriptor& aDescriptor, 1.248 + const nsIntRegion& aUpdatedRegion, 1.249 + const nsIntRect& aBufferRect, 1.250 + const nsIntPoint& aBufferRotation) MOZ_OVERRIDE 1.251 + { 1.252 + NS_RUNTIMEABORT("should not be called"); 1.253 + } 1.254 + 1.255 + /** 1.256 + * Communicate the picture rect of a YUV image in aLayer to the compositor 1.257 + */ 1.258 + virtual void UpdatePictureRect(CompositableClient* aCompositable, 1.259 + const nsIntRect& aRect) MOZ_OVERRIDE; 1.260 + 1.261 + 1.262 + virtual void CreatedIncrementalBuffer(CompositableClient* aCompositable, 1.263 + const TextureInfo& aTextureInfo, 1.264 + const nsIntRect& aBufferRect) MOZ_OVERRIDE 1.265 + { 1.266 + NS_RUNTIMEABORT("should not be called"); 1.267 + } 1.268 + virtual void UpdateTextureRegion(CompositableClient* aCompositable, 1.269 + const ThebesBufferData& aThebesBufferData, 1.270 + const nsIntRegion& aUpdatedRegion) MOZ_OVERRIDE { 1.271 + NS_RUNTIMEABORT("should not be called"); 1.272 + } 1.273 + 1.274 + // ISurfaceAllocator 1.275 + 1.276 + /** 1.277 + * See ISurfaceAllocator.h 1.278 + * Can be used from any thread. 1.279 + * If used outside the ImageBridgeChild thread, it will proxy a synchronous 1.280 + * call on the ImageBridgeChild thread. 1.281 + */ 1.282 + virtual bool AllocUnsafeShmem(size_t aSize, 1.283 + mozilla::ipc::SharedMemory::SharedMemoryType aType, 1.284 + mozilla::ipc::Shmem* aShmem) MOZ_OVERRIDE; 1.285 + /** 1.286 + * See ISurfaceAllocator.h 1.287 + * Can be used from any thread. 1.288 + * If used outside the ImageBridgeChild thread, it will proxy a synchronous 1.289 + * call on the ImageBridgeChild thread. 1.290 + */ 1.291 + virtual bool AllocShmem(size_t aSize, 1.292 + mozilla::ipc::SharedMemory::SharedMemoryType aType, 1.293 + mozilla::ipc::Shmem* aShmem) MOZ_OVERRIDE; 1.294 + /** 1.295 + * See ISurfaceAllocator.h 1.296 + * Can be used from any thread. 1.297 + * If used outside the ImageBridgeChild thread, it will proxy a synchronous 1.298 + * call on the ImageBridgeChild thread. 1.299 + */ 1.300 + virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem); 1.301 + 1.302 + virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData, 1.303 + TextureFlags aFlags) MOZ_OVERRIDE; 1.304 + 1.305 + virtual bool IsSameProcess() const MOZ_OVERRIDE; 1.306 + 1.307 + void AllocGrallocBufferNow(const gfx::IntSize& aSize, 1.308 + uint32_t aFormat, uint32_t aUsage, 1.309 + MaybeMagicGrallocBufferHandle* aHandle, 1.310 + PGrallocBufferChild** aChild); 1.311 + 1.312 + void MarkShutDown(); 1.313 +protected: 1.314 + ImageBridgeChild(); 1.315 + bool DispatchAllocShmemInternal(size_t aSize, 1.316 + SharedMemory::SharedMemoryType aType, 1.317 + Shmem* aShmem, 1.318 + bool aUnsafe); 1.319 + 1.320 + CompositableTransaction* mTxn; 1.321 + bool mShuttingDown; 1.322 + 1.323 + // ISurfaceAllocator 1.324 + virtual PGrallocBufferChild* AllocGrallocBuffer(const gfx::IntSize& aSize, 1.325 + uint32_t aFormat, uint32_t aUsage, 1.326 + MaybeMagicGrallocBufferHandle* aHandle) MOZ_OVERRIDE; 1.327 + 1.328 + virtual void DeallocGrallocBuffer(PGrallocBufferChild* aChild) MOZ_OVERRIDE; 1.329 +}; 1.330 + 1.331 +} // layers 1.332 +} // mozilla 1.333 + 1.334 +#endif