Bug 1860298 [wpt PR 42668] - [FedCM] Check "same origin with ancestors" for subresour...
[gecko.git] / gfx / layers / PersistentBufferProvider.h
blob25abcc8fcb127d71702248aae8e7ce84a434e5b5
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/. */
7 #ifndef MOZILLA_GFX_PersistentBUFFERPROVIDER_H
8 #define MOZILLA_GFX_PersistentBUFFERPROVIDER_H
10 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
11 #include "mozilla/RefPtr.h" // for RefPtr, already_AddRefed, etc
12 #include "mozilla/layers/KnowsCompositor.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"
20 namespace mozilla {
22 class ClientWebGLContext;
24 namespace gfx {
25 class SourceSurface;
26 class DrawTarget;
27 class DrawTargetWebgl;
28 } // namespace gfx
30 namespace layers {
32 class TextureClient;
34 /**
35 * A PersistentBufferProvider is for users which require the temporary use of
36 * a DrawTarget to draw into. When they're done drawing they return the
37 * DrawTarget, when they later need to continue drawing they get a DrawTarget
38 * from the provider again, the provider will guarantee the contents of the
39 * previously returned DrawTarget is persisted into the one newly returned.
41 class PersistentBufferProvider : public RefCounted<PersistentBufferProvider>,
42 public SupportsWeakPtr {
43 public:
44 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProvider)
46 virtual ~PersistentBufferProvider() = default;
48 virtual bool IsShared() const { return false; }
49 virtual bool IsAccelerated() const { return false; }
51 /**
52 * Get a DrawTarget from the PersistentBufferProvider.
54 * \param aPersistedRect This indicates the area of the DrawTarget that needs
55 * to have remained the same since the call to
56 * ReturnDrawTarget.
58 virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(
59 const gfx::IntRect& aPersistedRect) = 0;
61 /**
62 * Return a DrawTarget to the PersistentBufferProvider and indicate the
63 * contents of this DrawTarget is to be considered current by the
64 * BufferProvider. The caller should forget any references to the DrawTarget.
66 virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) = 0;
68 /**
69 * Temporarily borrow a snapshot of the provider. If a target is supplied,
70 * the snapshot will be optimized for it, if applicable.
72 virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot(
73 gfx::DrawTarget* aTarget = nullptr) = 0;
75 virtual void ReturnSnapshot(
76 already_AddRefed<gfx::SourceSurface> aSnapshot) = 0;
78 virtual TextureClient* GetTextureClient() { return nullptr; }
80 virtual void OnMemoryPressure() {}
82 virtual void OnShutdown() {}
84 virtual bool SetKnowsCompositor(KnowsCompositor* aKnowsCompositor,
85 bool& aOutLostFrontTexture) {
86 return true;
89 virtual void ClearCachedResources() {}
91 /**
92 * Return true if this provider preserves the drawing state (clips,
93 * transforms, etc.) across frames. In practice this means users of the
94 * provider can skip popping all of the clips at the end of the frames and
95 * pushing them back at the beginning of the following frames, which can be
96 * costly (cf. bug 1294351).
98 virtual bool PreservesDrawingState() const = 0;
101 * Whether or not the provider should be recreated, such as when profiling
102 * heuristics determine this type of provider is no longer advantageous to
103 * use.
105 virtual bool RequiresRefresh() const { return false; }
108 * Provide a WebGL front buffer for compositing, if available.
110 virtual Maybe<layers::SurfaceDescriptor> GetFrontBuffer() {
111 return Nothing();
115 class PersistentBufferProviderBasic : public PersistentBufferProvider {
116 public:
117 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderBasic,
118 override)
120 static already_AddRefed<PersistentBufferProviderBasic> Create(
121 gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
122 gfx::BackendType aBackend);
124 explicit PersistentBufferProviderBasic(gfx::DrawTarget* aTarget);
126 already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(
127 const gfx::IntRect& aPersistedRect) override;
129 bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;
131 already_AddRefed<gfx::SourceSurface> BorrowSnapshot(
132 gfx::DrawTarget* aTarget) override;
134 void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;
136 bool PreservesDrawingState() const override { return true; }
138 void OnShutdown() override { Destroy(); }
140 protected:
141 void Destroy();
143 ~PersistentBufferProviderBasic() override;
145 RefPtr<gfx::DrawTarget> mDrawTarget;
146 RefPtr<gfx::SourceSurface> mSnapshot;
149 class PersistentBufferProviderAccelerated
150 : public PersistentBufferProviderBasic {
151 public:
152 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderAccelerated,
153 override)
155 explicit PersistentBufferProviderAccelerated(gfx::DrawTarget* aTarget);
157 bool IsAccelerated() const override { return true; }
159 Maybe<layers::SurfaceDescriptor> GetFrontBuffer() override;
161 already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(
162 const gfx::IntRect& aPersistedRect) override;
164 bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;
166 already_AddRefed<gfx::SourceSurface> BorrowSnapshot(
167 gfx::DrawTarget* aTarget) override;
169 bool RequiresRefresh() const override;
171 void OnMemoryPressure() override;
173 protected:
174 ~PersistentBufferProviderAccelerated() override;
176 gfx::DrawTargetWebgl* GetDrawTargetWebgl() const;
180 * Provides access to a buffer which can be sent to the compositor without
181 * requiring a copy.
183 class PersistentBufferProviderShared : public PersistentBufferProvider,
184 public ActiveResource {
185 public:
186 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderShared,
187 override)
189 static already_AddRefed<PersistentBufferProviderShared> Create(
190 gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
191 KnowsCompositor* aKnowsCompositor, bool aWillReadFrequently = false);
193 bool IsShared() const override { return true; }
195 already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(
196 const gfx::IntRect& aPersistedRect) override;
198 bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;
200 already_AddRefed<gfx::SourceSurface> BorrowSnapshot(
201 gfx::DrawTarget* aTarget) override;
203 void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;
205 TextureClient* GetTextureClient() override;
207 void NotifyInactive() override;
209 void OnShutdown() override { Destroy(); }
211 bool SetKnowsCompositor(KnowsCompositor* aKnowsCompositor,
212 bool& aOutLostFrontTexture) override;
214 void ClearCachedResources() override;
216 bool PreservesDrawingState() const override { return false; }
218 bool IsAccelerated() const override;
220 protected:
221 PersistentBufferProviderShared(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
222 KnowsCompositor* aKnowsCompositor,
223 RefPtr<TextureClient>& aTexture,
224 bool aWillReadFrequently);
226 ~PersistentBufferProviderShared();
228 TextureClient* GetTexture(const Maybe<uint32_t>& aIndex);
229 bool CheckIndex(uint32_t aIndex) { return aIndex < mTextures.length(); }
231 void Destroy();
233 gfx::IntSize mSize;
234 gfx::SurfaceFormat mFormat;
235 RefPtr<KnowsCompositor> mKnowsCompositor;
236 // If the texture has its own synchronization then copying back from the
237 // previous texture can cause contention issues and even deadlocks. So we use
238 // a separate permanent back buffer and copy into the shared back buffer when
239 // the DrawTarget is returned, before making it the new front buffer.
240 RefPtr<TextureClient> mPermanentBackBuffer;
241 static const size_t kMaxTexturesAllowed = 5;
242 Vector<RefPtr<TextureClient>, kMaxTexturesAllowed + 2> mTextures;
243 // Offset of the texture in mTextures that the canvas uses.
244 Maybe<uint32_t> mBack;
245 // Offset of the texture in mTextures that is presented to the compositor.
246 Maybe<uint32_t> mFront;
247 // Whether to avoid acceleration.
248 bool mWillReadFrequently = false;
250 RefPtr<gfx::DrawTarget> mDrawTarget;
251 RefPtr<gfx::SourceSurface> mSnapshot;
252 size_t mMaxAllowedTextures = kMaxTexturesAllowed;
255 struct AutoReturnSnapshot final {
256 PersistentBufferProvider* mBufferProvider;
257 RefPtr<gfx::SourceSurface>* mSnapshot;
259 explicit AutoReturnSnapshot(PersistentBufferProvider* aProvider = nullptr)
260 : mBufferProvider(aProvider), mSnapshot(nullptr) {}
262 ~AutoReturnSnapshot() {
263 if (mBufferProvider) {
264 mBufferProvider->ReturnSnapshot(mSnapshot ? mSnapshot->forget()
265 : nullptr);
270 } // namespace layers
271 } // namespace mozilla
273 #endif