Bug 1638136 [wpt PR 23617] - Clipboard API Tests: Move permissions tests to WPT....
[gecko.git] / gfx / 2d / DrawEventRecorder.h
blobd756c3d941453209307cc20aeea8476fc0c17409
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_DRAWEVENTRECORDER_H_
8 #define MOZILLA_GFX_DRAWEVENTRECORDER_H_
10 #include "2D.h"
11 #include "RecordedEvent.h"
12 #include "RecordingTypes.h"
13 #include "mozilla/FStream.h"
15 #include <unordered_set>
16 #include <unordered_map>
17 #include <functional>
19 #include "nsHashKeys.h"
20 #include "nsTHashtable.h"
22 namespace mozilla {
23 namespace gfx {
25 class PathRecording;
27 class DrawEventRecorderPrivate : public DrawEventRecorder {
28 public:
29 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderPrivate, override)
31 DrawEventRecorderPrivate();
32 virtual ~DrawEventRecorderPrivate() = default;
33 bool Finish() override {
34 ClearResources();
35 return true;
37 virtual void FlushItem(IntRect) {}
38 void DetachResources() {
39 // The iteration is a bit awkward here because our iterator will
40 // be invalidated by the removal
41 for (auto font = mStoredFonts.begin(); font != mStoredFonts.end();) {
42 auto oldFont = font++;
43 (*oldFont)->RemoveUserData(reinterpret_cast<UserDataKey*>(this));
45 for (auto surface = mStoredSurfaces.begin();
46 surface != mStoredSurfaces.end();) {
47 auto oldSurface = surface++;
48 (*oldSurface)->RemoveUserData(reinterpret_cast<UserDataKey*>(this));
50 mStoredFonts.clear();
51 mStoredSurfaces.clear();
54 void ClearResources() {
55 mStoredObjects.clear();
56 mStoredFontData.clear();
57 mScaledFonts.clear();
60 template <class S>
61 void WriteHeader(S& aStream) {
62 WriteElement(aStream, kMagicInt);
63 WriteElement(aStream, kMajorRevision);
64 WriteElement(aStream, kMinorRevision);
67 virtual void RecordEvent(const RecordedEvent& aEvent) = 0;
68 void WritePath(const PathRecording* aPath);
70 void AddStoredObject(const ReferencePtr aObject) {
71 mStoredObjects.insert(aObject);
74 void RemoveStoredObject(const ReferencePtr aObject) {
75 mStoredObjects.erase(aObject);
78 /**
79 * @param aUnscaledFont the UnscaledFont to increment the reference count for
80 * @return the previous reference count
82 int32_t IncrementUnscaledFontRefCount(const ReferencePtr aUnscaledFont) {
83 int32_t& count = mUnscaledFontRefs[aUnscaledFont];
84 return count++;
87 /**
88 * Decrements the reference count for aUnscaledFont and, if count is now zero,
89 * records its destruction.
90 * @param aUnscaledFont the UnscaledFont to decrement the reference count for
92 void DecrementUnscaledFontRefCount(const ReferencePtr aUnscaledFont);
94 void AddScaledFont(ScaledFont* aFont) {
95 if (mStoredFonts.insert(aFont).second && WantsExternalFonts()) {
96 mScaledFonts.push_back(aFont);
100 void RemoveScaledFont(ScaledFont* aFont) { mStoredFonts.erase(aFont); }
102 void AddSourceSurface(SourceSurface* aSurface) {
103 mStoredSurfaces.insert(aSurface);
106 void RemoveSourceSurface(SourceSurface* aSurface) {
107 mStoredSurfaces.erase(aSurface);
110 bool HasStoredObject(const ReferencePtr aObject) {
111 return mStoredObjects.find(aObject) != mStoredObjects.end();
114 void AddStoredFontData(const uint64_t aFontDataKey) {
115 mStoredFontData.insert(aFontDataKey);
118 bool HasStoredFontData(const uint64_t aFontDataKey) {
119 return mStoredFontData.find(aFontDataKey) != mStoredFontData.end();
122 bool WantsExternalFonts() const { return mExternalFonts; }
124 void TakeExternalSurfaces(std::vector<RefPtr<SourceSurface>>& aSurfaces) {
125 aSurfaces = std::move(mExternalSurfaces);
128 virtual void StoreSourceSurfaceRecording(SourceSurface* aSurface,
129 const char* aReason);
131 virtual void RecordSourceSurfaceDestruction(SourceSurface* aSurface);
133 virtual void AddDependentSurface(uint64_t aDependencyId) {
134 MOZ_CRASH("GFX: AddDependentSurface");
137 protected:
138 void StoreExternalSurfaceRecording(SourceSurface* aSurface, uint64_t aKey);
140 virtual void Flush() = 0;
142 std::unordered_set<const void*> mStoredObjects;
144 // It's difficult to track the lifetimes of UnscaledFonts directly, so we
145 // instead track the number of recorded ScaledFonts that hold a reference to
146 // an Unscaled font and use that as a proxy to the real lifetime. An
147 // UnscaledFonts lifetime could be longer than this, but we only use the
148 // ScaledFonts directly and if another uses an UnscaledFont we have destroyed
149 // on the translation side, it will be recreated.
150 std::unordered_map<const void*, int32_t> mUnscaledFontRefs;
152 std::unordered_set<uint64_t> mStoredFontData;
153 std::unordered_set<ScaledFont*> mStoredFonts;
154 std::vector<RefPtr<ScaledFont>> mScaledFonts;
155 std::unordered_set<SourceSurface*> mStoredSurfaces;
156 std::vector<RefPtr<SourceSurface>> mExternalSurfaces;
157 bool mExternalFonts;
160 class DrawEventRecorderFile : public DrawEventRecorderPrivate {
161 using char_type = filesystem::Path::value_type;
163 public:
164 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderFile, override)
165 explicit DrawEventRecorderFile(const char_type* aFilename);
166 virtual ~DrawEventRecorderFile();
168 void RecordEvent(const RecordedEvent& aEvent) override;
171 * Returns whether a recording file is currently open.
173 bool IsOpen();
176 * Opens new file with the provided name. The recorder does NOT forget which
177 * objects it has recorded. This can be used with Close, so that a recording
178 * can be processed in chunks. The file must not already be open.
180 void OpenNew(const char_type* aFilename);
183 * Closes the file so that it can be processed. The recorder does NOT forget
184 * which objects it has recorded. This can be used with OpenNew, so that a
185 * recording can be processed in chunks. The file must be open.
187 void Close();
189 private:
190 void Flush() override;
192 mozilla::OFStream mOutputStream;
195 typedef std::function<void(MemStream& aStream,
196 std::vector<RefPtr<ScaledFont>>& aScaledFonts)>
197 SerializeResourcesFn;
199 // WARNING: This should not be used in its existing state because
200 // it is likely to OOM because of large continguous allocations.
201 class DrawEventRecorderMemory : public DrawEventRecorderPrivate {
202 public:
203 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderMemory, override)
206 * Constructs a DrawEventRecorder that stores the recording in memory.
208 DrawEventRecorderMemory();
209 explicit DrawEventRecorderMemory(const SerializeResourcesFn& aSerialize);
211 void RecordEvent(const RecordedEvent& aEvent) override;
213 void AddDependentSurface(uint64_t aDependencyId) override;
215 nsTHashtable<nsUint64HashKey>&& TakeDependentSurfaces();
218 * @return the current size of the recording (in chars).
220 size_t RecordingSize();
223 * Wipes the internal recording buffer, but the recorder does NOT forget which
224 * objects it has recorded. This can be used so that a recording can be copied
225 * and processed in chunks, releasing memory as it goes.
227 void WipeRecording();
228 bool Finish() override;
229 void FlushItem(IntRect) override;
231 MemStream mOutputStream;
232 /* The index stream is of the form:
233 * ItemIndex { size_t dataEnd; size_t extraDataEnd; }
234 * It gets concatenated to the end of mOutputStream in Finish()
235 * The last size_t in the stream is offset of the begining of the
236 * index.
238 MemStream mIndex;
240 protected:
241 virtual ~DrawEventRecorderMemory() = default;
243 private:
244 SerializeResourcesFn mSerializeCallback;
245 nsTHashtable<nsUint64HashKey> mDependentSurfaces;
247 void Flush() override;
250 } // namespace gfx
251 } // namespace mozilla
253 #endif /* MOZILLA_GFX_DRAWEVENTRECORDER_H_ */