tor-browser

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

SharedSurface.h (5983B)


      1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 4; -*- */
      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 /* SharedSurface abstracts an actual surface (can be a GL texture, but
      7 * not necessarily) that handles sharing.
      8 * Its specializations are:
      9 *     SharedSurface_Basic (client-side bitmap, does readback)
     10 *     SharedSurface_GLTexture
     11 *     SharedSurface_EGLImage
     12 *     SharedSurface_ANGLEShareHandle
     13 */
     14 
     15 #ifndef SHARED_SURFACE_H_
     16 #define SHARED_SURFACE_H_
     17 
     18 #include <queue>
     19 #include <stdint.h>
     20 
     21 #include "GLContext.h"  // Bug 1635644
     22 #include "GLContextTypes.h"
     23 #include "GLDefs.h"
     24 #include "mozilla/Attributes.h"
     25 #include "mozilla/gfx/Point.h"
     26 #include "mozilla/Mutex.h"
     27 #include "mozilla/UniquePtr.h"
     28 #include "mozilla/WeakPtr.h"
     29 #include "SurfaceTypes.h"
     30 
     31 class nsIThread;
     32 
     33 namespace mozilla {
     34 namespace gfx {
     35 class DataSourceSurface;
     36 class DrawTarget;
     37 }  // namespace gfx
     38 
     39 namespace layers {
     40 class KnowsCompositor;
     41 enum class LayersBackend : int8_t;
     42 class LayersIPCChannel;
     43 class SharedSurfaceTextureClient;
     44 class SurfaceDescriptor;
     45 class TextureClient;
     46 enum class TextureFlags : uint32_t;
     47 enum class TextureType : int8_t;
     48 }  // namespace layers
     49 
     50 namespace gl {
     51 
     52 class MozFramebuffer;
     53 struct ScopedBindFramebuffer;
     54 class SurfaceFactory;
     55 
     56 struct PartialSharedSurfaceDesc {
     57  const WeakPtr<GLContext> gl;
     58  const SharedSurfaceType type;
     59  const layers::TextureType consumerType;
     60  const bool canRecycle;
     61 
     62  bool operator==(const PartialSharedSurfaceDesc& rhs) const {
     63    return gl == rhs.gl && type == rhs.type &&
     64           consumerType == rhs.consumerType && canRecycle == rhs.canRecycle;
     65  }
     66 };
     67 struct SharedSurfaceDesc : public PartialSharedSurfaceDesc {
     68  gfx::IntSize size = {};
     69  gfx::ColorSpace2 colorSpace = gfx::ColorSpace2::UNKNOWN;
     70 
     71  bool operator==(const SharedSurfaceDesc& rhs) const {
     72    return PartialSharedSurfaceDesc::operator==(rhs) && size == rhs.size &&
     73           colorSpace == rhs.colorSpace;
     74  }
     75  bool operator!=(const SharedSurfaceDesc& rhs) const {
     76    return !(*this == rhs);
     77  }
     78 };
     79 
     80 class SharedSurface {
     81 public:
     82  const SharedSurfaceDesc mDesc;
     83  const UniquePtr<MozFramebuffer> mFb;  // null if we should use fb=0.
     84 
     85 protected:
     86  bool mIsLocked = false;
     87  bool mIsProducerAcquired = false;
     88 
     89  SharedSurface(const SharedSurfaceDesc&, UniquePtr<MozFramebuffer>);
     90 
     91 public:
     92  virtual ~SharedSurface();
     93 
     94  bool IsLocked() const { return mIsLocked; }
     95  bool IsProducerAcquired() const { return mIsProducerAcquired; }
     96 
     97  // This locks the SharedSurface as the production buffer for the context.
     98  // This is needed by backends which use PBuffers and/or EGLSurfaces.
     99  void LockProd();
    100 
    101  // Unlocking is harmless if we're already unlocked.
    102  void UnlockProd();
    103 
    104  // This surface has been moved to the front buffer and will not be locked
    105  // again until it is recycled. Do any finalization steps here.
    106  virtual void Commit() {}
    107 
    108 protected:
    109  virtual void LockProdImpl() {};
    110  virtual void UnlockProdImpl() {};
    111 
    112  virtual void ProducerAcquireImpl() {};
    113  virtual void ProducerReleaseImpl() {};
    114 
    115  virtual void ProducerReadAcquireImpl() { ProducerAcquireImpl(); }
    116  virtual void ProducerReadReleaseImpl() { ProducerReleaseImpl(); }
    117 
    118 public:
    119  void ProducerAcquire() {
    120    MOZ_ASSERT(!mIsProducerAcquired);
    121    ProducerAcquireImpl();
    122    mIsProducerAcquired = true;
    123  }
    124  void ProducerRelease() {
    125    MOZ_ASSERT(mIsProducerAcquired);
    126    ProducerReleaseImpl();
    127    mIsProducerAcquired = false;
    128  }
    129  void ProducerReadAcquire() {
    130    MOZ_ASSERT(!mIsProducerAcquired);
    131    ProducerReadAcquireImpl();
    132    mIsProducerAcquired = true;
    133  }
    134  void ProducerReadRelease() {
    135    MOZ_ASSERT(mIsProducerAcquired);
    136    ProducerReadReleaseImpl();
    137    mIsProducerAcquired = false;
    138  }
    139 
    140  // This function waits until the buffer is no longer being used.
    141  // To optimize the performance, some implementaions recycle SharedSurfaces
    142  // even when its buffer is still being used.
    143  virtual void WaitForBufferOwnership() {}
    144 
    145  // Returns true if the buffer is available.
    146  // You can call WaitForBufferOwnership to wait for availability.
    147  virtual bool IsBufferAvailable() const { return true; }
    148 
    149  virtual bool NeedsIndirectReads() const { return false; }
    150 
    151  // Returns true if the surface is still valid to use. If false, the underlying
    152  // resource has been released and we must allocate a new surface instead.
    153  virtual bool IsValid() const { return true; };
    154 
    155  virtual Maybe<layers::SurfaceDescriptor> ToSurfaceDescriptor() = 0;
    156 
    157  void BeginWrite() {
    158    WaitForBufferOwnership();
    159    ProducerAcquire();
    160    LockProd();
    161  }
    162 
    163  void EndWrite() {
    164    UnlockProd();
    165    ProducerRelease();
    166    Commit();
    167  }
    168 
    169  void BeginRead() {
    170    WaitForBufferOwnership();
    171    LockProd();
    172    ProducerReadAcquire();
    173  }
    174 
    175  void EndRead() {
    176    ProducerReadRelease();
    177    UnlockProd();
    178  }
    179 };
    180 
    181 // -
    182 
    183 class SurfaceFactory {
    184 public:
    185  const PartialSharedSurfaceDesc mDesc;
    186 
    187  layers::TextureType GetConsumerType() const { return mDesc.consumerType; }
    188 
    189 protected:
    190  Mutex mMutex MOZ_UNANNOTATED;
    191 
    192 public:
    193  static UniquePtr<SurfaceFactory> Create(GLContext*, layers::TextureType);
    194 
    195 protected:
    196  explicit SurfaceFactory(const PartialSharedSurfaceDesc&);
    197 
    198 public:
    199  virtual ~SurfaceFactory();
    200 
    201 protected:
    202  virtual UniquePtr<SharedSurface> CreateSharedImpl(
    203      const SharedSurfaceDesc&) = 0;
    204 
    205 public:
    206  virtual bool SupportsCspaces() const { return false; }
    207 
    208  UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size,
    209                                        gfx::ColorSpace2 cs) {
    210    if (!SupportsCspaces()) {
    211      cs = gfx::ColorSpace2::Display;
    212    }
    213    return CreateSharedImpl({mDesc, size, cs});
    214  }
    215 };
    216 
    217 template <typename T>
    218 inline UniquePtr<T> AsUnique(T* const p) {
    219  return UniquePtr<T>(p);
    220 }
    221 
    222 }  // namespace gl
    223 }  // namespace mozilla
    224 
    225 #endif  // SHARED_SURFACE_H_