From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- gfx/layers/PersistentBufferProvider.h | 273 ++++++++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 gfx/layers/PersistentBufferProvider.h (limited to 'gfx/layers/PersistentBufferProvider.h') diff --git a/gfx/layers/PersistentBufferProvider.h b/gfx/layers/PersistentBufferProvider.h new file mode 100644 index 0000000000..25abcc8fcb --- /dev/null +++ b/gfx/layers/PersistentBufferProvider.h @@ -0,0 +1,273 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/KnowsCompositor.h" +#include "mozilla/layers/LayersSurfaces.h" +#include "mozilla/layers/LayersTypes.h" +#include "mozilla/RefCounted.h" +#include "mozilla/gfx/Types.h" +#include "mozilla/Vector.h" +#include "mozilla/WeakPtr.h" + +namespace mozilla { + +class ClientWebGLContext; + +namespace gfx { +class SourceSurface; +class DrawTarget; +class DrawTargetWebgl; +} // namespace gfx + +namespace layers { + +class TextureClient; + +/** + * 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, + public SupportsWeakPtr { + public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProvider) + + virtual ~PersistentBufferProvider() = default; + + virtual bool IsShared() const { return false; } + virtual bool IsAccelerated() const { return false; } + + /** + * 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 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 aDT) = 0; + + /** + * Temporarily borrow a snapshot of the provider. If a target is supplied, + * the snapshot will be optimized for it, if applicable. + */ + virtual already_AddRefed BorrowSnapshot( + gfx::DrawTarget* aTarget = nullptr) = 0; + + virtual void ReturnSnapshot( + already_AddRefed aSnapshot) = 0; + + virtual TextureClient* GetTextureClient() { return nullptr; } + + virtual void OnMemoryPressure() {} + + virtual void OnShutdown() {} + + virtual bool SetKnowsCompositor(KnowsCompositor* aKnowsCompositor, + bool& aOutLostFrontTexture) { + 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; + + /** + * Whether or not the provider should be recreated, such as when profiling + * heuristics determine this type of provider is no longer advantageous to + * use. + */ + virtual bool RequiresRefresh() const { return false; } + + /** + * Provide a WebGL front buffer for compositing, if available. + */ + virtual Maybe GetFrontBuffer() { + return Nothing(); + } +}; + +class PersistentBufferProviderBasic : public PersistentBufferProvider { + public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderBasic, + override) + + static already_AddRefed Create( + gfx::IntSize aSize, gfx::SurfaceFormat aFormat, + gfx::BackendType aBackend); + + explicit PersistentBufferProviderBasic(gfx::DrawTarget* aTarget); + + already_AddRefed BorrowDrawTarget( + const gfx::IntRect& aPersistedRect) override; + + bool ReturnDrawTarget(already_AddRefed aDT) override; + + already_AddRefed BorrowSnapshot( + gfx::DrawTarget* aTarget) override; + + void ReturnSnapshot(already_AddRefed aSnapshot) override; + + bool PreservesDrawingState() const override { return true; } + + void OnShutdown() override { Destroy(); } + + protected: + void Destroy(); + + ~PersistentBufferProviderBasic() override; + + RefPtr mDrawTarget; + RefPtr mSnapshot; +}; + +class PersistentBufferProviderAccelerated + : public PersistentBufferProviderBasic { + public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderAccelerated, + override) + + explicit PersistentBufferProviderAccelerated(gfx::DrawTarget* aTarget); + + bool IsAccelerated() const override { return true; } + + Maybe GetFrontBuffer() override; + + already_AddRefed BorrowDrawTarget( + const gfx::IntRect& aPersistedRect) override; + + bool ReturnDrawTarget(already_AddRefed aDT) override; + + already_AddRefed BorrowSnapshot( + gfx::DrawTarget* aTarget) override; + + bool RequiresRefresh() const override; + + void OnMemoryPressure() override; + + protected: + ~PersistentBufferProviderAccelerated() override; + + gfx::DrawTargetWebgl* GetDrawTargetWebgl() const; +}; + +/** + * 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 Create( + gfx::IntSize aSize, gfx::SurfaceFormat aFormat, + KnowsCompositor* aKnowsCompositor, bool aWillReadFrequently = false); + + bool IsShared() const override { return true; } + + already_AddRefed BorrowDrawTarget( + const gfx::IntRect& aPersistedRect) override; + + bool ReturnDrawTarget(already_AddRefed aDT) override; + + already_AddRefed BorrowSnapshot( + gfx::DrawTarget* aTarget) override; + + void ReturnSnapshot(already_AddRefed aSnapshot) override; + + TextureClient* GetTextureClient() override; + + void NotifyInactive() override; + + void OnShutdown() override { Destroy(); } + + bool SetKnowsCompositor(KnowsCompositor* aKnowsCompositor, + bool& aOutLostFrontTexture) override; + + void ClearCachedResources() override; + + bool PreservesDrawingState() const override { return false; } + + bool IsAccelerated() const override; + + protected: + PersistentBufferProviderShared(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, + KnowsCompositor* aKnowsCompositor, + RefPtr& aTexture, + bool aWillReadFrequently); + + ~PersistentBufferProviderShared(); + + TextureClient* GetTexture(const Maybe& aIndex); + bool CheckIndex(uint32_t aIndex) { return aIndex < mTextures.length(); } + + void Destroy(); + + gfx::IntSize mSize; + gfx::SurfaceFormat mFormat; + RefPtr mKnowsCompositor; + // If the texture has its own synchronization then copying back from the + // previous texture can cause contention issues and even deadlocks. So we use + // a separate permanent back buffer and copy into the shared back buffer when + // the DrawTarget is returned, before making it the new front buffer. + RefPtr mPermanentBackBuffer; + static const size_t kMaxTexturesAllowed = 5; + Vector, kMaxTexturesAllowed + 2> mTextures; + // Offset of the texture in mTextures that the canvas uses. + Maybe mBack; + // Offset of the texture in mTextures that is presented to the compositor. + Maybe mFront; + // Whether to avoid acceleration. + bool mWillReadFrequently = false; + + RefPtr mDrawTarget; + RefPtr mSnapshot; + size_t mMaxAllowedTextures = kMaxTexturesAllowed; +}; + +struct AutoReturnSnapshot final { + PersistentBufferProvider* mBufferProvider; + RefPtr* mSnapshot; + + explicit AutoReturnSnapshot(PersistentBufferProvider* aProvider = nullptr) + : mBufferProvider(aProvider), mSnapshot(nullptr) {} + + ~AutoReturnSnapshot() { + if (mBufferProvider) { + mBufferProvider->ReturnSnapshot(mSnapshot ? mSnapshot->forget() + : nullptr); + } + } +}; + +} // namespace layers +} // namespace mozilla + +#endif -- cgit v1.2.3