tor-browser

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

PersistentBufferProvider.h (10306B)


      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_PersistentBUFFERPROVIDER_H
      8 #define MOZILLA_GFX_PersistentBUFFERPROVIDER_H
      9 
     10 #include "mozilla/Assertions.h"  // for MOZ_ASSERT, etc
     11 #include "mozilla/RefPtr.h"      // for RefPtr, already_AddRefed, etc
     12 #include "mozilla/layers/ActiveResource.h"
     13 #include "mozilla/layers/LayersSurfaces.h"
     14 #include "mozilla/layers/LayersTypes.h"
     15 #include "mozilla/RefCounted.h"
     16 #include "mozilla/gfx/Types.h"
     17 #include "mozilla/Vector.h"
     18 #include "mozilla/WeakPtr.h"
     19 
     20 namespace mozilla {
     21 
     22 class ClientWebGLContext;
     23 
     24 namespace gfx {
     25 class SourceSurface;
     26 class DrawTarget;
     27 }  // namespace gfx
     28 
     29 namespace layers {
     30 
     31 class CompositableForwarder;
     32 class FwdTransactionTracker;
     33 class KnowsCompositor;
     34 class TextureClient;
     35 
     36 /**
     37 * A PersistentBufferProvider is for users which require the temporary use of
     38 * a DrawTarget to draw into. When they're done drawing they return the
     39 * DrawTarget, when they later need to continue drawing they get a DrawTarget
     40 * from the provider again, the provider will guarantee the contents of the
     41 * previously returned DrawTarget is persisted into the one newly returned.
     42 */
     43 class PersistentBufferProvider : public RefCounted<PersistentBufferProvider>,
     44                                 public SupportsWeakPtr {
     45 public:
     46  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProvider)
     47 
     48  virtual ~PersistentBufferProvider() = default;
     49 
     50  virtual bool IsShared() const { return false; }
     51  virtual bool IsAccelerated() const { return false; }
     52 
     53  /**
     54   * Get a DrawTarget from the PersistentBufferProvider.
     55   *
     56   * \param aPersistedRect This indicates the area of the DrawTarget that needs
     57   *                       to have remained the same since the call to
     58   *                       ReturnDrawTarget.
     59   */
     60  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(
     61      const gfx::IntRect& aPersistedRect) = 0;
     62 
     63  /**
     64   * Return a DrawTarget to the PersistentBufferProvider and indicate the
     65   * contents of this DrawTarget is to be considered current by the
     66   * BufferProvider. The caller should forget any references to the DrawTarget.
     67   */
     68  virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) = 0;
     69 
     70  /**
     71   * Temporarily borrow a snapshot of the provider. If a target is supplied,
     72   * the snapshot will be optimized for it, if applicable.
     73   */
     74  virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot(
     75      gfx::DrawTarget* aTarget = nullptr) = 0;
     76 
     77  virtual void ReturnSnapshot(
     78      already_AddRefed<gfx::SourceSurface> aSnapshot) = 0;
     79 
     80  virtual TextureClient* GetTextureClient() { return nullptr; }
     81 
     82  virtual Maybe<RemoteTextureOwnerId> GetRemoteTextureOwnerId() const {
     83    return Nothing();
     84  }
     85 
     86  virtual void OnMemoryPressure() {}
     87 
     88  virtual void OnShutdown() {}
     89 
     90  virtual bool SetKnowsCompositor(KnowsCompositor* aKnowsCompositor,
     91                                  bool& aOutLostFrontTexture) {
     92    return true;
     93  }
     94 
     95  virtual void ClearCachedResources() {}
     96 
     97  /**
     98   * Return true if this provider preserves the drawing state (clips,
     99   * transforms, etc.) across frames. In practice this means users of the
    100   * provider can skip popping all of the clips at the end of the frames and
    101   * pushing them back at the beginning of the following frames, which can be
    102   * costly (cf. bug 1294351).
    103   */
    104  virtual bool PreservesDrawingState() const = 0;
    105 
    106  /**
    107   * Whether or not the provider should be recreated, such as when profiling
    108   * heuristics determine this type of provider is no longer advantageous to
    109   * use.
    110   */
    111  virtual bool RequiresRefresh() const { return false; }
    112 
    113  virtual Maybe<SurfaceDescriptor> GetFrontBuffer() { return Nothing(); }
    114 
    115  virtual already_AddRefed<FwdTransactionTracker> UseCompositableForwarder(
    116      CompositableForwarder* aForwarder) {
    117    return nullptr;
    118  }
    119 };
    120 
    121 class PersistentBufferProviderBasic : public PersistentBufferProvider {
    122 public:
    123  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderBasic,
    124                                          override)
    125 
    126  static already_AddRefed<PersistentBufferProviderBasic> Create(
    127      gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
    128      gfx::BackendType aBackend);
    129 
    130  explicit PersistentBufferProviderBasic(gfx::DrawTarget* aTarget);
    131 
    132  already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(
    133      const gfx::IntRect& aPersistedRect) override;
    134 
    135  bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;
    136 
    137  already_AddRefed<gfx::SourceSurface> BorrowSnapshot(
    138      gfx::DrawTarget* aTarget) override;
    139 
    140  void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;
    141 
    142  bool PreservesDrawingState() const override { return true; }
    143 
    144  void OnShutdown() override { Destroy(); }
    145 
    146 protected:
    147  void Destroy();
    148 
    149  ~PersistentBufferProviderBasic() override;
    150 
    151  RefPtr<gfx::DrawTarget> mDrawTarget;
    152  RefPtr<gfx::SourceSurface> mSnapshot;
    153 };
    154 
    155 class PersistentBufferProviderAccelerated : public PersistentBufferProvider {
    156 public:
    157  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderAccelerated,
    158                                          override)
    159 
    160  static already_AddRefed<PersistentBufferProviderAccelerated> Create(
    161      gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
    162      KnowsCompositor* aKnowsCompositor);
    163 
    164  bool IsAccelerated() const override { return true; }
    165 
    166  already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(
    167      const gfx::IntRect& aPersistedRect) override;
    168 
    169  bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;
    170 
    171  already_AddRefed<gfx::SourceSurface> BorrowSnapshot(
    172      gfx::DrawTarget* aTarget) override;
    173 
    174  void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;
    175 
    176  Maybe<RemoteTextureOwnerId> GetRemoteTextureOwnerId() const override {
    177    return Some(mRemoteTextureOwnerId);
    178  }
    179 
    180  bool PreservesDrawingState() const override { return true; }
    181 
    182  void OnShutdown() override { Destroy(); }
    183 
    184  Maybe<SurfaceDescriptor> GetFrontBuffer() override;
    185 
    186  bool RequiresRefresh() const override;
    187 
    188  already_AddRefed<FwdTransactionTracker> UseCompositableForwarder(
    189      CompositableForwarder* aForwarder) override;
    190 
    191 protected:
    192  explicit PersistentBufferProviderAccelerated(
    193      RemoteTextureOwnerId aRemoteTextureOwnerId,
    194      const RefPtr<TextureClient>& aTexture);
    195  ~PersistentBufferProviderAccelerated() override;
    196 
    197  void Destroy();
    198 
    199  RemoteTextureOwnerId mRemoteTextureOwnerId;
    200  RefPtr<TextureClient> mTexture;
    201 
    202  RefPtr<gfx::DrawTarget> mDrawTarget;
    203  RefPtr<gfx::SourceSurface> mSnapshot;
    204 };
    205 
    206 /**
    207 * Provides access to a buffer which can be sent to the compositor without
    208 * requiring a copy.
    209 */
    210 class PersistentBufferProviderShared : public PersistentBufferProvider,
    211                                       public ActiveResource {
    212 public:
    213  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderShared,
    214                                          override)
    215 
    216  static already_AddRefed<PersistentBufferProviderShared> Create(
    217      gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
    218      KnowsCompositor* aKnowsCompositor, bool aWillReadFrequently = false,
    219      const Maybe<uint64_t>& aWindowID = Nothing());
    220 
    221  bool IsShared() const override { return true; }
    222 
    223  already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(
    224      const gfx::IntRect& aPersistedRect) override;
    225 
    226  bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;
    227 
    228  already_AddRefed<gfx::SourceSurface> BorrowSnapshot(
    229      gfx::DrawTarget* aTarget) override;
    230 
    231  void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;
    232 
    233  TextureClient* GetTextureClient() override;
    234 
    235  void NotifyInactive() override;
    236 
    237  void OnShutdown() override { Destroy(); }
    238 
    239  bool SetKnowsCompositor(KnowsCompositor* aKnowsCompositor,
    240                          bool& aOutLostFrontTexture) override;
    241 
    242  void ClearCachedResources() override;
    243 
    244  bool PreservesDrawingState() const override { return false; }
    245 
    246 protected:
    247  PersistentBufferProviderShared(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
    248                                 KnowsCompositor* aKnowsCompositor,
    249                                 RefPtr<TextureClient>& aTexture,
    250                                 bool aWillReadFrequently,
    251                                 const Maybe<uint64_t>& aWindowID);
    252 
    253  ~PersistentBufferProviderShared();
    254 
    255  TextureClient* GetTexture(const Maybe<uint32_t>& aIndex);
    256  bool CheckIndex(uint32_t aIndex) { return aIndex < mTextures.length(); }
    257 
    258  void Destroy();
    259 
    260  gfx::IntSize mSize;
    261  gfx::SurfaceFormat mFormat;
    262  RefPtr<KnowsCompositor> mKnowsCompositor;
    263  // If the texture has its own synchronization then copying back from the
    264  // previous texture can cause contention issues and even deadlocks. So we use
    265  // a separate permanent back buffer and copy into the shared back buffer when
    266  // the DrawTarget is returned, before making it the new front buffer.
    267  RefPtr<TextureClient> mPermanentBackBuffer;
    268  static const size_t kMaxTexturesAllowed = 5;
    269  Vector<RefPtr<TextureClient>, kMaxTexturesAllowed + 2> mTextures;
    270  // Offset of the texture in mTextures that the canvas uses.
    271  Maybe<uint32_t> mBack;
    272  // Offset of the texture in mTextures that is presented to the compositor.
    273  Maybe<uint32_t> mFront;
    274  // Whether to avoid acceleration.
    275  bool mWillReadFrequently = false;
    276  // Owning window ID of the buffer provider.
    277  Maybe<uint64_t> mWindowID;
    278 
    279  RefPtr<gfx::DrawTarget> mDrawTarget;
    280  RefPtr<gfx::SourceSurface> mSnapshot;
    281  size_t mMaxAllowedTextures = kMaxTexturesAllowed;
    282 };
    283 
    284 struct AutoReturnSnapshot final {
    285  PersistentBufferProvider* mBufferProvider;
    286  RefPtr<gfx::SourceSurface>* mSnapshot;
    287 
    288  explicit AutoReturnSnapshot(PersistentBufferProvider* aProvider = nullptr)
    289      : mBufferProvider(aProvider), mSnapshot(nullptr) {}
    290 
    291  ~AutoReturnSnapshot() {
    292    if (mBufferProvider) {
    293      mBufferProvider->ReturnSnapshot(mSnapshot ? mSnapshot->forget()
    294                                                : nullptr);
    295    }
    296  }
    297 };
    298 
    299 }  // namespace layers
    300 }  // namespace mozilla
    301 
    302 #endif