tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TextureHost.h (32923B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef MOZILLA_GFX_TEXTUREHOST_H
      8 #define MOZILLA_GFX_TEXTUREHOST_H
      9 
     10 #include <stddef.h>              // for size_t
     11 #include <stdint.h>              // for uint64_t, uint32_t, uint8_t
     12 #include "mozilla/Assertions.h"  // for MOZ_ASSERT, etc
     13 #include "mozilla/Attributes.h"  // for override
     14 #include "mozilla/RefPtr.h"      // for RefPtr, already_AddRefed, etc
     15 #include "mozilla/dom/ipc/IdType.h"
     16 #include "mozilla/gfx/Logging.h"
     17 #include "mozilla/gfx/Matrix.h"
     18 #include "mozilla/gfx/Point.h"  // for IntSize, IntPoint
     19 #include "mozilla/gfx/Rect.h"
     20 #include "mozilla/gfx/Types.h"               // for SurfaceFormat, etc
     21 #include "mozilla/layers/CompositorTypes.h"  // for TextureFlags, etc
     22 #include "mozilla/layers/LayersTypes.h"      // for LayerRenderState, etc
     23 #include "mozilla/layers/LayersMessages.h"
     24 #include "mozilla/layers/LayersSurfaces.h"
     25 #include "mozilla/layers/TextureSourceProvider.h"
     26 #include "mozilla/mozalloc.h"  // for operator delete
     27 #include "mozilla/Range.h"
     28 #include "mozilla/UniquePtr.h"            // for UniquePtr
     29 #include "mozilla/UniquePtrExtensions.h"  // for UniqueFileHandle
     30 #include "mozilla/webrender/WebRenderTypes.h"
     31 #include "nsCOMPtr.h"         // for already_AddRefed
     32 #include "nsDebug.h"          // for NS_WARNING
     33 #include "nsISupportsImpl.h"  // for MOZ_COUNT_CTOR, etc
     34 #include "nsRect.h"
     35 #include "nsRegion.h"       // for nsIntRegion
     36 #include "nsTraceRefcnt.h"  // for MOZ_COUNT_CTOR, etc
     37 #include "nscore.h"         // for nsACString
     38 #include "mozilla/layers/AtomicRefCountedWithFinalize.h"
     39 
     40 class MacIOSurface;
     41 namespace mozilla {
     42 namespace gfx {
     43 class DataSourceSurface;
     44 }
     45 
     46 namespace ipc {
     47 class Shmem;
     48 }  // namespace ipc
     49 
     50 namespace wr {
     51 class DisplayListBuilder;
     52 class TransactionBuilder;
     53 }  // namespace wr
     54 
     55 namespace layers {
     56 
     57 class AndroidHardwareBuffer;
     58 class AndroidHardwareBufferTextureHost;
     59 class BufferDescriptor;
     60 class BufferTextureHost;
     61 class Compositor;
     62 class CompositableParentManager;
     63 class ReadLockDescriptor;
     64 class CompositorBridgeParent;
     65 class DXGITextureHostD3D11;
     66 class DXGIYCbCrTextureHostD3D11;
     67 class Fence;
     68 class SurfaceDescriptor;
     69 class HostIPCAllocator;
     70 class ISurfaceAllocator;
     71 class MacIOSurfaceTextureHostOGL;
     72 class ShmemTextureHost;
     73 class SurfaceTextureHost;
     74 class TextureHostOGL;
     75 class TextureReadLock;
     76 class TextureSourceOGL;
     77 class TextureSourceD3D11;
     78 class DataTextureSource;
     79 class PTextureParent;
     80 class RemoteTextureHostWrapper;
     81 class TextureParent;
     82 class WebRenderTextureHost;
     83 class WrappingTextureSourceYCbCrBasic;
     84 class TextureHostWrapperD3D11;
     85 
     86 /**
     87 * A view on a TextureHost where the texture is internally represented as tiles
     88 * (contrast with a tiled buffer, where each texture is a tile). For iteration
     89 * by the texture's buffer host. This is only useful when the underlying surface
     90 * is too big to fit in one device texture, which forces us to split it in
     91 * smaller parts. Tiled Compositable is a different thing.
     92 */
     93 class BigImageIterator {
     94 public:
     95  virtual void BeginBigImageIteration() = 0;
     96  virtual void EndBigImageIteration() {};
     97  virtual gfx::IntRect GetTileRect() = 0;
     98  virtual size_t GetTileCount() = 0;
     99  virtual bool NextTile() = 0;
    100 };
    101 
    102 /**
    103 * TextureSource is the interface for texture objects that can be composited
    104 * by a given compositor backend. Since the drawing APIs are different
    105 * between backends, the TextureSource interface is split into different
    106 * interfaces (TextureSourceOGL, etc.), and TextureSource mostly provide
    107 * access to these interfaces.
    108 *
    109 * This class is used on the compositor side.
    110 */
    111 class TextureSource : public RefCounted<TextureSource> {
    112 public:
    113  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(TextureSource)
    114 
    115  TextureSource();
    116 
    117  virtual ~TextureSource();
    118 
    119  virtual const char* Name() const = 0;
    120 
    121  /**
    122   * Should be overridden in order to deallocate the data that is associated
    123   * with the rendering backend, such as GL textures.
    124   */
    125  virtual void DeallocateDeviceData() {}
    126 
    127  /**
    128   * Return the size of the texture in texels.
    129   * If this is a tile iterator, GetSize must return the size of the current
    130   * tile.
    131   */
    132  virtual gfx::IntSize GetSize() const = 0;
    133 
    134  /**
    135   * Return the pixel format of this texture
    136   */
    137  virtual gfx::SurfaceFormat GetFormat() const {
    138    return gfx::SurfaceFormat::UNKNOWN;
    139  }
    140 
    141  /**
    142   * Cast to a TextureSource for for each backend..
    143   */
    144  virtual TextureSourceOGL* AsSourceOGL() {
    145    gfxCriticalNote << "Failed to cast " << Name()
    146                    << " into a TextureSourceOGL";
    147    return nullptr;
    148  }
    149  virtual TextureSourceD3D11* AsSourceD3D11() { return nullptr; }
    150  /**
    151   * Cast to a DataTextureSurce.
    152   */
    153  virtual DataTextureSource* AsDataTextureSource() { return nullptr; }
    154 
    155  /**
    156   * Overload this if the TextureSource supports big textures that don't fit in
    157   * one device texture and must be tiled internally.
    158   */
    159  virtual BigImageIterator* AsBigImageIterator() { return nullptr; }
    160 
    161  virtual void Unbind() {}
    162 
    163  void SetNextSibling(TextureSource* aTexture) { mNextSibling = aTexture; }
    164 
    165  TextureSource* GetNextSibling() const { return mNextSibling; }
    166 
    167  /**
    168   * In some rare cases we currently need to consider a group of textures as one
    169   * TextureSource, that can be split in sub-TextureSources.
    170   */
    171  TextureSource* GetSubSource(int index) {
    172    switch (index) {
    173      case 0:
    174        return this;
    175      case 1:
    176        return GetNextSibling();
    177      case 2:
    178        return GetNextSibling() ? GetNextSibling()->GetNextSibling() : nullptr;
    179    }
    180    return nullptr;
    181  }
    182 
    183  void AddCompositableRef() { ++mCompositableCount; }
    184 
    185  void ReleaseCompositableRef() {
    186    --mCompositableCount;
    187    MOZ_ASSERT(mCompositableCount >= 0);
    188  }
    189 
    190  // When iterating as a BigImage, this creates temporary TextureSources
    191  // wrapping individual tiles.
    192  virtual RefPtr<TextureSource> ExtractCurrentTile() {
    193    NS_WARNING("Implementation does not expose tile sources");
    194    return nullptr;
    195  }
    196 
    197  int NumCompositableRefs() const { return mCompositableCount; }
    198 
    199  // The direct-map cpu buffer should be alive when gpu uses it. And it
    200  // should not be updated while gpu reads it. This Sync() function
    201  // implements this synchronized behavior by allowing us to check if
    202  // the GPU is done with the texture, and block on it if aBlocking is
    203  // true.
    204  virtual bool Sync(bool aBlocking) { return true; }
    205 
    206 protected:
    207  RefPtr<TextureSource> mNextSibling;
    208  int mCompositableCount;
    209 };
    210 
    211 /// Equivalent of a RefPtr<TextureSource>, that calls AddCompositableRef and
    212 /// ReleaseCompositableRef in addition to the usual AddRef and Release.
    213 ///
    214 /// The semantoics of these CompositableTextureRefs are important because they
    215 /// are used both as a synchronization/safety mechanism, and as an optimization
    216 /// mechanism. They are also tricky and subtle because we use them in a very
    217 /// implicit way (assigning to a CompositableTextureRef is less visible than
    218 /// explicitly calling a method or whatnot).
    219 /// It is Therefore important to be careful about the way we use this tool.
    220 ///
    221 /// CompositableTextureRef is a mechanism that lets us count how many
    222 /// compositables are using a given texture (for TextureSource and TextureHost).
    223 /// We use it to run specific code when a texture is not used anymore, and also
    224 /// we trigger fast paths on some operations when we can see that the texture's
    225 /// CompositableTextureRef counter is equal to 1 (the texture is not shared
    226 /// between compositables).
    227 /// This means that it is important to observe the following rules:
    228 /// * CompositableHosts that receive UseTexture and similar messages *must*
    229 /// store all of the TextureHosts they receive in CompositableTextureRef slots
    230 /// for as long as they may be using them.
    231 /// * CompositableHosts must store each texture in a *single*
    232 /// CompositableTextureRef slot to ensure that the counter properly reflects how
    233 /// many compositables are using the texture. If a compositable needs to hold
    234 /// two references to a given texture (for example to have a pointer to the
    235 /// current texture in a list of textures that may be used), it can hold its
    236 /// extra references with RefPtr or whichever pointer type makes sense.
    237 template <typename T>
    238 class CompositableTextureRef {
    239 public:
    240  CompositableTextureRef() = default;
    241 
    242  explicit CompositableTextureRef(const CompositableTextureRef& aOther) {
    243    *this = aOther;
    244  }
    245 
    246  explicit CompositableTextureRef(T* aOther) { *this = aOther; }
    247 
    248  ~CompositableTextureRef() {
    249    if (mRef) {
    250      mRef->ReleaseCompositableRef();
    251    }
    252  }
    253 
    254  CompositableTextureRef& operator=(const CompositableTextureRef& aOther) {
    255    if (aOther.get()) {
    256      aOther->AddCompositableRef();
    257    }
    258    if (mRef) {
    259      mRef->ReleaseCompositableRef();
    260    }
    261    mRef = aOther.get();
    262    return *this;
    263  }
    264 
    265  CompositableTextureRef& operator=(T* aOther) {
    266    if (aOther) {
    267      aOther->AddCompositableRef();
    268    }
    269    if (mRef) {
    270      mRef->ReleaseCompositableRef();
    271    }
    272    mRef = aOther;
    273    return *this;
    274  }
    275 
    276  T* get() const { return mRef; }
    277  operator T*() const { return mRef; }
    278  T* operator->() const { return mRef; }
    279  T& operator*() const { return *mRef; }
    280 
    281 private:
    282  RefPtr<T> mRef;
    283 };
    284 
    285 typedef CompositableTextureRef<TextureSource> CompositableTextureSourceRef;
    286 typedef CompositableTextureRef<TextureHost> CompositableTextureHostRef;
    287 
    288 /**
    289 * Interface for TextureSources that can be updated from a DataSourceSurface.
    290 *
    291 * All backend should implement at least one DataTextureSource.
    292 */
    293 class DataTextureSource : public TextureSource {
    294 public:
    295  DataTextureSource() : mOwner(0), mUpdateSerial(0) {}
    296 
    297  const char* Name() const override { return "DataTextureSource"; }
    298 
    299  DataTextureSource* AsDataTextureSource() override { return this; }
    300 
    301  /**
    302   * Upload a (portion of) surface to the TextureSource.
    303   *
    304   * The DataTextureSource doesn't own aSurface, although it owns and manage
    305   * the device texture it uploads to internally.
    306   */
    307  virtual bool Update(gfx::DataSourceSurface* aSurface,
    308                      nsIntRegion* aDestRegion = nullptr,
    309                      gfx::IntPoint* aSrcOffset = nullptr,
    310                      gfx::IntPoint* aDstOffset = nullptr) = 0;
    311 
    312  /**
    313   * A facility to avoid reuploading when it is not necessary.
    314   * The caller of Update can use GetUpdateSerial to see if the number has
    315   * changed since last update, and call SetUpdateSerial after each successful
    316   * update. The caller is responsible for managing the update serial except
    317   * when the texture data is deallocated in which case the TextureSource should
    318   * always reset the update serial to zero.
    319   */
    320  uint32_t GetUpdateSerial() const { return mUpdateSerial; }
    321  void SetUpdateSerial(uint32_t aValue) { mUpdateSerial = aValue; }
    322 
    323  // By default at least set the update serial to zero.
    324  // overloaded versions should do that too.
    325  void DeallocateDeviceData() override { SetUpdateSerial(0); }
    326 
    327 #ifdef DEBUG
    328  /**
    329   * Provide read access to the data as a DataSourceSurface.
    330   *
    331   * This is expected to be very slow and should be used for mostly debugging.
    332   * XXX - implement everywhere and make it pure virtual.
    333   */
    334  virtual already_AddRefed<gfx::DataSourceSurface> ReadBack() {
    335    return nullptr;
    336  };
    337 #endif
    338 
    339  void SetOwner(TextureHost* aOwner) {
    340    auto newOwner = (uintptr_t)aOwner;
    341    if (newOwner != mOwner) {
    342      mOwner = newOwner;
    343      SetUpdateSerial(0);
    344    }
    345  }
    346 
    347  bool IsOwnedBy(TextureHost* aOwner) const {
    348    return mOwner == (uintptr_t)aOwner;
    349  }
    350 
    351  bool HasOwner() const { return !IsOwnedBy(nullptr); }
    352 
    353 private:
    354  // We store mOwner as an integer rather than as a pointer to make it clear
    355  // it is not intended to be dereferenced.
    356  uintptr_t mOwner;
    357  uint32_t mUpdateSerial;
    358 };
    359 
    360 enum class TextureHostType : int8_t {
    361  Unknown = 0,
    362  Buffer,
    363  DXGI,
    364  DXGIYCbCr,
    365  DcompSurface,
    366  DMABUF,
    367  MacIOSurface,
    368  AndroidSurfaceTexture,
    369  AndroidHardwareBuffer,
    370  EGLImage,
    371  GLTexture,
    372  Last
    373 };
    374 
    375 /**
    376 * TextureHost is a thin abstraction over texture data that need to be shared
    377 * between the content process and the compositor process. It is the
    378 * compositor-side half of a TextureClient/TextureHost pair. A corresponding
    379 * TextureClient lives on the content-side.
    380 *
    381 * TextureHost only knows how to deserialize or synchronize generic image data
    382 * (SurfaceDescriptor) and provide access to one or more TextureSource objects
    383 * (these provide the necessary APIs for compositor backends to composite the
    384 * image).
    385 *
    386 * A TextureHost implementation corresponds to one SurfaceDescriptor type, as
    387 * opposed to TextureSource that corresponds to device textures.
    388 * This means that for YCbCr planes, even though they are represented as
    389 * 3 textures internally (3 TextureSources), we use 1 TextureHost and not 3,
    390 * because the 3 planes are stored in the same buffer of shared memory, before
    391 * they are uploaded separately.
    392 *
    393 * There is always one and only one TextureHost per TextureClient, and the
    394 * TextureClient/Host pair only owns one buffer of image data through its
    395 * lifetime. This means that the lifetime of the underlying shared data
    396 * matches the lifetime of the TextureClient/Host pair. It also means
    397 * TextureClient/Host do not implement double buffering, which is the
    398 * reponsibility of the compositable (which would use two Texture pairs).
    399 *
    400 * The Lock/Unlock mecanism here mirrors Lock/Unlock in TextureClient.
    401 *
    402 */
    403 class TextureHost : public AtomicRefCountedWithFinalize<TextureHost> {
    404  /**
    405   * Called once, just before the destructor.
    406   *
    407   * Here goes the shut-down code that uses virtual methods.
    408   * Must only be called by Release().
    409   */
    410  void Finalize();
    411 
    412  friend class AtomicRefCountedWithFinalize<TextureHost>;
    413 
    414 public:
    415  TextureHost(TextureHostType aType, TextureFlags aFlags);
    416 
    417 protected:
    418  virtual ~TextureHost();
    419 
    420 public:
    421  /**
    422   * Factory method.
    423   */
    424  static already_AddRefed<TextureHost> Create(
    425      const SurfaceDescriptor& aDesc, ReadLockDescriptor&& aReadLock,
    426      HostIPCAllocator* aDeallocator, LayersBackend aBackend,
    427      TextureFlags aFlags, wr::MaybeExternalImageId& aExternalImageId);
    428 
    429  /**
    430   * Lock the texture host for compositing without using compositor.
    431   */
    432  virtual bool LockWithoutCompositor() { return true; }
    433  /**
    434   * Similar to Unlock(), but it should be called with LockWithoutCompositor().
    435   */
    436  virtual void UnlockWithoutCompositor() {}
    437 
    438  /**
    439   * Note that the texture host format can be different from its corresponding
    440   * texture source's. For example a ShmemTextureHost can have the ycbcr
    441   * format and produce 3 "alpha" textures sources.
    442   */
    443  virtual gfx::SurfaceFormat GetFormat() const = 0;
    444  /**
    445   * Return the format used for reading the texture.
    446   * Apple's YCBCR_422 is R8G8B8X8.
    447   */
    448  virtual gfx::SurfaceFormat GetReadFormat() const { return GetFormat(); }
    449 
    450  virtual gfx::YUVColorSpace GetYUVColorSpace() const {
    451    return gfx::YUVColorSpace::Identity;
    452  }
    453 
    454  /**
    455   * Return the color depth of the image. Used with YUV textures.
    456   */
    457  virtual gfx::ColorDepth GetColorDepth() const {
    458    return gfx::ColorDepth::COLOR_8;
    459  }
    460 
    461  /**
    462   * Return true if using full range values (0-255 if 8 bits YUV). Used with YUV
    463   * textures.
    464   */
    465  virtual gfx::ColorRange GetColorRange() const {
    466    return gfx::ColorRange::LIMITED;
    467  }
    468 
    469  /**
    470   * Called when another TextureHost will take over.
    471   */
    472  virtual void UnbindTextureSource();
    473 
    474  virtual bool IsValid() { return true; }
    475 
    476  /**
    477   * Should be overridden in order to deallocate the data that is associated
    478   * with the rendering backend, such as GL textures.
    479   */
    480  virtual void DeallocateDeviceData() {}
    481 
    482  /**
    483   * Should be overridden in order to deallocate the data that is shared with
    484   * the content side, such as shared memory.
    485   */
    486  virtual void DeallocateSharedData() {}
    487 
    488  /**
    489   * Should be overridden in order to force the TextureHost to drop all
    490   * references to it's shared data.
    491   *
    492   * This is important to ensure the correctness of the deallocation protocol.
    493   */
    494  virtual void ForgetSharedData() {}
    495 
    496  virtual gfx::IntSize GetSize() const = 0;
    497 
    498  /**
    499   * Should be overridden if TextureHost supports crop rect.
    500   */
    501  virtual void SetCropRect(nsIntRect aCropRect) {}
    502 
    503  /**
    504   * Return TextureHost's data as DataSourceSurface.
    505   *
    506   * @param aSurface may be used as returned DataSourceSurface.
    507   *
    508   * XXX - cool kids use Moz2D. See bug 882113.
    509   */
    510  virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
    511      gfx::DataSourceSurface* aSurface = nullptr) = 0;
    512 
    513  /**
    514   * XXX - Flags should only be set at creation time, this will be removed.
    515   */
    516  void SetFlags(TextureFlags aFlags) { mFlags = aFlags; }
    517 
    518  /**
    519   * XXX - Flags should only be set at creation time, this will be removed.
    520   */
    521  void AddFlag(TextureFlags aFlag) { mFlags |= aFlag; }
    522 
    523  TextureFlags GetFlags() { return mFlags; }
    524 
    525  wr::MaybeExternalImageId GetMaybeExternalImageId() const {
    526    return mExternalImageId;
    527  }
    528 
    529  /**
    530   * Allocate and deallocate a TextureParent actor.
    531   *
    532   * TextureParent< is an implementation detail of TextureHost that is not
    533   * exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor
    534   * are for use with the managing IPDL protocols only (so that they can
    535   * implement AllocPTextureParent and DeallocPTextureParent).
    536   */
    537  static PTextureParent* CreateIPDLActor(
    538      HostIPCAllocator* aAllocator, const SurfaceDescriptor& aSharedData,
    539      ReadLockDescriptor&& aDescriptor, LayersBackend aLayersBackend,
    540      TextureFlags aFlags, const dom::ContentParentId& aContentId,
    541      uint64_t aSerial, const wr::MaybeExternalImageId& aExternalImageId);
    542  static bool DestroyIPDLActor(PTextureParent* actor);
    543 
    544  /**
    545   * Destroy the TextureChild/Parent pair.
    546   */
    547  static bool SendDeleteIPDLActor(PTextureParent* actor);
    548 
    549  static void ReceivedDestroy(PTextureParent* actor);
    550 
    551  /**
    552   * Get the TextureHost corresponding to the actor passed in parameter.
    553   */
    554  static TextureHost* AsTextureHost(PTextureParent* actor);
    555 
    556  static uint64_t GetTextureSerial(PTextureParent* actor);
    557 
    558  static dom::ContentParentId GetTextureContentId(PTextureParent* actor);
    559 
    560  /**
    561   * Return a pointer to the IPDLActor.
    562   *
    563   * This is to be used with IPDL messages only. Do not store the returned
    564   * pointer.
    565   */
    566  PTextureParent* GetIPDLActor();
    567 
    568  // If a texture host holds a reference to shmem, it should override this
    569  // method to forget about the shmem _without_ releasing it.
    570  virtual void OnShutdown() {}
    571 
    572  // Forget buffer actor. Used only for hacky fix for bug 966446.
    573  virtual void ForgetBufferActor() {}
    574 
    575  virtual const char* Name() { return "TextureHost"; }
    576 
    577  /**
    578   * Returns true if the TextureHost can be released before the rendering is
    579   * completed, otherwise returns false.
    580   */
    581  virtual bool NeedsDeferredDeletion() const { return true; }
    582 
    583  void AddCompositableRef() {
    584    ++mCompositableCount;
    585    if (mCompositableCount == 1) {
    586      PrepareForUse();
    587    }
    588  }
    589 
    590  void ReleaseCompositableRef() {
    591    --mCompositableCount;
    592    MOZ_ASSERT(mCompositableCount >= 0);
    593    if (mCompositableCount == 0) {
    594      UnbindTextureSource();
    595      // Send mFwdTransactionId to client side if necessary.
    596      NotifyNotUsed();
    597    }
    598  }
    599 
    600  int NumCompositableRefs() const { return mCompositableCount; }
    601 
    602  void SetLastFwdTransactionId(uint64_t aTransactionId);
    603 
    604  void DeserializeReadLock(ReadLockDescriptor&& aDesc,
    605                           ISurfaceAllocator* aAllocator);
    606  void SetReadLocked();
    607 
    608  TextureReadLock* GetReadLock() { return mReadLock; }
    609 
    610  virtual BufferTextureHost* AsBufferTextureHost() { return nullptr; }
    611  virtual ShmemTextureHost* AsShmemTextureHost() { return nullptr; }
    612  virtual MacIOSurfaceTextureHostOGL* AsMacIOSurfaceTextureHost() {
    613    return nullptr;
    614  }
    615  virtual WebRenderTextureHost* AsWebRenderTextureHost() { return nullptr; }
    616  virtual SurfaceTextureHost* AsSurfaceTextureHost() { return nullptr; }
    617  virtual AndroidHardwareBufferTextureHost*
    618  AsAndroidHardwareBufferTextureHost() {
    619    return nullptr;
    620  }
    621  virtual RemoteTextureHostWrapper* AsRemoteTextureHostWrapper() {
    622    return nullptr;
    623  }
    624 
    625  virtual TextureHostWrapperD3D11* AsTextureHostWrapperD3D11() {
    626    return nullptr;
    627  }
    628 
    629  virtual DXGITextureHostD3D11* AsDXGITextureHostD3D11() { return nullptr; }
    630 
    631  virtual DXGIYCbCrTextureHostD3D11* AsDXGIYCbCrTextureHostD3D11() {
    632    return nullptr;
    633  }
    634 
    635  virtual bool IsWrappingSurfaceTextureHost() { return false; }
    636 
    637  // Create the corresponding RenderTextureHost type of this texture, and
    638  // register the RenderTextureHost into render thread.
    639  virtual void CreateRenderTexture(
    640      const wr::ExternalImageId& aExternalImageId) {
    641    MOZ_RELEASE_ASSERT(
    642        false,
    643        "No CreateRenderTexture() implementation for this TextureHost type.");
    644  }
    645 
    646  void EnsureRenderTexture(const wr::MaybeExternalImageId& aExternalImageId);
    647 
    648  // Destroy RenderTextureHost when it was created by the TextureHost.
    649  // It is called in TextureHost::Finalize().
    650  virtual void MaybeDestroyRenderTexture();
    651 
    652  static void DestroyRenderTexture(const wr::ExternalImageId& aExternalImageId);
    653 
    654  /// Returns the number of actual textures that will be used to render this.
    655  /// For example in a lot of YUV cases it will be 3
    656  virtual uint32_t NumSubTextures() { return 1; }
    657 
    658  enum ResourceUpdateOp {
    659    ADD_IMAGE,
    660    UPDATE_IMAGE,
    661  };
    662 
    663  // Add all necessary TextureHost informations to the resource update queue.
    664  virtual void PushResourceUpdates(wr::TransactionBuilder& aResources,
    665                                   ResourceUpdateOp aOp,
    666                                   const Range<wr::ImageKey>& aImageKeys,
    667                                   const wr::ExternalImageId& aExtID) {
    668    MOZ_ASSERT_UNREACHABLE("Unimplemented");
    669  }
    670 
    671  enum class PushDisplayItemFlag {
    672    // Passed if the caller wants these display items to be promoted
    673    // to compositor surfaces if possible.
    674    PREFER_COMPOSITOR_SURFACE,
    675 
    676    // Passed in the RenderCompositor supports BufferTextureHosts
    677    // being used directly as external compositor surfaces.
    678    SUPPORTS_EXTERNAL_BUFFER_TEXTURES,
    679 
    680    // Passed if the caller wants to disable external compositing of TextureHost
    681    EXTERNAL_COMPOSITING_DISABLED,
    682  };
    683  using PushDisplayItemFlagSet = EnumSet<PushDisplayItemFlag>;
    684 
    685  // Put all necessary WR commands into DisplayListBuilder for this textureHost
    686  // rendering.
    687  virtual void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
    688                                const wr::LayoutRect& aBounds,
    689                                const wr::LayoutRect& aClip,
    690                                wr::ImageRendering aFilter,
    691                                const Range<wr::ImageKey>& aKeys,
    692                                PushDisplayItemFlagSet aFlags) {
    693    MOZ_ASSERT_UNREACHABLE(
    694        "No PushDisplayItems() implementation for this TextureHost type.");
    695  }
    696 
    697  /**
    698   * Some API's can use the cross-process IOSurface directly, such as OpenVR
    699   */
    700  virtual MacIOSurface* GetMacIOSurface() { return nullptr; }
    701 
    702  virtual bool NeedsYFlip() const;
    703 
    704  virtual AndroidHardwareBuffer* GetAndroidHardwareBuffer() const {
    705    return nullptr;
    706  }
    707 
    708  virtual bool SupportsExternalCompositing(WebRenderBackend aBackend) {
    709    return false;
    710  }
    711 
    712  virtual TextureHostType GetTextureHostType() { return mTextureHostType; }
    713 
    714  virtual void SetReadFence(Fence* aReadFence) {}
    715 
    716  // Our WebRender backend may impose restrictions on whether textures are
    717  // prepared as native textures or not, or it may have no restriction at
    718  // all. This enumerates those possibilities.
    719  enum NativeTexturePolicy {
    720    REQUIRE,
    721    FORBID,
    722    DONT_CARE,
    723  };
    724 
    725  static NativeTexturePolicy BackendNativeTexturePolicy(
    726      layers::WebRenderBackend aBackend, gfx::IntSize aSize) {
    727    static const int32_t SWGL_DIMENSION_MAX = 1 << 15;
    728    if (aBackend == WebRenderBackend::SOFTWARE) {
    729      return (aSize.width <= SWGL_DIMENSION_MAX &&
    730              aSize.height <= SWGL_DIMENSION_MAX)
    731                 ? REQUIRE
    732                 : FORBID;
    733    }
    734    return DONT_CARE;
    735  }
    736 
    737  void SetDestroyedCallback(std::function<void()>&& aDestroyedCallback) {
    738    MOZ_ASSERT(!mDestroyedCallback);
    739    mDestroyedCallback = std::move(aDestroyedCallback);
    740  }
    741 
    742 protected:
    743  virtual void ReadUnlock();
    744 
    745  void RecycleTexture(TextureFlags aFlags);
    746 
    747  /**
    748   * Called when mCompositableCount becomes from 0 to 1.
    749   */
    750  virtual void PrepareForUse();
    751 
    752  /**
    753   * Called when mCompositableCount becomes 0.
    754   */
    755  virtual void NotifyNotUsed();
    756 
    757  // for Compositor.
    758  void CallNotifyNotUsed();
    759 
    760  TextureHostType mTextureHostType;
    761  PTextureParent* mActor;
    762  RefPtr<TextureReadLock> mReadLock;
    763  TextureFlags mFlags;
    764  int mCompositableCount;
    765  uint64_t mFwdTransactionId;
    766  bool mReadLocked;
    767  wr::MaybeExternalImageId mExternalImageId;
    768 
    769  std::function<void()> mDestroyedCallback;
    770 
    771  friend class Compositor;
    772  friend class RemoteTextureHostWrapper;
    773  friend class TextureParent;
    774  friend class TextureSourceProvider;
    775  friend class GPUVideoTextureHost;
    776  friend class WebRenderTextureHost;
    777  friend class TextureHostWrapperD3D11;
    778 };
    779 
    780 /**
    781 * TextureHost that wraps a random access buffer such as a Shmem or some raw
    782 * memory.
    783 *
    784 * This TextureHost is backend-independent and the backend-specific bits are
    785 * in the TextureSource.
    786 * This class must be inherited to implement GetBuffer and DeallocSharedData
    787 * (see ShmemTextureHost and MemoryTextureHost)
    788 *
    789 * Uploads happen when Lock is called.
    790 *
    791 * BufferTextureHost supports YCbCr and flavours of RGBA images (RGBX, A, etc.).
    792 */
    793 class BufferTextureHost : public TextureHost {
    794 public:
    795  BufferTextureHost(const BufferDescriptor& aDescriptor, TextureFlags aFlags);
    796 
    797  virtual ~BufferTextureHost();
    798 
    799  virtual uint8_t* GetBuffer() const = 0;
    800 
    801  virtual size_t GetBufferSize() const = 0;
    802 
    803  void UnbindTextureSource() override;
    804 
    805  void DeallocateDeviceData() override;
    806 
    807  /**
    808   * Return the format that is exposed to the compositor when calling
    809   * BindTextureSource.
    810   *
    811   * If the shared format is YCbCr and the compositor does not support it,
    812   * GetFormat will be RGB32 (even though mFormat is SurfaceFormat::YUV).
    813   */
    814  gfx::SurfaceFormat GetFormat() const override;
    815 
    816  gfx::YUVColorSpace GetYUVColorSpace() const override;
    817 
    818  gfx::ColorDepth GetColorDepth() const override;
    819 
    820  gfx::ColorRange GetColorRange() const override;
    821 
    822  gfx::ChromaSubsampling GetChromaSubsampling() const;
    823 
    824  gfx::IntSize GetSize() const override { return mSize; }
    825 
    826  already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
    827      gfx::DataSourceSurface* aSurface) override;
    828 
    829  bool NeedsDeferredDeletion() const override {
    830    return TextureHost::NeedsDeferredDeletion() || UseExternalTextures();
    831  }
    832 
    833  BufferTextureHost* AsBufferTextureHost() override { return this; }
    834 
    835  const BufferDescriptor& GetBufferDescriptor() const { return mDescriptor; }
    836 
    837  void CreateRenderTexture(
    838      const wr::ExternalImageId& aExternalImageId) override;
    839 
    840  uint32_t NumSubTextures() override;
    841 
    842  void PushResourceUpdates(wr::TransactionBuilder& aResources,
    843                           ResourceUpdateOp aOp,
    844                           const Range<wr::ImageKey>& aImageKeys,
    845                           const wr::ExternalImageId& aExtID) override;
    846 
    847  void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
    848                        const wr::LayoutRect& aBounds,
    849                        const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
    850                        const Range<wr::ImageKey>& aImageKeys,
    851                        PushDisplayItemFlagSet aFlags) override;
    852 
    853  uint8_t* GetYChannel();
    854  uint8_t* GetCbChannel();
    855  uint8_t* GetCrChannel();
    856  int32_t GetYStride() const;
    857  int32_t GetCbCrStride() const;
    858 
    859 protected:
    860  bool UseExternalTextures() const { return mUseExternalTextures; }
    861 
    862  BufferDescriptor mDescriptor;
    863  RefPtr<Compositor> mCompositor;
    864  gfx::IntSize mSize;
    865  gfx::SurfaceFormat mFormat;
    866  bool mLocked;
    867  bool mUseExternalTextures;
    868 
    869  class DataTextureSourceYCbCrBasic;
    870 };
    871 
    872 /**
    873 * TextureHost that wraps shared memory.
    874 * the corresponding texture on the client side is ShmemTextureClient.
    875 * This TextureHost is backend-independent.
    876 */
    877 class ShmemTextureHost : public BufferTextureHost {
    878 public:
    879  ShmemTextureHost(const mozilla::ipc::Shmem& aShmem,
    880                   const BufferDescriptor& aDesc,
    881                   ISurfaceAllocator* aDeallocator, TextureFlags aFlags);
    882 
    883 protected:
    884  ~ShmemTextureHost();
    885 
    886 public:
    887  void DeallocateSharedData() override;
    888 
    889  void ForgetSharedData() override;
    890 
    891  uint8_t* GetBuffer() const override;
    892 
    893  size_t GetBufferSize() const override;
    894 
    895  const char* Name() override { return "ShmemTextureHost"; }
    896 
    897  void OnShutdown() override;
    898 
    899  ShmemTextureHost* AsShmemTextureHost() override { return this; }
    900 
    901 protected:
    902  UniquePtr<mozilla::ipc::Shmem> mShmem;
    903  RefPtr<ISurfaceAllocator> mDeallocator;
    904 };
    905 
    906 /**
    907 * TextureHost that wraps raw memory.
    908 * The corresponding texture on the client side is MemoryTextureClient.
    909 * Can obviously not be used in a cross process setup.
    910 * This TextureHost is backend-independent.
    911 */
    912 class MemoryTextureHost : public BufferTextureHost {
    913 public:
    914  MemoryTextureHost(uint8_t* aBuffer, const BufferDescriptor& aDesc,
    915                    TextureFlags aFlags);
    916 
    917 protected:
    918  ~MemoryTextureHost();
    919 
    920 public:
    921  void DeallocateSharedData() override;
    922 
    923  void ForgetSharedData() override;
    924 
    925  uint8_t* GetBuffer() const override;
    926 
    927  size_t GetBufferSize() const override;
    928 
    929  const char* Name() override { return "MemoryTextureHost"; }
    930 
    931 protected:
    932  uint8_t* mBuffer;
    933 };
    934 
    935 class MOZ_STACK_CLASS AutoLockTextureHostWithoutCompositor {
    936 public:
    937  explicit AutoLockTextureHostWithoutCompositor(TextureHost* aTexture)
    938      : mTexture(aTexture) {
    939    mLocked = mTexture ? mTexture->LockWithoutCompositor() : false;
    940  }
    941 
    942  ~AutoLockTextureHostWithoutCompositor() {
    943    if (mTexture && mLocked) {
    944      mTexture->UnlockWithoutCompositor();
    945    }
    946  }
    947 
    948  bool Failed() { return mTexture && !mLocked; }
    949 
    950 private:
    951  RefPtr<TextureHost> mTexture;
    952  bool mLocked;
    953 };
    954 
    955 /**
    956 * This can be used as an offscreen rendering target by the compositor, and
    957 * subsequently can be used as a source by the compositor.
    958 */
    959 class CompositingRenderTarget : public TextureSource {
    960 public:
    961  explicit CompositingRenderTarget(const gfx::IntPoint& aOrigin)
    962      : mClearOnBind(false),
    963        mOrigin(aOrigin),
    964        mZNear(0),
    965        mZFar(0),
    966        mHasComplexProjection(false),
    967        mEnableDepthBuffer(false) {}
    968  virtual ~CompositingRenderTarget() = default;
    969 
    970  const char* Name() const override { return "CompositingRenderTarget"; }
    971 
    972 #ifdef MOZ_DUMP_PAINTING
    973  virtual already_AddRefed<gfx::DataSourceSurface> Dump(
    974      Compositor* aCompositor) {
    975    return nullptr;
    976  }
    977 #endif
    978 
    979  /**
    980   * Perform a clear when recycling a non opaque surface.
    981   * The clear is deferred to when the render target is bound.
    982   */
    983  void ClearOnBind() { mClearOnBind = true; }
    984 
    985  const gfx::IntPoint& GetOrigin() const { return mOrigin; }
    986  gfx::IntRect GetRect() { return gfx::IntRect(GetOrigin(), GetSize()); }
    987 
    988  /**
    989   * If a Projection matrix is set, then it is used for rendering to
    990   * this render target instead of generating one.  If no explicit
    991   * projection is set, Compositors are expected to generate an
    992   * orthogonal maaping that maps 0..1 to the full size of the render
    993   * target.
    994   */
    995  bool HasComplexProjection() const { return mHasComplexProjection; }
    996  void ClearProjection() { mHasComplexProjection = false; }
    997  void SetProjection(const gfx::Matrix4x4& aNewMatrix, bool aEnableDepthBuffer,
    998                     float aZNear, float aZFar) {
    999    mProjectionMatrix = aNewMatrix;
   1000    mEnableDepthBuffer = aEnableDepthBuffer;
   1001    mZNear = aZNear;
   1002    mZFar = aZFar;
   1003    mHasComplexProjection = true;
   1004  }
   1005  void GetProjection(gfx::Matrix4x4& aMatrix, bool& aEnableDepth, float& aZNear,
   1006                     float& aZFar) {
   1007    MOZ_ASSERT(mHasComplexProjection);
   1008    aMatrix = mProjectionMatrix;
   1009    aEnableDepth = mEnableDepthBuffer;
   1010    aZNear = mZNear;
   1011    aZFar = mZFar;
   1012  }
   1013 
   1014 protected:
   1015  bool mClearOnBind;
   1016 
   1017 private:
   1018  gfx::IntPoint mOrigin;
   1019 
   1020  gfx::Matrix4x4 mProjectionMatrix;
   1021  float mZNear, mZFar;
   1022  bool mHasComplexProjection;
   1023  bool mEnableDepthBuffer;
   1024 };
   1025 
   1026 /**
   1027 * Creates a TextureHost that can be used with any of the existing backends
   1028 * Not all SurfaceDescriptor types are supported
   1029 */
   1030 already_AddRefed<TextureHost> CreateBackendIndependentTextureHost(
   1031    const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator,
   1032    LayersBackend aBackend, TextureFlags aFlags);
   1033 
   1034 }  // namespace layers
   1035 }  // namespace mozilla
   1036 
   1037 #endif