LCOV - code coverage report
Current view: top level - gfx/layers/client - TextureClient.h (source / functions) Hit Total Coverage
Test: output.info Lines: 37 87 42.5 %
Date: 2017-07-14 16:53:18 Functions: 23 65 35.4 %
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_TEXTURECLIENT_H
       7             : #define MOZILLA_GFX_TEXTURECLIENT_H
       8             : 
       9             : #include <stddef.h>                     // for size_t
      10             : #include <stdint.h>                     // for uint32_t, uint8_t, uint64_t
      11             : #include "GLTextureImage.h"             // for TextureImage
      12             : #include "ImageTypes.h"                 // for StereoMode
      13             : #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
      14             : #include "mozilla/Attributes.h"         // for override
      15             : #include "mozilla/DebugOnly.h"
      16             : #include "mozilla/RefPtr.h"             // for RefPtr, RefCounted
      17             : #include "mozilla/gfx/2D.h"             // for DrawTarget
      18             : #include "mozilla/gfx/Point.h"          // for IntSize
      19             : #include "mozilla/gfx/Types.h"          // for SurfaceFormat
      20             : #include "mozilla/ipc/Shmem.h"          // for Shmem
      21             : #include "mozilla/layers/AtomicRefCountedWithFinalize.h"
      22             : #include "mozilla/layers/CompositorTypes.h"  // for TextureFlags, etc
      23             : #include "mozilla/layers/ISurfaceAllocator.h"
      24             : #include "mozilla/layers/LayersTypes.h"
      25             : #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
      26             : #include "mozilla/mozalloc.h"           // for operator delete
      27             : #include "mozilla/gfx/CriticalSection.h"
      28             : #include "mozilla/webrender/WebRenderTypes.h"
      29             : #include "nsCOMPtr.h"                   // for already_AddRefed
      30             : #include "nsISupportsImpl.h"            // for TextureImage::AddRef, etc
      31             : #include "GfxTexturesReporter.h"
      32             : #include "pratom.h"
      33             : #include "nsThreadUtils.h"
      34             : 
      35             : class gfxImageSurface;
      36             : struct ID3D11Device;
      37             : 
      38             : namespace mozilla {
      39             : 
      40             : // When defined, we track which pool the tile came from and test for
      41             : // any inconsistencies.  This can be defined in release build as well.
      42             : #ifdef DEBUG
      43             : #define GFX_DEBUG_TRACK_CLIENTS_IN_POOL 1
      44             : #endif
      45             : 
      46             : namespace layers {
      47             : 
      48             : class AsyncTransactionWaiter;
      49             : class BufferTextureData;
      50             : class CompositableForwarder;
      51             : class KnowsCompositor;
      52             : class LayersIPCChannel;
      53             : class CompositableClient;
      54             : struct PlanarYCbCrData;
      55             : class Image;
      56             : class PTextureChild;
      57             : class TextureChild;
      58             : class TextureData;
      59             : class GPUVideoTextureData;
      60             : struct RawTextureBuffer;
      61             : class RawYCbCrTextureBuffer;
      62             : class TextureClient;
      63             : class ITextureClientRecycleAllocator;
      64             : #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
      65             : class TextureClientPool;
      66             : #endif
      67             : class TextureForwarder;
      68             : class KeepAlive;
      69             : 
      70             : /**
      71             :  * TextureClient is the abstraction that allows us to share data between the
      72             :  * content and the compositor side.
      73             :  */
      74             : 
      75             : enum TextureAllocationFlags {
      76             :   ALLOC_DEFAULT = 0,
      77             :   ALLOC_CLEAR_BUFFER = 1 << 1,  // Clear the buffer to whatever is best for the draw target
      78             :   ALLOC_CLEAR_BUFFER_WHITE = 1 << 2,  // explicit all white
      79             :   ALLOC_CLEAR_BUFFER_BLACK = 1 << 3,  // explicit all black
      80             :   ALLOC_DISALLOW_BUFFERTEXTURECLIENT = 1 << 4,
      81             : 
      82             :   // Allocate the texture for out-of-band content updates. This is mostly for
      83             :   // TextureClientD3D11, which may otherwise choose D3D10 or non-KeyedMutex
      84             :   // surfaces when used on the main thread.
      85             :   ALLOC_FOR_OUT_OF_BAND_CONTENT = 1 << 5,
      86             : 
      87             :   // Disable any cross-device synchronization. This is also for TextureClientD3D11,
      88             :   // and creates a texture without KeyedMutex.
      89             :   ALLOC_MANUAL_SYNCHRONIZATION = 1 << 6,
      90             : 
      91             :   // The texture is going to be updated using UpdateFromSurface and needs to support
      92             :   // that call.
      93             :   ALLOC_UPDATE_FROM_SURFACE = 1 << 7,
      94             : };
      95             : 
      96             : #ifdef XP_WIN
      97             : typedef void* SyncHandle;
      98             : #else
      99             : typedef uintptr_t SyncHandle;
     100             : #endif // XP_WIN
     101             : 
     102             : class SyncObject : public RefCounted<SyncObject>
     103             : {
     104             : public:
     105             :   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SyncObject)
     106             :   virtual ~SyncObject() { }
     107             : 
     108             :   static already_AddRefed<SyncObject> CreateSyncObject(SyncHandle aHandle
     109             : #ifdef XP_WIN
     110             :                                                        , ID3D11Device* aDevice = nullptr
     111             : #endif
     112             :                                                        );
     113             : 
     114             :   enum class SyncType {
     115             :     D3D11,
     116             :   };
     117             : 
     118             :   virtual SyncType GetSyncType() = 0;
     119             :   virtual void FinalizeFrame() = 0;
     120             :   virtual bool IsSyncObjectValid() = 0;
     121             : 
     122             : protected:
     123             :   SyncObject() { }
     124             : };
     125             : 
     126             : /**
     127             :  * This class may be used to asynchronously receive an update when the content
     128             :  * drawn to this texture client is available for reading in CPU memory. This
     129             :  * can only be used on texture clients that support draw target creation.
     130             :  */
     131           0 : class TextureReadbackSink
     132             : {
     133           0 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureReadbackSink)
     134             : public:
     135             :   /**
     136             :    * Callback function to implement in order to receive a DataSourceSurface
     137             :    * containing the data read back from the texture client. This will always
     138             :    * be called on the main thread, and this may not hold on to the
     139             :    * DataSourceSurface beyond the execution of this function.
     140             :    */
     141             :   virtual void ProcessReadback(gfx::DataSourceSurface *aSourceSurface) = 0;
     142             : 
     143             : protected:
     144           0 :   virtual ~TextureReadbackSink() {}
     145             : };
     146             : 
     147             : enum class BackendSelector
     148             : {
     149             :   Content,
     150             :   Canvas
     151             : };
     152             : 
     153             : /// Temporary object providing direct access to a Texture's memory.
     154             : ///
     155             : /// see TextureClient::CanExposeMappedData() and TextureClient::BorrowMappedData().
     156           0 : struct MappedTextureData
     157             : {
     158             :   uint8_t* data;
     159             :   gfx::IntSize size;
     160             :   int32_t stride;
     161             :   gfx::SurfaceFormat format;
     162             : };
     163             : 
     164           0 : struct MappedYCbCrChannelData
     165             : {
     166             :   uint8_t* data;
     167             :   gfx::IntSize size;
     168             :   int32_t stride;
     169             :   int32_t skip;
     170             : 
     171             :   bool CopyInto(MappedYCbCrChannelData& aDst);
     172             : };
     173             : 
     174           0 : struct MappedYCbCrTextureData {
     175             :   MappedYCbCrChannelData y;
     176             :   MappedYCbCrChannelData cb;
     177             :   MappedYCbCrChannelData cr;
     178             :   // Sad but because of how SharedPlanarYCbCrData is used we have to expose this for now.
     179             :   uint8_t* metadata;
     180             :   StereoMode stereoMode;
     181             : 
     182           0 :   bool CopyInto(MappedYCbCrTextureData& aDst)
     183             :   {
     184           0 :     return y.CopyInto(aDst.y)
     185           0 :         && cb.CopyInto(aDst.cb)
     186           0 :         && cr.CopyInto(aDst.cr);
     187             :   }
     188             : };
     189             : 
     190             : class ReadLockDescriptor;
     191             : class NonBlockingTextureReadLock;
     192             : 
     193             : // A class to help implement copy-on-write semantics for shared textures.
     194             : //
     195             : // A TextureClient/Host pair can opt into using a ReadLock by calling
     196             : // TextureClient::EnableReadLock. This will equip the TextureClient with a
     197             : // ReadLock object that will be automatically ReadLock()'ed by the texture itself
     198             : // when it is written into (see TextureClient::Unlock).
     199             : // A TextureReadLock's counter starts at 1 and is expected to be equal to 1 when the
     200             : // lock is destroyed. See ShmemTextureReadLock for explanations about why we use
     201             : // 1 instead of 0 as the initial state.
     202             : // TextureReadLock is mostly internally managed by the TextureClient/Host pair,
     203             : // and the compositable only has to forward it during updates. If an update message
     204             : // contains a null_t lock, it means that the texture was not written into on the
     205             : // content side, and there is no synchronization required on the compositor side
     206             : // (or it means that the texture pair did not opt into using ReadLocks).
     207             : // On the compositor side, the TextureHost can receive a ReadLock during a
     208             : // transaction, and will both ReadUnlock() it and drop it as soon as the shared
     209             : // data is available again for writing (the texture upload is done, or the compositor
     210             : // not reading the texture anymore). The lock is dropped to make sure it is
     211             : // ReadUnlock()'ed only once.
     212          42 : class TextureReadLock {
     213             : protected:
     214          37 :   virtual ~TextureReadLock() {}
     215             : 
     216             : public:
     217         145 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureReadLock)
     218             : 
     219             :   virtual bool ReadLock() = 0;
     220           0 :   virtual bool TryReadLock(TimeDuration aTimeout) { return ReadLock(); }
     221             :   virtual int32_t ReadUnlock() = 0;
     222             :   virtual bool IsValid() const = 0;
     223             : 
     224             :   static already_AddRefed<TextureReadLock>
     225             :   Deserialize(const ReadLockDescriptor& aDescriptor, ISurfaceAllocator* aAllocator);
     226             : 
     227             :   virtual bool Serialize(ReadLockDescriptor& aOutput, base::ProcessId aOther) = 0;
     228             : 
     229             :   enum LockType {
     230             :     TYPE_NONBLOCKING_MEMORY,
     231             :     TYPE_NONBLOCKING_SHMEM,
     232             :     TYPE_CROSS_PROCESS_SEMAPHORE
     233             :   };
     234             :   virtual LockType GetType() = 0;
     235             : 
     236          34 :   virtual NonBlockingTextureReadLock* AsNonBlockingLock() { return nullptr; }
     237             : 
     238             : protected:
     239             :   NS_DECL_OWNINGTHREAD
     240             : };
     241             : 
     242           0 : class NonBlockingTextureReadLock : public TextureReadLock {
     243             : public:
     244             :   virtual int32_t GetReadCount() = 0;
     245             : 
     246             :   static already_AddRefed<TextureReadLock>
     247             :   Create(LayersIPCChannel* aAllocator);
     248             : 
     249           0 :   virtual NonBlockingTextureReadLock* AsNonBlockingLock() override { return this; }
     250             : };
     251             : 
     252             : #ifdef XP_WIN
     253             : class D3D11TextureData;
     254             : #endif
     255             : 
     256             : class TextureData {
     257             : public:
     258             :   struct Info {
     259             :     gfx::IntSize size;
     260             :     gfx::SurfaceFormat format;
     261             :     bool hasIntermediateBuffer;
     262             :     bool hasSynchronization;
     263             :     bool supportsMoz2D;
     264             :     bool canExposeMappedData;
     265             : 
     266           9 :     Info()
     267           9 :     : format(gfx::SurfaceFormat::UNKNOWN)
     268             :     , hasIntermediateBuffer(false)
     269             :     , hasSynchronization(false)
     270             :     , supportsMoz2D(false)
     271           9 :     , canExposeMappedData(false)
     272           9 :     {}
     273             :   };
     274             : 
     275           9 :   TextureData() { MOZ_COUNT_CTOR(TextureData); }
     276             : 
     277           6 :   virtual ~TextureData() { MOZ_COUNT_DTOR(TextureData); }
     278             : 
     279             :   virtual void FillInfo(TextureData::Info& aInfo) const = 0;
     280             : 
     281             :   virtual bool Lock(OpenMode aMode) = 0;
     282             : 
     283             :   virtual void Unlock() = 0;
     284             : 
     285           0 :   virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() { return nullptr; }
     286             : 
     287           0 :   virtual bool BorrowMappedData(MappedTextureData&) { return false; }
     288             : 
     289           0 :   virtual bool BorrowMappedYCbCrData(MappedYCbCrTextureData&) { return false; }
     290             : 
     291             :   virtual void Deallocate(LayersIPCChannel* aAllocator) = 0;
     292             : 
     293             :   /// Depending on the texture's flags either Deallocate or Forget is called.
     294           6 :   virtual void Forget(LayersIPCChannel* aAllocator) {}
     295             : 
     296             :   virtual bool Serialize(SurfaceDescriptor& aDescriptor) = 0;
     297             : 
     298             :   virtual TextureData*
     299           0 :   CreateSimilar(LayersIPCChannel* aAllocator,
     300             :                 LayersBackend aLayersBackend,
     301             :                 TextureFlags aFlags = TextureFlags::DEFAULT,
     302           0 :                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const { return nullptr; }
     303             : 
     304           0 :   virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) { return false; };
     305             : 
     306           0 :   virtual bool ReadBack(TextureReadbackSink* aReadbackSink) { return false; }
     307             : 
     308          33 :   virtual void SyncWithObject(SyncObject* aFence) {};
     309             : 
     310           9 :   virtual TextureFlags GetTextureFlags() const { return TextureFlags::NO_FLAGS; }
     311             : 
     312             : #ifdef XP_WIN
     313             :   virtual D3D11TextureData* AsD3D11TextureData() {
     314             :     return nullptr;
     315             :   }
     316             : #endif
     317             : 
     318           0 :   virtual BufferTextureData* AsBufferTextureData() { return nullptr; }
     319             : 
     320           0 :   virtual GPUVideoTextureData* AsGPUVideoTextureData() { return nullptr; }
     321             : };
     322             : 
     323             : /**
     324             :  * TextureClient is a thin abstraction over texture data that need to be shared
     325             :  * between the content process and the compositor process. It is the
     326             :  * content-side half of a TextureClient/TextureHost pair. A corresponding
     327             :  * TextureHost lives on the compositor-side.
     328             :  *
     329             :  * TextureClient's primary purpose is to present texture data in a way that is
     330             :  * understood by the IPC system. There are two ways to use it:
     331             :  * - Use it to serialize image data that is not IPC-friendly (most likely
     332             :  * involving a copy into shared memory)
     333             :  * - preallocate it and paint directly into it, which avoids copy but requires
     334             :  * the painting code to be aware of TextureClient (or at least the underlying
     335             :  * shared memory).
     336             :  *
     337             :  * There is always one and only one TextureClient per TextureHost, and the
     338             :  * TextureClient/Host pair only owns one buffer of image data through its
     339             :  * lifetime. This means that the lifetime of the underlying shared data
     340             :  * matches the lifetime of the TextureClient/Host pair. It also means
     341             :  * TextureClient/Host do not implement double buffering, which is the
     342             :  * responsibility of the compositable (which would use two Texture pairs).
     343             :  * In order to send several different buffers to the compositor side, use
     344             :  * several TextureClients.
     345             :  */
     346             : class TextureClient
     347             :   : public AtomicRefCountedWithFinalize<TextureClient>
     348             : {
     349             : public:
     350             :   explicit TextureClient(TextureData* aData, TextureFlags aFlags, LayersIPCChannel* aAllocator);
     351             : 
     352             :   virtual ~TextureClient();
     353             : 
     354             :   static already_AddRefed<TextureClient>
     355             :   CreateWithData(TextureData* aData, TextureFlags aFlags, LayersIPCChannel* aAllocator);
     356             : 
     357             :   // Creates and allocates a TextureClient usable with Moz2D.
     358             :   static already_AddRefed<TextureClient>
     359             :   CreateForDrawing(KnowsCompositor* aAllocator,
     360             :                    gfx::SurfaceFormat aFormat,
     361             :                    gfx::IntSize aSize,
     362             :                    BackendSelector aSelector,
     363             :                    TextureFlags aTextureFlags,
     364             :                    TextureAllocationFlags flags = ALLOC_DEFAULT);
     365             : 
     366             :   static already_AddRefed<TextureClient>
     367             :   CreateFromSurface(KnowsCompositor* aAllocator,
     368             :                     gfx::SourceSurface* aSurface,
     369             :                     BackendSelector aSelector,
     370             :                     TextureFlags aTextureFlags,
     371             :                     TextureAllocationFlags aAllocFlags);
     372             : 
     373             :   // Creates and allocates a TextureClient supporting the YCbCr format.
     374             :   static already_AddRefed<TextureClient>
     375             :   CreateForYCbCr(KnowsCompositor* aAllocator,
     376             :                  gfx::IntSize aYSize,
     377             :                  gfx::IntSize aCbCrSize,
     378             :                  StereoMode aStereoMode,
     379             :                  YUVColorSpace aYUVColorSpace,
     380             :                  TextureFlags aTextureFlags);
     381             : 
     382             :   // Creates and allocates a TextureClient (can be accessed through raw
     383             :   // pointers).
     384             :   static already_AddRefed<TextureClient>
     385             :   CreateForRawBufferAccess(KnowsCompositor* aAllocator,
     386             :                            gfx::SurfaceFormat aFormat,
     387             :                            gfx::IntSize aSize,
     388             :                            gfx::BackendType aMoz2dBackend,
     389             :                            TextureFlags aTextureFlags,
     390             :                            TextureAllocationFlags flags = ALLOC_DEFAULT);
     391             : 
     392             :   // Creates and allocates a TextureClient (can beaccessed through raw
     393             :   // pointers) with a certain buffer size. It's unfortunate that we need this.
     394             :   // providing format and sizes could let us do more optimization.
     395             :   static already_AddRefed<TextureClient>
     396             :   CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
     397             :                                size_t aSize,
     398             :                                YUVColorSpace aYUVColorSpace,
     399             :                                TextureFlags aTextureFlags);
     400             : 
     401             :   // Creates and allocates a TextureClient of the same type.
     402             :   already_AddRefed<TextureClient>
     403             :   CreateSimilar(LayersBackend aLayersBackend = LayersBackend::LAYERS_NONE,
     404             :                 TextureFlags aFlags = TextureFlags::DEFAULT,
     405             :                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const;
     406             : 
     407             :   /**
     408             :    * Locks the shared data, allowing the caller to get access to it.
     409             :    *
     410             :    * Please always lock/unlock when accessing the shared data.
     411             :    * If Lock() returns false, you should not attempt to access the shared data.
     412             :    */
     413             :   bool Lock(OpenMode aMode);
     414             : 
     415             :   void Unlock();
     416             : 
     417          58 :   bool IsLocked() const { return mIsLocked; }
     418             : 
     419          33 :   gfx::IntSize GetSize() const { return mInfo.size; }
     420             : 
     421         150 :   gfx::SurfaceFormat GetFormat() const { return mInfo.format; }
     422             : 
     423             :   /**
     424             :    * Returns true if this texture has a synchronization mechanism (mutex, fence, etc.).
     425             :    * Textures that do not implement synchronization should be immutable or should
     426             :    * use immediate uploads (see TextureFlags in CompositorTypes.h)
     427             :    * Even if a texture does not implement synchronization, Lock and Unlock need
     428             :    * to be used appropriately since the latter are also there to map/numap data.
     429             :    */
     430           0 :   bool HasSynchronization() const { return mInfo.hasSynchronization; }
     431             : 
     432             :   /**
     433             :    * Indicates whether the TextureClient implementation is backed by an
     434             :    * in-memory buffer. The consequence of this is that locking the
     435             :    * TextureClient does not contend with locking the texture on the host side.
     436             :    */
     437           0 :   bool HasIntermediateBuffer() const { return mInfo.hasIntermediateBuffer; }
     438             : 
     439          47 :   bool CanExposeDrawTarget() const { return mInfo.supportsMoz2D; }
     440             : 
     441             :   bool CanExposeMappedData() const { return mInfo.canExposeMappedData; }
     442             : 
     443             :   /**
     444             :    * Returns a DrawTarget to draw into the TextureClient.
     445             :    * This function should never be called when not on the main thread!
     446             :    *
     447             :    * This must never be called on a TextureClient that is not sucessfully locked.
     448             :    * When called several times within one Lock/Unlock pair, this method should
     449             :    * return the same DrawTarget.
     450             :    * The DrawTarget is automatically flushed by the TextureClient when the latter
     451             :    * is unlocked, and the DrawTarget that will be returned within the next
     452             :    * lock/unlock pair may or may not be the same object.
     453             :    * Do not keep references to the DrawTarget outside of the lock/unlock pair.
     454             :    *
     455             :    * This is typically used as follows:
     456             :    *
     457             :    * if (!texture->Lock(OpenMode::OPEN_READ_WRITE)) {
     458             :    *   return false;
     459             :    * }
     460             :    * {
     461             :    *   // Restrict this code's scope to ensure all references to dt are gone
     462             :    *   // when Unlock is called.
     463             :    *   DrawTarget* dt = texture->BorrowDrawTarget();
     464             :    *   // use the draw target ...
     465             :    * }
     466             :    * texture->Unlock();
     467             :    *
     468             :    */
     469             :   gfx::DrawTarget* BorrowDrawTarget();
     470             : 
     471             :   /**
     472             :    * Similar to BorrowDrawTarget but provides direct access to the texture's bits
     473             :    * instead of a DrawTarget.
     474             :    */
     475             :   bool BorrowMappedData(MappedTextureData&);
     476             :   bool BorrowMappedYCbCrData(MappedYCbCrTextureData&);
     477             : 
     478             :   /**
     479             :    * This function can be used to update the contents of the TextureClient
     480             :    * off the main thread.
     481             :    */
     482             :   void UpdateFromSurface(gfx::SourceSurface* aSurface);
     483             : 
     484             :   /**
     485             :    * This method is strictly for debugging. It causes locking and
     486             :    * needless copies.
     487             :    */
     488             :   already_AddRefed<gfx::DataSourceSurface> GetAsSurface();
     489             : 
     490             :   virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
     491             : 
     492             :   /**
     493             :    * Copies a rectangle from this texture client to a position in aTarget.
     494             :    * It is assumed that the necessary locks are in place; so this should at
     495             :    * least have a read lock and aTarget should at least have a write lock.
     496             :    */
     497             :   bool CopyToTextureClient(TextureClient* aTarget,
     498             :                            const gfx::IntRect* aRect,
     499             :                            const gfx::IntPoint* aPoint);
     500             : 
     501             :   /**
     502             :    * Allocate and deallocate a TextureChild actor.
     503             :    *
     504             :    * TextureChild is an implementation detail of TextureClient that is not
     505             :    * exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor
     506             :    * are for use with the managing IPDL protocols only (so that they can
     507             :    * implement AllocPextureChild and DeallocPTextureChild).
     508             :    */
     509             :   static PTextureChild* CreateIPDLActor();
     510             :   static bool DestroyIPDLActor(PTextureChild* actor);
     511             : 
     512             :   /**
     513             :    * Get the TextureClient corresponding to the actor passed in parameter.
     514             :    */
     515             :   static already_AddRefed<TextureClient> AsTextureClient(PTextureChild* actor);
     516             : 
     517             :   /**
     518             :    * TextureFlags contain important information about various aspects
     519             :    * of the texture, like how its liferime is managed, and how it
     520             :    * should be displayed.
     521             :    * See TextureFlags in CompositorTypes.h.
     522             :    */
     523          51 :   TextureFlags GetFlags() const { return mFlags; }
     524             : 
     525           0 :   bool HasFlags(TextureFlags aFlags) const
     526             :   {
     527           0 :     return (mFlags & aFlags) == aFlags;
     528             :   }
     529             : 
     530             :   void AddFlags(TextureFlags aFlags);
     531             : 
     532             :   void RemoveFlags(TextureFlags aFlags);
     533             : 
     534             :   // Must not be called when TextureClient is in use by CompositableClient.
     535             :   void RecycleTexture(TextureFlags aFlags);
     536             : 
     537             :   /**
     538             :    * After being shared with the compositor side, an immutable texture is never
     539             :    * modified, it can only be read. It is safe to not Lock/Unlock immutable
     540             :    * textures.
     541             :    */
     542           0 :   bool IsImmutable() const { return !!(mFlags & TextureFlags::IMMUTABLE); }
     543             : 
     544           0 :   void MarkImmutable() { AddFlags(TextureFlags::IMMUTABLE); }
     545             : 
     546             :   bool IsSharedWithCompositor() const;
     547             : 
     548             :   /**
     549             :    * If this method returns false users of TextureClient are not allowed
     550             :    * to access the shared data.
     551             :    */
     552         359 :   bool IsValid() const { return !!mData; }
     553             : 
     554             :   /**
     555             :    * Called when TextureClient is added to CompositableClient.
     556             :    */
     557             :   void SetAddedToCompositableClient();
     558             : 
     559             :   /**
     560             :    * If this method retuns false, TextureClient is already added to CompositableClient,
     561             :    * since its creation or recycling.
     562             :    */
     563           0 :   bool IsAddedToCompositableClient() const { return mAddedToCompositableClient; }
     564             : 
     565             :   /**
     566             :   * Create and init the TextureChild/Parent IPDL actor pair
     567             :   * with a CompositableForwarder.
     568             :   *
     569             :   * Should be called only once per TextureClient.
     570             :   * The TextureClient must not be locked when calling this method.
     571             :   */
     572             :   bool InitIPDLActor(CompositableForwarder* aForwarder);
     573             : 
     574             :   /**
     575             :    * Create and init the TextureChild/Parent IPDL actor pair
     576             :    * with a TextureForwarder.
     577             :    *
     578             :    * Should be called only once per TextureClient.
     579             :    * The TextureClient must not be locked when calling this method.
     580             :    */
     581             :   bool InitIPDLActor(KnowsCompositor* aForwarder);
     582             : 
     583             :   /**
     584             :    * Return a pointer to the IPDLActor.
     585             :    *
     586             :    * This is to be used with IPDL messages only. Do not store the returned
     587             :    * pointer.
     588             :    */
     589             :   PTextureChild* GetIPDLActor();
     590             : 
     591             :   /**
     592             :    * Triggers the destruction of the shared data and the corresponding TextureHost.
     593             :    *
     594             :    * If the texture flags contain TextureFlags::DEALLOCATE_CLIENT, the destruction
     595             :    * will be synchronously coordinated with the compositor side, otherwise it
     596             :    * will be done asynchronously.
     597             :    */
     598             :   void Destroy();
     599             : 
     600             :   /**
     601             :    * Track how much of this texture is wasted.
     602             :    * For example we might allocate a 256x256 tile but only use 10x10.
     603             :    */
     604             :   void SetWaste(int aWasteArea) {
     605             :     mWasteTracker.Update(aWasteArea, BytesPerPixel(GetFormat()));
     606             :   }
     607             : 
     608             :   /**
     609             :    * This sets the readback sink that this texture is to use. This will
     610             :    * receive the data for this texture as soon as it becomes available after
     611             :    * texture unlock.
     612             :    */
     613           0 :   virtual void SetReadbackSink(TextureReadbackSink* aReadbackSink) {
     614           0 :     mReadbackSink = aReadbackSink;
     615           0 :   }
     616             : 
     617          33 :   void SyncWithObject(SyncObject* aFence) { mData->SyncWithObject(aFence); }
     618             : 
     619          33 :   LayersIPCChannel* GetAllocator() { return mAllocator; }
     620             : 
     621           0 :   ITextureClientRecycleAllocator* GetRecycleAllocator() { return mRecycleAllocator; }
     622             :   void SetRecycleAllocator(ITextureClientRecycleAllocator* aAllocator);
     623             : 
     624             :   /// If you add new code that uses this method, you are probably doing something wrong.
     625           0 :   TextureData* GetInternalData() { return mData; }
     626           0 :   const TextureData* GetInternalData() const { return mData; }
     627             : 
     628           0 :   uint64_t GetSerial() const { return mSerial; }
     629             : 
     630             :   void CancelWaitForRecycle();
     631             : 
     632             :   /**
     633             :    * Set last transaction id of CompositableForwarder.
     634             :    * 
     635             :    * Called when TextureClient has TextureFlags::RECYCLE flag.
     636             :    * When CompositableForwarder forwards the TextureClient with
     637             :    * TextureFlags::RECYCLE, it holds TextureClient's ref until host side
     638             :    * releases it. The host side sends TextureClient release message.
     639             :    * The id is used to check if the message is for the last TextureClient
     640             :    * forwarding.
     641             :    */
     642           0 :   void SetLastFwdTransactionId(uint64_t aTransactionId)
     643             :   {
     644           0 :     MOZ_ASSERT(mFwdTransactionId <= aTransactionId);
     645           0 :     mFwdTransactionId = aTransactionId;
     646           0 :   }
     647             : 
     648           0 :   uint64_t GetLastFwdTransactionId() { return mFwdTransactionId; }
     649             : 
     650             :   void EnableReadLock();
     651             :   void EnableBlockingReadLock();
     652             : 
     653           0 :   TextureReadLock* GetReadLock() { return mReadLock; }
     654             : 
     655             :   bool IsReadLocked() const;
     656             : 
     657             :   bool TryReadLock();
     658             :   void ReadUnlock();
     659             : 
     660             :   bool SerializeReadLock(ReadLockDescriptor& aDescriptor);
     661             : 
     662             : private:
     663             :   static void TextureClientRecycleCallback(TextureClient* aClient, void* aClosure);
     664             :  
     665             :   // Internal helpers for creating texture clients using the actual forwarder instead
     666             :   // of KnowsCompositor. TextureClientPool uses these to let it cache texture clients
     667             :   // per-process instead of per ShadowLayerForwarder, but everyone else should
     668             :   // use the public functions instead.
     669             :   friend class TextureClientPool;
     670             :   static already_AddRefed<TextureClient>
     671             :   CreateForDrawing(TextureForwarder* aAllocator,
     672             :                    gfx::SurfaceFormat aFormat,
     673             :                    gfx::IntSize aSize,
     674             :                    LayersBackend aLayersBackend,
     675             :                    int32_t aMaxTextureSize,
     676             :                    BackendSelector aSelector,
     677             :                    TextureFlags aTextureFlags,
     678             :                    TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT);
     679             :   
     680             :   static already_AddRefed<TextureClient>
     681             :   CreateForRawBufferAccess(LayersIPCChannel* aAllocator,
     682             :                            gfx::SurfaceFormat aFormat,
     683             :                            gfx::IntSize aSize,
     684             :                            gfx::BackendType aMoz2dBackend,
     685             :                            LayersBackend aLayersBackend,
     686             :                            TextureFlags aTextureFlags,
     687             :                            TextureAllocationFlags flags = ALLOC_DEFAULT);
     688             : 
     689             :   /**
     690             :    * Called once, during the destruction of the Texture, on the thread in which
     691             :    * texture's reference count reaches 0 (could be any thread).
     692             :    *
     693             :    * Here goes the shut-down code that uses virtual methods.
     694             :    * Must only be called by Release().
     695             :    */
     696           6 :   void Finalize() {}
     697             : 
     698             :   friend class AtomicRefCountedWithFinalize<TextureClient>;
     699             : protected:
     700             :   /**
     701             :    * Should only be called *once* per texture, in TextureClient::InitIPDLActor.
     702             :    * Some texture implementations rely on the fact that the descriptor will be
     703             :    * deserialized.
     704             :    * Calling ToSurfaceDescriptor again after it has already returned true,
     705             :    * or never constructing a TextureHost with aDescriptor may result in a memory
     706             :    * leak (see TextureClientD3D9 for example).
     707             :    */
     708             :   bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor);
     709             : 
     710             :   void LockActor() const;
     711             :   void UnlockActor() const;
     712             : 
     713             :   TextureData::Info mInfo;
     714             : 
     715             :   RefPtr<LayersIPCChannel> mAllocator;
     716             :   RefPtr<TextureChild> mActor;
     717             :   RefPtr<ITextureClientRecycleAllocator> mRecycleAllocator;
     718             :   RefPtr<TextureReadLock> mReadLock;
     719             : 
     720             :   TextureData* mData;
     721             :   RefPtr<gfx::DrawTarget> mBorrowedDrawTarget;
     722             : 
     723             :   TextureFlags mFlags;
     724             : 
     725             :   gl::GfxTextureWasteTracker mWasteTracker;
     726             : 
     727             :   OpenMode mOpenMode;
     728             : #ifdef DEBUG
     729             :   uint32_t mExpectedDtRefs;
     730             : #endif
     731             :   bool mIsLocked;
     732             :   bool mIsReadLocked;
     733             :   // This member tracks that the texture was written into until the update
     734             :   // is sent to the compositor. We need this remember to lock mReadLock on
     735             :   // behalf of the compositor just before sending the notification.
     736             :   bool mUpdated;
     737             : 
     738             :   // Used when TextureClient is recycled with TextureFlags::RECYCLE flag.
     739             :   bool mAddedToCompositableClient;
     740             : 
     741             :   bool mWorkaroundAnnoyingSharedSurfaceLifetimeIssues;
     742             :   bool mWorkaroundAnnoyingSharedSurfaceOwnershipIssues;
     743             : 
     744             :   RefPtr<TextureReadbackSink> mReadbackSink;
     745             : 
     746             :   uint64_t mFwdTransactionId;
     747             : 
     748             :   // Serial id of TextureClient. It is unique in current process.
     749             :   const uint64_t mSerial;
     750             : 
     751             :   // External image id. It is unique if it is allocated.
     752             :   // The id is allocated in TextureClient::InitIPDLActor().
     753             :   // Its allocation is supported by
     754             :   // CompositorBridgeChild and ImageBridgeChild for now.
     755             :   wr::MaybeExternalImageId mExternalImageId;
     756             : 
     757             :   // Used to assign serial ids of TextureClient.
     758             :   static mozilla::Atomic<uint64_t> sSerialCounter;
     759             : 
     760             :   friend class TextureChild;
     761             :   friend void TestTextureClientSurface(TextureClient*, gfxImageSurface*);
     762             :   friend void TestTextureClientYCbCr(TextureClient*, PlanarYCbCrData&);
     763             :   friend already_AddRefed<TextureHost> CreateTextureHostWithBackend(
     764             :     TextureClient*, LayersBackend&);
     765             : 
     766             : #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
     767             : public:
     768             :   // Pointer to the pool this tile came from.
     769             :   TextureClientPool* mPoolTracker;
     770             : #endif
     771             : };
     772             : 
     773             : /**
     774             :  * Task that releases TextureClient pointer on a specified thread.
     775             :  */
     776           0 : class TextureClientReleaseTask : public Runnable
     777             : {
     778             : public:
     779           0 :   explicit TextureClientReleaseTask(TextureClient* aClient)
     780           0 :     : Runnable("layers::TextureClientReleaseTask")
     781           0 :     , mTextureClient(aClient)
     782             :   {
     783           0 :     }
     784             : 
     785           0 :     NS_IMETHOD Run() override
     786             :     {
     787           0 :         mTextureClient = nullptr;
     788           0 :         return NS_OK;
     789             :     }
     790             : 
     791             : private:
     792             :     RefPtr<TextureClient> mTextureClient;
     793             : };
     794             : 
     795             : // Automatically lock and unlock a texture. Since texture locking is fallible,
     796             : // Succeeded() must be checked on the guard object before proceeding.
     797             : class MOZ_RAII TextureClientAutoLock
     798             : {
     799             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
     800             : 
     801             : public:
     802          13 :   TextureClientAutoLock(TextureClient* aTexture, OpenMode aMode
     803             :                         MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     804          13 :    : mTexture(aTexture),
     805          13 :      mSucceeded(false)
     806             :   {
     807          13 :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     808             : 
     809          13 :     mSucceeded = mTexture->Lock(aMode);
     810             : #ifdef DEBUG
     811          13 :     mChecked = false;
     812             : #endif
     813          13 :   }
     814          26 :   ~TextureClientAutoLock() {
     815          13 :     MOZ_ASSERT(mChecked);
     816          13 :     if (mSucceeded) {
     817          13 :       mTexture->Unlock();
     818             :     }
     819          13 :   }
     820             : 
     821          13 :   bool Succeeded() {
     822             : #ifdef DEBUG
     823          13 :     mChecked = true;
     824             : #endif
     825          13 :     return mSucceeded;
     826             :   }
     827             : 
     828             : private:
     829             :   TextureClient* mTexture;
     830             : #ifdef DEBUG
     831             :   bool mChecked;
     832             : #endif
     833             :   bool mSucceeded;
     834             : };
     835             : 
     836             : class KeepAlive
     837             : {
     838             : public:
     839             :   virtual ~KeepAlive() {}
     840             : };
     841             : 
     842             : template<typename T>
     843             : class TKeepAlive : public KeepAlive
     844             : {
     845             : public:
     846             :   explicit TKeepAlive(T* aData) : mData(aData) {}
     847             : protected:
     848             :   RefPtr<T> mData;
     849             : };
     850             : 
     851             : /// Convenience function to set the content of ycbcr texture.
     852             : bool UpdateYCbCrTextureClient(TextureClient* aTexture, const PlanarYCbCrData& aData);
     853             : 
     854             : } // namespace layers
     855             : } // namespace mozilla
     856             : 
     857             : #endif

Generated by: LCOV version 1.13