Bug 1891710: part 2) Enable <Element-outerHTML.html> WPT for Trusted Types. r=smaug
[gecko.git] / gfx / layers / PersistentBufferProvider.h
blob6451ea90d6797b8b9661dd73c86c9e614431c391
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/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"
20 namespace mozilla {
22 class ClientWebGLContext;
24 namespace gfx {
25 class SourceSurface;
26 class DrawTarget;
27 } // namespace gfx
29 namespace layers {
31 class CompositableForwarder;
32 class FwdTransactionTracker;
33 class KnowsCompositor;
34 struct RemoteTextureOwnerId;
35 class TextureClient;
37 /**
38 * A PersistentBufferProvider is for users which require the temporary use of
39 * a DrawTarget to draw into. When they're done drawing they return the
40 * DrawTarget, when they later need to continue drawing they get a DrawTarget
41 * from the provider again, the provider will guarantee the contents of the
42 * previously returned DrawTarget is persisted into the one newly returned.
44 class PersistentBufferProvider : public RefCounted<PersistentBufferProvider>,
45 public SupportsWeakPtr {
46 public:
47 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProvider)
49 virtual ~PersistentBufferProvider() = default;
51 virtual bool IsShared() const { return false; }
52 virtual bool IsAccelerated() const { return false; }
54 /**
55 * Get a DrawTarget from the PersistentBufferProvider.
57 * \param aPersistedRect This indicates the area of the DrawTarget that needs
58 * to have remained the same since the call to
59 * ReturnDrawTarget.
61 virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(
62 const gfx::IntRect& aPersistedRect) = 0;
64 /**
65 * Return a DrawTarget to the PersistentBufferProvider and indicate the
66 * contents of this DrawTarget is to be considered current by the
67 * BufferProvider. The caller should forget any references to the DrawTarget.
69 virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) = 0;
71 /**
72 * Temporarily borrow a snapshot of the provider. If a target is supplied,
73 * the snapshot will be optimized for it, if applicable.
75 virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot(
76 gfx::DrawTarget* aTarget = nullptr) = 0;
78 virtual void ReturnSnapshot(
79 already_AddRefed<gfx::SourceSurface> aSnapshot) = 0;
81 virtual TextureClient* GetTextureClient() { return nullptr; }
83 virtual void OnMemoryPressure() {}
85 virtual void OnShutdown() {}
87 virtual bool SetKnowsCompositor(KnowsCompositor* aKnowsCompositor,
88 bool& aOutLostFrontTexture) {
89 return true;
92 virtual void ClearCachedResources() {}
94 /**
95 * Return true if this provider preserves the drawing state (clips,
96 * transforms, etc.) across frames. In practice this means users of the
97 * provider can skip popping all of the clips at the end of the frames and
98 * pushing them back at the beginning of the following frames, which can be
99 * costly (cf. bug 1294351).
101 virtual bool PreservesDrawingState() const = 0;
104 * Whether or not the provider should be recreated, such as when profiling
105 * heuristics determine this type of provider is no longer advantageous to
106 * use.
108 virtual bool RequiresRefresh() const { return false; }
110 virtual Maybe<SurfaceDescriptor> GetFrontBuffer() { return Nothing(); }
112 virtual already_AddRefed<FwdTransactionTracker> UseCompositableForwarder(
113 CompositableForwarder* aForwarder) {
114 return nullptr;
118 class PersistentBufferProviderBasic : public PersistentBufferProvider {
119 public:
120 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderBasic,
121 override)
123 static already_AddRefed<PersistentBufferProviderBasic> Create(
124 gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
125 gfx::BackendType aBackend);
127 explicit PersistentBufferProviderBasic(gfx::DrawTarget* aTarget);
129 already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(
130 const gfx::IntRect& aPersistedRect) override;
132 bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;
134 already_AddRefed<gfx::SourceSurface> BorrowSnapshot(
135 gfx::DrawTarget* aTarget) override;
137 void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;
139 bool PreservesDrawingState() const override { return true; }
141 void OnShutdown() override { Destroy(); }
143 protected:
144 void Destroy();
146 ~PersistentBufferProviderBasic() override;
148 RefPtr<gfx::DrawTarget> mDrawTarget;
149 RefPtr<gfx::SourceSurface> mSnapshot;
152 class PersistentBufferProviderAccelerated : public PersistentBufferProvider {
153 public:
154 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderAccelerated,
155 override)
157 static already_AddRefed<PersistentBufferProviderAccelerated> Create(
158 gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
159 KnowsCompositor* aKnowsCompositor);
161 bool IsAccelerated() const override { return true; }
163 already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(
164 const gfx::IntRect& aPersistedRect) override;
166 bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;
168 already_AddRefed<gfx::SourceSurface> BorrowSnapshot(
169 gfx::DrawTarget* aTarget) override;
171 void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;
173 bool PreservesDrawingState() const override { return true; }
175 void OnShutdown() override { Destroy(); }
177 Maybe<SurfaceDescriptor> GetFrontBuffer() override;
179 bool RequiresRefresh() const override;
181 already_AddRefed<FwdTransactionTracker> UseCompositableForwarder(
182 CompositableForwarder* aForwarder) override;
184 protected:
185 explicit PersistentBufferProviderAccelerated(
186 const RefPtr<TextureClient>& aTexture);
187 ~PersistentBufferProviderAccelerated() override;
189 void Destroy();
191 RefPtr<TextureClient> mTexture;
193 RefPtr<gfx::DrawTarget> mDrawTarget;
194 RefPtr<gfx::SourceSurface> mSnapshot;
198 * Provides access to a buffer which can be sent to the compositor without
199 * requiring a copy.
201 class PersistentBufferProviderShared : public PersistentBufferProvider,
202 public ActiveResource {
203 public:
204 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderShared,
205 override)
207 static already_AddRefed<PersistentBufferProviderShared> Create(
208 gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
209 KnowsCompositor* aKnowsCompositor, bool aWillReadFrequently = false,
210 const Maybe<uint64_t>& aWindowID = Nothing());
212 bool IsShared() const override { return true; }
214 already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(
215 const gfx::IntRect& aPersistedRect) override;
217 bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;
219 already_AddRefed<gfx::SourceSurface> BorrowSnapshot(
220 gfx::DrawTarget* aTarget) override;
222 void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;
224 TextureClient* GetTextureClient() override;
226 void NotifyInactive() override;
228 void OnShutdown() override { Destroy(); }
230 bool SetKnowsCompositor(KnowsCompositor* aKnowsCompositor,
231 bool& aOutLostFrontTexture) override;
233 void ClearCachedResources() override;
235 bool PreservesDrawingState() const override { return false; }
237 protected:
238 PersistentBufferProviderShared(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
239 KnowsCompositor* aKnowsCompositor,
240 RefPtr<TextureClient>& aTexture,
241 bool aWillReadFrequently,
242 const Maybe<uint64_t>& aWindowID);
244 ~PersistentBufferProviderShared();
246 TextureClient* GetTexture(const Maybe<uint32_t>& aIndex);
247 bool CheckIndex(uint32_t aIndex) { return aIndex < mTextures.length(); }
249 void Destroy();
251 gfx::IntSize mSize;
252 gfx::SurfaceFormat mFormat;
253 RefPtr<KnowsCompositor> mKnowsCompositor;
254 // If the texture has its own synchronization then copying back from the
255 // previous texture can cause contention issues and even deadlocks. So we use
256 // a separate permanent back buffer and copy into the shared back buffer when
257 // the DrawTarget is returned, before making it the new front buffer.
258 RefPtr<TextureClient> mPermanentBackBuffer;
259 static const size_t kMaxTexturesAllowed = 5;
260 Vector<RefPtr<TextureClient>, kMaxTexturesAllowed + 2> mTextures;
261 // Offset of the texture in mTextures that the canvas uses.
262 Maybe<uint32_t> mBack;
263 // Offset of the texture in mTextures that is presented to the compositor.
264 Maybe<uint32_t> mFront;
265 // Whether to avoid acceleration.
266 bool mWillReadFrequently = false;
267 // Owning window ID of the buffer provider.
268 Maybe<uint64_t> mWindowID;
270 RefPtr<gfx::DrawTarget> mDrawTarget;
271 RefPtr<gfx::SourceSurface> mSnapshot;
272 size_t mMaxAllowedTextures = kMaxTexturesAllowed;
275 struct AutoReturnSnapshot final {
276 PersistentBufferProvider* mBufferProvider;
277 RefPtr<gfx::SourceSurface>* mSnapshot;
279 explicit AutoReturnSnapshot(PersistentBufferProvider* aProvider = nullptr)
280 : mBufferProvider(aProvider), mSnapshot(nullptr) {}
282 ~AutoReturnSnapshot() {
283 if (mBufferProvider) {
284 mBufferProvider->ReturnSnapshot(mSnapshot ? mSnapshot->forget()
285 : nullptr);
290 } // namespace layers
291 } // namespace mozilla
293 #endif