DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (d38398e5144e)

VCS Links

AutoReturnSnapshot

PersistentBufferProvider

PersistentBufferProviderBasic

PersistentBufferProviderShared

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef MOZILLA_GFX_PersistentBUFFERPROVIDER_H
#define MOZILLA_GFX_PersistentBUFFERPROVIDER_H

#include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
#include "mozilla/RefPtr.h"             // for RefPtr, already_AddRefed, etc
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/ShadowLayers.h"
#include "mozilla/gfx/Types.h"
#include "mozilla/Vector.h"

namespace mozilla {

namespace gfx {
  class SourceSurface;
  class DrawTarget;
}

namespace layers {

class CopyableCanvasLayer;

/**
 * A PersistentBufferProvider is for users which require the temporary use of
 * a DrawTarget to draw into. When they're done drawing they return the
 * DrawTarget, when they later need to continue drawing they get a DrawTarget
 * from the provider again, the provider will guarantee the contents of the
 * previously returned DrawTarget is persisted into the one newly returned.
 */
class PersistentBufferProvider : public RefCounted<PersistentBufferProvider>
{
public:
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProvider)

  virtual ~PersistentBufferProvider() { }

  virtual LayersBackend GetType() { return LayersBackend::LAYERS_NONE; }

  /**
   * Get a DrawTarget from the PersistentBufferProvider.
   *
   * \param aPersistedRect This indicates the area of the DrawTarget that needs
   *                       to have remained the same since the call to
   *                       ReturnDrawTarget.
   */
  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(const gfx::IntRect& aPersistedRect) = 0;

  /**
   * Return a DrawTarget to the PersistentBufferProvider and indicate the
   * contents of this DrawTarget is to be considered current by the
   * BufferProvider. The caller should forget any references to the DrawTarget.
   */
  virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) = 0;

  virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot() = 0;

  virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) = 0;

  virtual TextureClient* GetTextureClient() { return nullptr; }

  virtual void OnShutdown() {}

  virtual bool SetForwarder(ShadowLayerForwarder* aFwd) { return true; }

  virtual void ClearCachedResources() {}

  /**
   * Return true if this provider preserves the drawing state (clips, transforms,
   * etc.) across frames. In practice this means users of the provider can skip
   * popping all of the clips at the end of the frames and pushing them back at
   * the beginning of the following frames, which can be costly (cf. bug 1294351).
   */
  virtual bool PreservesDrawingState() const = 0;
};


class PersistentBufferProviderBasic : public PersistentBufferProvider
{
public:
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderBasic, override)

  static already_AddRefed<PersistentBufferProviderBasic>
  Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, gfx::BackendType aBackend);

  explicit PersistentBufferProviderBasic(gfx::DrawTarget* aTarget);

  virtual LayersBackend GetType() override { return LayersBackend::LAYERS_BASIC; }

  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(const gfx::IntRect& aPersistedRect) override;

  virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;

  virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot() override;

  virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;

  virtual bool PreservesDrawingState() const override { return true; }
private:
  ~PersistentBufferProviderBasic();

  RefPtr<gfx::DrawTarget> mDrawTarget;
  RefPtr<gfx::SourceSurface> mSnapshot;
};


/**
 * Provides access to a buffer which can be sent to the compositor without
 * requiring a copy.
 */
class PersistentBufferProviderShared : public PersistentBufferProvider
                                     , public ActiveResource
{
public:
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderShared, override)

  static already_AddRefed<PersistentBufferProviderShared>
  Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
         ShadowLayerForwarder* aFwd);

  virtual LayersBackend GetType() override { return LayersBackend::LAYERS_CLIENT; }

  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(const gfx::IntRect& aPersistedRect) override;

  virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;

  virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot() override;

  virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;

  virtual TextureClient* GetTextureClient() override;

  virtual void NotifyInactive() override;

  virtual void OnShutdown() override { Destroy(); }

  virtual bool SetForwarder(ShadowLayerForwarder* aFwd) override;

  virtual void ClearCachedResources() override;

  virtual bool PreservesDrawingState() const override { return false; }
protected:
  PersistentBufferProviderShared(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                                 ShadowLayerForwarder* aFwd,
                                 RefPtr<TextureClient>& aTexture);

  ~PersistentBufferProviderShared();

  TextureClient* GetTexture(const Maybe<uint32_t>& aIndex);
  bool CheckIndex(uint32_t aIndex) { return aIndex < mTextures.length(); }

  void Destroy();

  gfx::IntSize mSize;
  gfx::SurfaceFormat mFormat;
  RefPtr<ShadowLayerForwarder> mFwd;
  Vector<RefPtr<TextureClient>, 4> mTextures;
  // Offset of the texture in mTextures that the canvas uses.
  Maybe<uint32_t> mBack;
  // Offset of the texture in mTextures that is presented to the compositor.
  Maybe<uint32_t> mFront;

  RefPtr<gfx::DrawTarget> mDrawTarget;
  RefPtr<gfx::SourceSurface > mSnapshot;
};

struct AutoReturnSnapshot
{
  PersistentBufferProvider* mBufferProvider;
  RefPtr<gfx::SourceSurface>* mSnapshot;

  explicit AutoReturnSnapshot(PersistentBufferProvider* aProvider = nullptr)
  : mBufferProvider(aProvider)
  , mSnapshot(nullptr)
  {}

  ~AutoReturnSnapshot()
  {
    if (mBufferProvider) {
      mBufferProvider->ReturnSnapshot(mSnapshot ? mSnapshot->forget() : nullptr);
    }
  }
};

} // namespace layers
} // namespace mozilla

#endif