gfx/layers/ipc/ImageBridgeChild.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef MOZILLA_GFX_IMAGEBRIDGECHILD_H
michael@0 7 #define MOZILLA_GFX_IMAGEBRIDGECHILD_H
michael@0 8
michael@0 9 #include <stddef.h> // for size_t
michael@0 10 #include <stdint.h> // for uint32_t, uint64_t
michael@0 11 #include "mozilla/Attributes.h" // for MOZ_OVERRIDE
michael@0 12 #include "mozilla/RefPtr.h" // for TemporaryRef
michael@0 13 #include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
michael@0 14 #include "mozilla/layers/CompositableForwarder.h"
michael@0 15 #include "mozilla/layers/CompositorTypes.h" // for TextureIdentifier, etc
michael@0 16 #include "mozilla/layers/LayersSurfaces.h" // for PGrallocBufferChild
michael@0 17 #include "mozilla/layers/PImageBridgeChild.h"
michael@0 18 #include "nsDebug.h" // for NS_RUNTIMEABORT
michael@0 19 #include "nsRegion.h" // for nsIntRegion
michael@0 20 class MessageLoop;
michael@0 21 struct nsIntPoint;
michael@0 22 struct nsIntRect;
michael@0 23
michael@0 24 namespace base {
michael@0 25 class Thread;
michael@0 26 }
michael@0 27
michael@0 28 namespace mozilla {
michael@0 29 namespace ipc {
michael@0 30 class Shmem;
michael@0 31 }
michael@0 32
michael@0 33 namespace layers {
michael@0 34
michael@0 35 class ClientTiledLayerBuffer;
michael@0 36 class ImageClient;
michael@0 37 class ImageContainer;
michael@0 38 class ImageBridgeParent;
michael@0 39 class CompositableClient;
michael@0 40 class CompositableTransaction;
michael@0 41 class Image;
michael@0 42 class TextureClient;
michael@0 43
michael@0 44 /**
michael@0 45 * Returns true if the current thread is the ImageBrdigeChild's thread.
michael@0 46 *
michael@0 47 * Can be called from any thread.
michael@0 48 */
michael@0 49 bool InImageBridgeChildThread();
michael@0 50
michael@0 51 /**
michael@0 52 * The ImageBridge protocol is meant to allow ImageContainers to forward images
michael@0 53 * directly to the compositor thread/process without using the main thread.
michael@0 54 *
michael@0 55 * ImageBridgeChild is a CompositableForwarder just like ShadowLayerForwarder.
michael@0 56 * This means it also does transactions with the compositor thread/process,
michael@0 57 * except that the transactions are restricted to operations on the Compositables
michael@0 58 * and cannot contain messages affecting layers directly.
michael@0 59 *
michael@0 60 * ImageBridgeChild is also a ISurfaceAllocator. It can be used to allocate or
michael@0 61 * deallocate data that is shared with the compositor. The main differerence
michael@0 62 * with other ISurfaceAllocators is that some of its overriden methods can be
michael@0 63 * invoked from any thread.
michael@0 64 *
michael@0 65 * There are three important phases in the ImageBridge protocol. These three steps
michael@0 66 * can do different things depending if (A) the ImageContainer uses ImageBridge
michael@0 67 * or (B) it does not use ImageBridge:
michael@0 68 *
michael@0 69 * - When an ImageContainer calls its method SetCurrentImage:
michael@0 70 * - (A) The image is sent directly to the compositor process through the
michael@0 71 * ImageBridge IPDL protocol.
michael@0 72 * On the compositor side the image is stored in a global table that associates
michael@0 73 * the image with an ID corresponding to the ImageContainer, and a composition is
michael@0 74 * triggered.
michael@0 75 * - (B) Since it does not have an ImageBridge, the image is not sent yet.
michael@0 76 * instead the will be sent to the compositor during the next layer transaction
michael@0 77 * (on the main thread).
michael@0 78 *
michael@0 79 * - During a Layer transaction:
michael@0 80 * - (A) The ImageContainer uses ImageBridge. The image is already available to the
michael@0 81 * compositor process because it has been sent with SetCurrentImage. Yet, the
michael@0 82 * CompositableHost on the compositor side will needs the ID referring to the
michael@0 83 * ImageContainer to access the Image. So during the Swap operation that happens
michael@0 84 * in the transaction, we swap the container ID rather than the image data.
michael@0 85 * - (B) Since the ImageContainer does not use ImageBridge, the image data is swaped.
michael@0 86 *
michael@0 87 * - During composition:
michael@0 88 * - (A) The CompositableHost has an AsyncID, it looks up the ID in the
michael@0 89 * global table to see if there is an image. If there is no image, nothing is rendered.
michael@0 90 * - (B) The CompositableHost has image data rather than an ID (meaning it is not
michael@0 91 * using ImageBridge), then it just composites the image data normally.
michael@0 92 *
michael@0 93 * This means that there might be a possibility for the ImageBridge to send the first
michael@0 94 * frame before the first layer transaction that will pass the container ID to the
michael@0 95 * CompositableHost happens. In this (unlikely) case the layer is not composited
michael@0 96 * until the layer transaction happens. This means this scenario is not harmful.
michael@0 97 *
michael@0 98 * Since sending an image through imageBridge triggers compositing, the main thread is
michael@0 99 * not used at all (except for the very first transaction that provides the
michael@0 100 * CompositableHost with an AsyncID).
michael@0 101 */
michael@0 102 class ImageBridgeChild : public PImageBridgeChild
michael@0 103 , public CompositableForwarder
michael@0 104 {
michael@0 105 friend class ImageContainer;
michael@0 106 public:
michael@0 107
michael@0 108 /**
michael@0 109 * Creates the image bridge with a dedicated thread for ImageBridgeChild.
michael@0 110 *
michael@0 111 * We may want to use a specifi thread in the future. In this case, use
michael@0 112 * CreateWithThread instead.
michael@0 113 */
michael@0 114 static void StartUp();
michael@0 115
michael@0 116 static PImageBridgeChild*
michael@0 117 StartUpInChildProcess(Transport* aTransport, ProcessId aOtherProcess);
michael@0 118
michael@0 119 /**
michael@0 120 * Destroys the image bridge by calling DestroyBridge, and destroys the
michael@0 121 * ImageBridge's thread.
michael@0 122 *
michael@0 123 * If you don't want to destroy the thread, call DestroyBridge directly
michael@0 124 * instead.
michael@0 125 */
michael@0 126 static void ShutDown();
michael@0 127
michael@0 128 /**
michael@0 129 * Creates the ImageBridgeChild manager protocol.
michael@0 130 */
michael@0 131 static bool StartUpOnThread(base::Thread* aThread);
michael@0 132
michael@0 133 /**
michael@0 134 * Returns true if the singleton has been created.
michael@0 135 *
michael@0 136 * Can be called from any thread.
michael@0 137 */
michael@0 138 static bool IsCreated();
michael@0 139
michael@0 140 /**
michael@0 141 * returns the singleton instance.
michael@0 142 *
michael@0 143 * can be called from any thread.
michael@0 144 */
michael@0 145 static ImageBridgeChild* GetSingleton();
michael@0 146
michael@0 147
michael@0 148 /**
michael@0 149 * Dispatches a task to the ImageBridgeChild thread to do the connection
michael@0 150 */
michael@0 151 void ConnectAsync(ImageBridgeParent* aParent);
michael@0 152
michael@0 153 static void IdentifyCompositorTextureHost(const TextureFactoryIdentifier& aIdentifier);
michael@0 154
michael@0 155 void BeginTransaction();
michael@0 156 void EndTransaction();
michael@0 157
michael@0 158 /**
michael@0 159 * Returns the ImageBridgeChild's thread.
michael@0 160 *
michael@0 161 * Can be called from any thread.
michael@0 162 */
michael@0 163 base::Thread * GetThread() const;
michael@0 164
michael@0 165 /**
michael@0 166 * Returns the ImageBridgeChild's message loop.
michael@0 167 *
michael@0 168 * Can be called from any thread.
michael@0 169 */
michael@0 170 MessageLoop * GetMessageLoop() const;
michael@0 171
michael@0 172 PCompositableChild* AllocPCompositableChild(const TextureInfo& aInfo, uint64_t* aID) MOZ_OVERRIDE;
michael@0 173 bool DeallocPCompositableChild(PCompositableChild* aActor) MOZ_OVERRIDE;
michael@0 174
michael@0 175 /**
michael@0 176 * This must be called by the static function DeleteImageBridgeSync defined
michael@0 177 * in ImageBridgeChild.cpp ONLY.
michael@0 178 */
michael@0 179 ~ImageBridgeChild();
michael@0 180
michael@0 181 virtual PGrallocBufferChild*
michael@0 182 AllocPGrallocBufferChild(const gfx::IntSize&, const uint32_t&, const uint32_t&,
michael@0 183 MaybeMagicGrallocBufferHandle*) MOZ_OVERRIDE;
michael@0 184
michael@0 185 virtual bool
michael@0 186 DeallocPGrallocBufferChild(PGrallocBufferChild* actor) MOZ_OVERRIDE;
michael@0 187
michael@0 188 virtual PTextureChild*
michael@0 189 AllocPTextureChild(const SurfaceDescriptor& aSharedData, const TextureFlags& aFlags) MOZ_OVERRIDE;
michael@0 190
michael@0 191 virtual bool
michael@0 192 DeallocPTextureChild(PTextureChild* actor) MOZ_OVERRIDE;
michael@0 193
michael@0 194 TemporaryRef<ImageClient> CreateImageClient(CompositableType aType);
michael@0 195 TemporaryRef<ImageClient> CreateImageClientNow(CompositableType aType);
michael@0 196
michael@0 197 static void DispatchReleaseImageClient(ImageClient* aClient);
michael@0 198 static void DispatchReleaseTextureClient(TextureClient* aClient);
michael@0 199 static void DispatchImageClientUpdate(ImageClient* aClient, ImageContainer* aContainer);
michael@0 200
michael@0 201 /**
michael@0 202 * Flush all Images sent to CompositableHost.
michael@0 203 */
michael@0 204 static void FlushAllImages(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront);
michael@0 205
michael@0 206 /**
michael@0 207 * Must be called on the ImageBridgeChild's thread.
michael@0 208 */
michael@0 209 static void FlushAllImagesNow(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront);
michael@0 210
michael@0 211 // CompositableForwarder
michael@0 212
michael@0 213 virtual void Connect(CompositableClient* aCompositable) MOZ_OVERRIDE;
michael@0 214
michael@0 215 /**
michael@0 216 * See CompositableForwarder::UpdatedTexture
michael@0 217 */
michael@0 218 virtual void UpdatedTexture(CompositableClient* aCompositable,
michael@0 219 TextureClient* aTexture,
michael@0 220 nsIntRegion* aRegion) MOZ_OVERRIDE;
michael@0 221
michael@0 222 /**
michael@0 223 * See CompositableForwarder::UseTexture
michael@0 224 */
michael@0 225 virtual void UseTexture(CompositableClient* aCompositable,
michael@0 226 TextureClient* aClient) MOZ_OVERRIDE;
michael@0 227 virtual void UseComponentAlphaTextures(CompositableClient* aCompositable,
michael@0 228 TextureClient* aClientOnBlack,
michael@0 229 TextureClient* aClientOnWhite) MOZ_OVERRIDE;
michael@0 230
michael@0 231 virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable,
michael@0 232 TextureClient* aTexture) MOZ_OVERRIDE;
michael@0 233
michael@0 234 virtual void RemoveTexture(TextureClient* aTexture) MOZ_OVERRIDE;
michael@0 235
michael@0 236 virtual void UseTiledLayerBuffer(CompositableClient* aCompositable,
michael@0 237 const SurfaceDescriptorTiles& aTileLayerDescriptor) MOZ_OVERRIDE
michael@0 238 {
michael@0 239 NS_RUNTIMEABORT("should not be called");
michael@0 240 }
michael@0 241
michael@0 242 virtual void UpdateTextureIncremental(CompositableClient* aCompositable,
michael@0 243 TextureIdentifier aTextureId,
michael@0 244 SurfaceDescriptor& aDescriptor,
michael@0 245 const nsIntRegion& aUpdatedRegion,
michael@0 246 const nsIntRect& aBufferRect,
michael@0 247 const nsIntPoint& aBufferRotation) MOZ_OVERRIDE
michael@0 248 {
michael@0 249 NS_RUNTIMEABORT("should not be called");
michael@0 250 }
michael@0 251
michael@0 252 /**
michael@0 253 * Communicate the picture rect of a YUV image in aLayer to the compositor
michael@0 254 */
michael@0 255 virtual void UpdatePictureRect(CompositableClient* aCompositable,
michael@0 256 const nsIntRect& aRect) MOZ_OVERRIDE;
michael@0 257
michael@0 258
michael@0 259 virtual void CreatedIncrementalBuffer(CompositableClient* aCompositable,
michael@0 260 const TextureInfo& aTextureInfo,
michael@0 261 const nsIntRect& aBufferRect) MOZ_OVERRIDE
michael@0 262 {
michael@0 263 NS_RUNTIMEABORT("should not be called");
michael@0 264 }
michael@0 265 virtual void UpdateTextureRegion(CompositableClient* aCompositable,
michael@0 266 const ThebesBufferData& aThebesBufferData,
michael@0 267 const nsIntRegion& aUpdatedRegion) MOZ_OVERRIDE {
michael@0 268 NS_RUNTIMEABORT("should not be called");
michael@0 269 }
michael@0 270
michael@0 271 // ISurfaceAllocator
michael@0 272
michael@0 273 /**
michael@0 274 * See ISurfaceAllocator.h
michael@0 275 * Can be used from any thread.
michael@0 276 * If used outside the ImageBridgeChild thread, it will proxy a synchronous
michael@0 277 * call on the ImageBridgeChild thread.
michael@0 278 */
michael@0 279 virtual bool AllocUnsafeShmem(size_t aSize,
michael@0 280 mozilla::ipc::SharedMemory::SharedMemoryType aType,
michael@0 281 mozilla::ipc::Shmem* aShmem) MOZ_OVERRIDE;
michael@0 282 /**
michael@0 283 * See ISurfaceAllocator.h
michael@0 284 * Can be used from any thread.
michael@0 285 * If used outside the ImageBridgeChild thread, it will proxy a synchronous
michael@0 286 * call on the ImageBridgeChild thread.
michael@0 287 */
michael@0 288 virtual bool AllocShmem(size_t aSize,
michael@0 289 mozilla::ipc::SharedMemory::SharedMemoryType aType,
michael@0 290 mozilla::ipc::Shmem* aShmem) MOZ_OVERRIDE;
michael@0 291 /**
michael@0 292 * See ISurfaceAllocator.h
michael@0 293 * Can be used from any thread.
michael@0 294 * If used outside the ImageBridgeChild thread, it will proxy a synchronous
michael@0 295 * call on the ImageBridgeChild thread.
michael@0 296 */
michael@0 297 virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem);
michael@0 298
michael@0 299 virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
michael@0 300 TextureFlags aFlags) MOZ_OVERRIDE;
michael@0 301
michael@0 302 virtual bool IsSameProcess() const MOZ_OVERRIDE;
michael@0 303
michael@0 304 void AllocGrallocBufferNow(const gfx::IntSize& aSize,
michael@0 305 uint32_t aFormat, uint32_t aUsage,
michael@0 306 MaybeMagicGrallocBufferHandle* aHandle,
michael@0 307 PGrallocBufferChild** aChild);
michael@0 308
michael@0 309 void MarkShutDown();
michael@0 310 protected:
michael@0 311 ImageBridgeChild();
michael@0 312 bool DispatchAllocShmemInternal(size_t aSize,
michael@0 313 SharedMemory::SharedMemoryType aType,
michael@0 314 Shmem* aShmem,
michael@0 315 bool aUnsafe);
michael@0 316
michael@0 317 CompositableTransaction* mTxn;
michael@0 318 bool mShuttingDown;
michael@0 319
michael@0 320 // ISurfaceAllocator
michael@0 321 virtual PGrallocBufferChild* AllocGrallocBuffer(const gfx::IntSize& aSize,
michael@0 322 uint32_t aFormat, uint32_t aUsage,
michael@0 323 MaybeMagicGrallocBufferHandle* aHandle) MOZ_OVERRIDE;
michael@0 324
michael@0 325 virtual void DeallocGrallocBuffer(PGrallocBufferChild* aChild) MOZ_OVERRIDE;
michael@0 326 };
michael@0 327
michael@0 328 } // layers
michael@0 329 } // mozilla
michael@0 330
michael@0 331 #endif

mercurial