diff options
Diffstat (limited to 'gfx/layers/PersistentBufferProvider.h')
-rw-r--r-- | gfx/layers/PersistentBufferProvider.h | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/gfx/layers/PersistentBufferProvider.h b/gfx/layers/PersistentBufferProvider.h new file mode 100644 index 000000000..1a1355ca9 --- /dev/null +++ b/gfx/layers/PersistentBufferProvider.h @@ -0,0 +1,187 @@ +/* -*- 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; } + + /** + * 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 bool PreservesDrawingState() const override { return false; } +protected: + PersistentBufferProviderShared(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, + ShadowLayerForwarder* aFwd, + RefPtr<TextureClient>& aTexture); + + ~PersistentBufferProviderShared(); + + TextureClient* GetTexture(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 |