LCOV - code coverage report
Current view: top level - gfx/layers/ipc - ImageBridgeChild.h (source / functions) Hit Total Coverage
Test: output.info Lines: 1 14 7.1 %
Date: 2017-07-14 16:53:18 Functions: 2 12 16.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef MOZILLA_GFX_IMAGEBRIDGECHILD_H
       7             : #define MOZILLA_GFX_IMAGEBRIDGECHILD_H
       8             : 
       9             : #include <stddef.h>                     // for size_t
      10             : #include <stdint.h>                     // for uint32_t, uint64_t
      11             : #include "mozilla/Attributes.h"         // for override
      12             : #include "mozilla/Atomics.h"
      13             : #include "mozilla/RefPtr.h"             // for already_AddRefed
      14             : #include "mozilla/ipc/SharedMemory.h"   // for SharedMemory, etc
      15             : #include "mozilla/layers/CanvasClient.h"
      16             : #include "mozilla/layers/CompositableForwarder.h"
      17             : #include "mozilla/layers/CompositorTypes.h"
      18             : #include "mozilla/layers/PImageBridgeChild.h"
      19             : #include "mozilla/Mutex.h"
      20             : #include "mozilla/webrender/WebRenderTypes.h"
      21             : #include "nsDebug.h"                    // for NS_RUNTIMEABORT
      22             : #include "nsIObserver.h"
      23             : #include "nsRegion.h"                   // for nsIntRegion
      24             : #include "nsRefPtrHashtable.h"
      25             : #include "mozilla/gfx/Rect.h"
      26             : #include "mozilla/ReentrantMonitor.h"   // for ReentrantMonitor, etc
      27             : 
      28             : class MessageLoop;
      29             : 
      30             : namespace base {
      31             : class Thread;
      32             : } // namespace base
      33             : 
      34             : namespace mozilla {
      35             : namespace ipc {
      36             : class Shmem;
      37             : } // namespace ipc
      38             : 
      39             : namespace layers {
      40             : 
      41             : class AsyncCanvasRenderer;
      42             : class ImageClient;
      43             : class ImageContainer;
      44             : class ImageBridgeParent;
      45             : class CompositableClient;
      46             : struct CompositableTransaction;
      47             : class Image;
      48             : class TextureClient;
      49             : class SynchronousTask;
      50             : struct AllocShmemParams;
      51             : 
      52             : /**
      53             :  * Returns true if the current thread is the ImageBrdigeChild's thread.
      54             :  *
      55             :  * Can be called from any thread.
      56             :  */
      57             : bool InImageBridgeChildThread();
      58             : 
      59             : /**
      60             :  * The ImageBridge protocol is meant to allow ImageContainers to forward images
      61             :  * directly to the compositor thread/process without using the main thread.
      62             :  *
      63             :  * ImageBridgeChild is a CompositableForwarder just like ShadowLayerForwarder.
      64             :  * This means it also does transactions with the compositor thread/process,
      65             :  * except that the transactions are restricted to operations on the Compositables
      66             :  * and cannot contain messages affecting layers directly.
      67             :  *
      68             :  * ImageBridgeChild is also a ISurfaceAllocator. It can be used to allocate or
      69             :  * deallocate data that is shared with the compositor. The main differerence
      70             :  * with other ISurfaceAllocators is that some of its overriden methods can be
      71             :  * invoked from any thread.
      72             :  *
      73             :  * There are three important phases in the ImageBridge protocol. These three steps
      74             :  * can do different things depending if (A) the ImageContainer uses ImageBridge
      75             :  * or (B) it does not use ImageBridge:
      76             :  *
      77             :  * - When an ImageContainer calls its method SetCurrentImage:
      78             :  *   - (A) The image is sent directly to the compositor process through the
      79             :  *   ImageBridge IPDL protocol.
      80             :  *   On the compositor side the image is stored in a global table that associates
      81             :  *   the image with an ID corresponding to the ImageContainer, and a composition is
      82             :  *   triggered.
      83             :  *   - (B) Since it does not have an ImageBridge, the image is not sent yet.
      84             :  *   instead the will be sent to the compositor during the next layer transaction
      85             :  *   (on the main thread).
      86             :  *
      87             :  * - During a Layer transaction:
      88             :  *   - (A) The ImageContainer uses ImageBridge. The image is already available to the
      89             :  *   compositor process because it has been sent with SetCurrentImage. Yet, the
      90             :  *   CompositableHost on the compositor side will needs the ID referring to the
      91             :  *   ImageContainer to access the Image. So during the Swap operation that happens
      92             :  *   in the transaction, we swap the container ID rather than the image data.
      93             :  *   - (B) Since the ImageContainer does not use ImageBridge, the image data is swaped.
      94             :  *
      95             :  * - During composition:
      96             :  *   - (A) The CompositableHost has an AsyncID, it looks up the ID in the 
      97             :  *   global table to see if there is an image. If there is no image, nothing is rendered.
      98             :  *   - (B) The CompositableHost has image data rather than an ID (meaning it is not
      99             :  *   using ImageBridge), then it just composites the image data normally.
     100             :  *
     101             :  * This means that there might be a possibility for the ImageBridge to send the first
     102             :  * frame before the first layer transaction that will pass the container ID to the
     103             :  * CompositableHost happens. In this (unlikely) case the layer is not composited
     104             :  * until the layer transaction happens. This means this scenario is not harmful.
     105             :  *
     106             :  * Since sending an image through imageBridge triggers compositing, the main thread is
     107             :  * not used at all (except for the very first transaction that provides the
     108             :  * CompositableHost with an AsyncID).
     109             :  */
     110             : class ImageBridgeChild final : public PImageBridgeChild
     111             :                              , public CompositableForwarder
     112             :                              , public TextureForwarder
     113             : {
     114             :   friend class ImageContainer;
     115             : 
     116             :   typedef InfallibleTArray<AsyncParentMessageData> AsyncParentMessageArray;
     117             : public:
     118          32 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageBridgeChild, override);
     119             : 
     120           0 :   TextureForwarder* GetTextureForwarder() override { return this; }
     121           0 :   LayersIPCActor* GetLayersIPCActor() override { return this; }
     122             : 
     123             :   /**
     124             :    * Creates the image bridge with a dedicated thread for ImageBridgeChild.
     125             :    *
     126             :    * We may want to use a specifi thread in the future. In this case, use
     127             :    * CreateWithThread instead.
     128             :    */
     129             :   static void InitSameProcess(uint32_t aNamespace);
     130             : 
     131             :   static void InitWithGPUProcess(Endpoint<PImageBridgeChild>&& aEndpoint, uint32_t aNamespace);
     132             :   static bool InitForContent(Endpoint<PImageBridgeChild>&& aEndpoint, uint32_t aNamespace);
     133             :   static bool ReinitForContent(Endpoint<PImageBridgeChild>&& aEndpoint, uint32_t aNamespace);
     134             : 
     135             :   /**
     136             :    * Destroys the image bridge by calling DestroyBridge, and destroys the
     137             :    * ImageBridge's thread.
     138             :    *
     139             :    * If you don't want to destroy the thread, call DestroyBridge directly
     140             :    * instead.
     141             :    */
     142             :   static void ShutDown();
     143             : 
     144             :   /**
     145             :    * returns the singleton instance.
     146             :    *
     147             :    * can be called from any thread.
     148             :    */
     149             :   static RefPtr<ImageBridgeChild> GetSingleton();
     150             : 
     151             : 
     152             :   static void IdentifyCompositorTextureHost(const TextureFactoryIdentifier& aIdentifier);
     153             : 
     154             :   void BeginTransaction();
     155             :   void EndTransaction();
     156             : 
     157             :   /**
     158             :    * Returns the ImageBridgeChild's thread.
     159             :    *
     160             :    * Can be called from any thread.
     161             :    */
     162             :   base::Thread * GetThread() const;
     163             : 
     164             :   /**
     165             :    * Returns the ImageBridgeChild's message loop.
     166             :    *
     167             :    * Can be called from any thread.
     168             :    */
     169             :   virtual MessageLoop * GetMessageLoop() const override;
     170             : 
     171           0 :   virtual base::ProcessId GetParentPid() const override { return OtherPid(); }
     172             : 
     173             :   virtual PTextureChild*
     174             :   AllocPTextureChild(const SurfaceDescriptor& aSharedData,
     175             :                      const LayersBackend& aLayersBackend,
     176             :                      const TextureFlags& aFlags,
     177             :                      const uint64_t& aSerial,
     178             :                      const wr::MaybeExternalImageId& aExternalImageId) override;
     179             : 
     180             :   virtual bool
     181             :   DeallocPTextureChild(PTextureChild* actor) override;
     182             : 
     183             :   PMediaSystemResourceManagerChild*
     184             :   AllocPMediaSystemResourceManagerChild() override;
     185             :   bool
     186             :   DeallocPMediaSystemResourceManagerChild(PMediaSystemResourceManagerChild* aActor) override;
     187             : 
     188             :   virtual mozilla::ipc::IPCResult
     189             :   RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages) override;
     190             : 
     191             :   virtual mozilla::ipc::IPCResult
     192             :   RecvDidComposite(InfallibleTArray<ImageCompositeNotification>&& aNotifications) override;
     193             : 
     194             :   // Create an ImageClient from any thread.
     195             :   RefPtr<ImageClient> CreateImageClient(
     196             :     CompositableType aType,
     197             :     ImageContainer* aImageContainer);
     198             : 
     199             :   // Create an ImageClient from the ImageBridge thread.
     200             :   RefPtr<ImageClient> CreateImageClientNow(
     201             :     CompositableType aType,
     202             :     ImageContainer* aImageContainer);
     203             : 
     204             :   already_AddRefed<CanvasClient> CreateCanvasClient(CanvasClient::CanvasClientType aType,
     205             :                                                     TextureFlags aFlag);
     206             :   void UpdateAsyncCanvasRenderer(AsyncCanvasRenderer* aClient);
     207             :   void UpdateImageClient(RefPtr<ImageClient> aClient, RefPtr<ImageContainer> aContainer);
     208             :   static void DispatchReleaseTextureClient(TextureClient* aClient);
     209             : 
     210             :   /**
     211             :    * Flush all Images sent to CompositableHost.
     212             :    */
     213             :   void FlushAllImages(ImageClient* aClient, ImageContainer* aContainer);
     214             : 
     215           0 :   virtual bool IPCOpen() const override { return mCanSend; }
     216             : 
     217             : private:
     218             : 
     219             :   /**
     220             :    * This must be called by the static function DeleteImageBridgeSync defined
     221             :    * in ImageBridgeChild.cpp ONLY.
     222             :    */
     223             :   ~ImageBridgeChild();
     224             : 
     225             :   // Helpers for dispatching.
     226             :   already_AddRefed<CanvasClient> CreateCanvasClientNow(
     227             :     CanvasClient::CanvasClientType aType,
     228             :     TextureFlags aFlags);
     229             :   void CreateCanvasClientSync(
     230             :     SynchronousTask* aTask,
     231             :     CanvasClient::CanvasClientType aType,
     232             :     TextureFlags aFlags,
     233             :     RefPtr<CanvasClient>* const outResult);
     234             : 
     235             :   void CreateImageClientSync(
     236             :     SynchronousTask* aTask,
     237             :     RefPtr<ImageClient>* result,
     238             :     CompositableType aType,
     239             :     ImageContainer* aImageContainer);
     240             : 
     241             :   void ReleaseTextureClientNow(TextureClient* aClient);
     242             : 
     243             :   void UpdateAsyncCanvasRendererNow(AsyncCanvasRenderer* aClient);
     244             :   void UpdateAsyncCanvasRendererSync(
     245             :     SynchronousTask* aTask,
     246             :     AsyncCanvasRenderer* aWrapper);
     247             : 
     248             :   void FlushAllImagesSync(
     249             :     SynchronousTask* aTask,
     250             :     ImageClient* aClient,
     251             :     ImageContainer* aContainer);
     252             : 
     253             :   void ProxyAllocShmemNow(SynchronousTask* aTask, AllocShmemParams* aParams);
     254             :   void ProxyDeallocShmemNow(SynchronousTask* aTask, Shmem* aShmem, bool* aResult);
     255             : 
     256             : public:
     257             :   // CompositableForwarder
     258             : 
     259             :   virtual void Connect(CompositableClient* aCompositable,
     260             :                        ImageContainer* aImageContainer) override;
     261             : 
     262           0 :   virtual bool UsesImageBridge() const override { return true; }
     263             : 
     264             :   /**
     265             :    * See CompositableForwarder::UseTextures
     266             :    */
     267             :   virtual void UseTextures(CompositableClient* aCompositable,
     268             :                            const nsTArray<TimedTextureClient>& aTextures) override;
     269             :   virtual void UseComponentAlphaTextures(CompositableClient* aCompositable,
     270             :                                          TextureClient* aClientOnBlack,
     271             :                                          TextureClient* aClientOnWhite) override;
     272             : 
     273             :   void ReleaseCompositable(const CompositableHandle& aHandle) override;
     274             : 
     275             :   void ForgetImageContainer(const CompositableHandle& aHandle);
     276             : 
     277             :   /**
     278             :    * Hold TextureClient ref until end of usage on host side if TextureFlags::RECYCLE is set.
     279             :    * Host side's usage is checked via CompositableRef.
     280             :    */
     281             :   void HoldUntilCompositableRefReleasedIfNecessary(TextureClient* aClient);
     282             : 
     283             :   /**
     284             :    * Notify id of Texture When host side end its use. Transaction id is used to
     285             :    * make sure if there is no newer usage.
     286             :    */
     287             :   void NotifyNotUsed(uint64_t aTextureId, uint64_t aFwdTransactionId);
     288             : 
     289             :   virtual void CancelWaitForRecycle(uint64_t aTextureId) override;
     290             : 
     291             :   virtual bool DestroyInTransaction(PTextureChild* aTexture) override;
     292             :   bool DestroyInTransaction(const CompositableHandle& aHandle);
     293             : 
     294             :   virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable,
     295             :                                              TextureClient* aTexture) override;
     296             : 
     297           0 :   virtual void UseTiledLayerBuffer(CompositableClient* aCompositable,
     298             :                                    const SurfaceDescriptorTiles& aTileLayerDescriptor) override
     299             :   {
     300           0 :     MOZ_CRASH("should not be called");
     301             :   }
     302             : 
     303           0 :   virtual void UpdateTextureRegion(CompositableClient* aCompositable,
     304             :                                    const ThebesBufferData& aThebesBufferData,
     305             :                                    const nsIntRegion& aUpdatedRegion) override {
     306           0 :     MOZ_CRASH("should not be called");
     307             :   }
     308             : 
     309             :   // ISurfaceAllocator
     310             : 
     311             :   /**
     312             :    * See ISurfaceAllocator.h
     313             :    * Can be used from any thread.
     314             :    * If used outside the ImageBridgeChild thread, it will proxy a synchronous
     315             :    * call on the ImageBridgeChild thread.
     316             :    */
     317             :   virtual bool AllocUnsafeShmem(size_t aSize,
     318             :                                 mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
     319             :                                 mozilla::ipc::Shmem* aShmem) override;
     320             :   virtual bool AllocShmem(size_t aSize,
     321             :                           mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
     322             :                           mozilla::ipc::Shmem* aShmem) override;
     323             : 
     324             :   /**
     325             :    * See ISurfaceAllocator.h
     326             :    * Can be used from any thread.
     327             :    * If used outside the ImageBridgeChild thread, it will proxy a synchronous
     328             :    * call on the ImageBridgeChild thread.
     329             :    */
     330             :   virtual bool DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
     331             : 
     332             :   virtual PTextureChild* CreateTexture(
     333             :     const SurfaceDescriptor& aSharedData,
     334             :     LayersBackend aLayersBackend,
     335             :     TextureFlags aFlags,
     336             :     uint64_t aSerial,
     337             :     wr::MaybeExternalImageId& aExternalImageId,
     338             :     nsIEventTarget* aTarget = nullptr) override;
     339             : 
     340             :   virtual bool IsSameProcess() const override;
     341             : 
     342           0 :   virtual void UpdateFwdTransactionId() override { ++mFwdTransactionId; }
     343           0 :   virtual uint64_t GetFwdTransactionId() override { return mFwdTransactionId; }
     344             : 
     345           0 :   bool InForwarderThread() override {
     346           0 :     return InImageBridgeChildThread();
     347             :   }
     348             : 
     349             :   virtual void HandleFatalError(const char* aName, const char* aMsg) const override;
     350             : 
     351             :   virtual wr::MaybeExternalImageId GetNextExternalImageId() override;
     352             : 
     353             : protected:
     354             :   explicit ImageBridgeChild(uint32_t aNamespace);
     355             :   bool DispatchAllocShmemInternal(size_t aSize,
     356             :                                   SharedMemory::SharedMemoryType aType,
     357             :                                   Shmem* aShmem,
     358             :                                   bool aUnsafe);
     359             : 
     360             :   void Bind(Endpoint<PImageBridgeChild>&& aEndpoint);
     361             :   void BindSameProcess(RefPtr<ImageBridgeParent> aParent);
     362             : 
     363             :   void SendImageBridgeThreadId();
     364             : 
     365             :   void WillShutdown();
     366             :   void ShutdownStep1(SynchronousTask* aTask);
     367             :   void ShutdownStep2(SynchronousTask* aTask);
     368             :   void MarkShutDown();
     369             : 
     370             :   void ActorDestroy(ActorDestroyReason aWhy) override;
     371             :   void DeallocPImageBridgeChild() override;
     372             : 
     373             :   bool CanSend() const;
     374             :   bool CanPostTask() const;
     375             : 
     376             :   static void ShutdownSingleton();
     377             : 
     378             : private:
     379             :   uint32_t mNamespace;
     380             : 
     381             :   CompositableTransaction* mTxn;
     382             : 
     383             :   bool mCanSend;
     384             :   mozilla::Atomic<bool> mDestroyed;
     385             : 
     386             :   /**
     387             :    * Transaction id of CompositableForwarder.
     388             :    * It is incrementaed by UpdateFwdTransactionId() in each BeginTransaction() call.
     389             :    */
     390             :   uint64_t mFwdTransactionId;
     391             : 
     392             :   /**
     393             :    * Hold TextureClients refs until end of their usages on host side.
     394             :    * It defer calling of TextureClient recycle callback.
     395             :    */
     396             :   nsRefPtrHashtable<nsUint64HashKey, TextureClient> mTexturesWaitingRecycled;
     397             : 
     398             :   /**
     399             :    * Mapping from async compositable IDs to image containers.
     400             :    */
     401             :   Mutex mContainerMapLock;
     402             :   nsDataHashtable<nsUint64HashKey, ImageContainer*> mImageContainers;
     403             : };
     404             : 
     405             : } // namespace layers
     406             : } // namespace mozilla
     407             : 
     408             : #endif

Generated by: LCOV version 1.13