Bug 1874684 - Part 17: Fix uninitialised variable warnings from clang-tidy. r=allstarschh
[gecko.git] / gfx / 2d / DrawEventRecorder.h
blobc099973fbdd4c6ac6d556b8d1d36f8d08942a338
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"
14 #include <deque>
15 #include <functional>
16 #include <vector>
18 #include "ImageContainer.h"
19 #include "mozilla/DataMutex.h"
20 #include "mozilla/ThreadSafeWeakPtr.h"
21 #include "nsTHashMap.h"
22 #include "nsTHashSet.h"
23 #include "nsISupportsImpl.h"
25 namespace mozilla {
26 namespace gfx {
28 class DrawTargetRecording;
29 class PathRecording;
31 class DrawEventRecorderPrivate : public DrawEventRecorder {
32 public:
33 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderPrivate, override)
35 DrawEventRecorderPrivate();
36 virtual ~DrawEventRecorderPrivate();
37 RecorderType GetRecorderType() const override {
38 return RecorderType::PRIVATE;
40 bool Finish() override {
41 ClearResources();
42 return true;
44 virtual void FlushItem(IntRect) {}
45 virtual void DetachResources() {
46 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
48 nsTHashSet<ScaledFont*> fonts = std::move(mStoredFonts);
49 for (const auto& font : fonts) {
50 font->RemoveUserData(reinterpret_cast<UserDataKey*>(this));
53 // SourceSurfaces can be deleted off the main thread, so we use
54 // ThreadSafeWeakPtrs to allow for this. RemoveUserData is thread safe.
55 nsTHashMap<void*, ThreadSafeWeakPtr<SourceSurface>> surfaces =
56 std::move(mStoredSurfaces);
57 for (const auto& entry : surfaces) {
58 RefPtr<SourceSurface> strongRef(entry.GetData());
59 if (strongRef) {
60 strongRef->RemoveUserData(reinterpret_cast<UserDataKey*>(this));
64 // Now that we've detached we can't get any more pending deletions, so
65 // processing now should mean we include all clean up operations.
66 ProcessPendingDeletions();
69 void ClearResources() {
70 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
71 mStoredObjects.Clear();
72 mStoredFontData.Clear();
73 mScaledFonts.clear();
74 mCurrentDT = nullptr;
77 template <class S>
78 void WriteHeader(S& aStream) {
79 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
80 WriteElement(aStream, kMagicInt);
81 WriteElement(aStream, kMajorRevision);
82 WriteElement(aStream, kMinorRevision);
85 virtual void RecordEvent(const RecordedEvent& aEvent) = 0;
87 void RecordEvent(const DrawTargetRecording* aDT,
88 const RecordedEvent& aEvent) {
89 ReferencePtr dt = aDT;
90 if (mCurrentDT != dt) {
91 SetDrawTarget(dt);
93 RecordEvent(aEvent);
96 void SetDrawTarget(ReferencePtr aDT);
98 void ClearDrawTarget(const DrawTargetRecording* aDT) {
99 ReferencePtr dt = aDT;
100 if (mCurrentDT == dt) {
101 mCurrentDT = nullptr;
105 void AddStoredObject(const ReferencePtr aObject) {
106 ProcessPendingDeletions();
107 mStoredObjects.Insert(aObject);
111 * This is a combination of HasStoredObject and AddStoredObject, so that we
112 * only have to call ProcessPendingDeletions once, which involves locking.
113 * @param aObject the object to store if not already stored
114 * @return true if the object was not already stored, false if it was
116 bool TryAddStoredObject(const ReferencePtr aObject) {
117 ProcessPendingDeletions();
118 return mStoredObjects.EnsureInserted(aObject);
121 virtual void AddPendingDeletion(std::function<void()>&& aPendingDeletion) {
122 auto lockedPendingDeletions = mPendingDeletions.Lock();
123 lockedPendingDeletions->emplace_back(std::move(aPendingDeletion));
126 void RemoveStoredObject(const ReferencePtr aObject) {
127 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
128 mStoredObjects.Remove(aObject);
132 * @param aUnscaledFont the UnscaledFont to increment the reference count for
133 * @return the previous reference count
135 int32_t IncrementUnscaledFontRefCount(const ReferencePtr aUnscaledFont) {
136 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
137 int32_t& count = mUnscaledFontRefs.LookupOrInsert(aUnscaledFont, 0);
138 return count++;
142 * Decrements the reference count for aUnscaledFont and, if count is now zero,
143 * records its destruction.
144 * @param aUnscaledFont the UnscaledFont to decrement the reference count for
146 void DecrementUnscaledFontRefCount(const ReferencePtr aUnscaledFont);
148 void AddScaledFont(ScaledFont* aFont) {
149 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
150 if (mStoredFonts.EnsureInserted(aFont) && WantsExternalFonts()) {
151 mScaledFonts.push_back(aFont);
155 void RemoveScaledFont(ScaledFont* aFont) { mStoredFonts.Remove(aFont); }
157 void AddSourceSurface(SourceSurface* aSurface) {
158 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
159 mStoredSurfaces.InsertOrUpdate(aSurface, aSurface);
162 void RemoveSourceSurface(SourceSurface* aSurface) {
163 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
164 mStoredSurfaces.Remove(aSurface);
167 #if defined(DEBUG)
168 // Only used within debug assertions.
169 bool HasStoredObject(const ReferencePtr aObject) {
170 ProcessPendingDeletions();
171 return mStoredObjects.Contains(aObject);
173 #endif
175 void AddStoredFontData(const uint64_t aFontDataKey) {
176 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
177 mStoredFontData.Insert(aFontDataKey);
180 bool HasStoredFontData(const uint64_t aFontDataKey) {
181 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
182 return mStoredFontData.Contains(aFontDataKey);
185 bool WantsExternalFonts() const { return mExternalFonts; }
187 virtual void StoreSourceSurfaceRecording(SourceSurface* aSurface,
188 const char* aReason);
190 virtual void StoreImageRecording(
191 const RefPtr<layers::Image>& aImageOfSurfaceDescriptor,
192 const char* aReasony) {
193 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
197 * Used when a source surface is destroyed, aSurface is a void* instead of a
198 * SourceSurface* because this is called during the SourceSurface destructor,
199 * so it is partially destructed and should not be accessed.
200 * @param aSurface the surface whose destruction is being recorded
202 void RecordSourceSurfaceDestruction(void* aSurface);
204 virtual void AddDependentSurface(uint64_t aDependencyId) {
205 MOZ_CRASH("GFX: AddDependentSurface");
208 struct ExternalSurfaceEntry {
209 RefPtr<SourceSurface> mSurface;
210 int64_t mEventCount = -1;
213 using ExternalSurfacesHolder = std::deque<ExternalSurfaceEntry>;
215 void TakeExternalSurfaces(ExternalSurfacesHolder& aSurfaces) {
216 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
217 aSurfaces = std::move(mExternalSurfaces);
220 struct ExternalImageEntry {
221 RefPtr<layers::Image> mImage;
222 int64_t mEventCount = -1;
225 using ExternalImagesHolder = std::deque<ExternalImageEntry>;
227 protected:
228 NS_DECL_OWNINGTHREAD
230 void StoreExternalSurfaceRecording(SourceSurface* aSurface, uint64_t aKey);
232 void StoreExternalImageRecording(
233 const RefPtr<layers::Image>& aImageOfSurfaceDescriptor);
235 void ProcessPendingDeletions() {
236 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
238 PendingDeletionsVector pendingDeletions;
240 auto lockedPendingDeletions = mPendingDeletions.Lock();
241 pendingDeletions.swap(*lockedPendingDeletions);
243 for (const auto& pendingDeletion : pendingDeletions) {
244 pendingDeletion();
248 virtual void Flush() = 0;
250 nsTHashSet<const void*> mStoredObjects;
252 using PendingDeletionsVector = std::vector<std::function<void()>>;
253 DataMutex<PendingDeletionsVector> mPendingDeletions{
254 "DrawEventRecorderPrivate::mPendingDeletions"};
256 // It's difficult to track the lifetimes of UnscaledFonts directly, so we
257 // instead track the number of recorded ScaledFonts that hold a reference to
258 // an Unscaled font and use that as a proxy to the real lifetime. An
259 // UnscaledFonts lifetime could be longer than this, but we only use the
260 // ScaledFonts directly and if another uses an UnscaledFont we have destroyed
261 // on the translation side, it will be recreated.
262 nsTHashMap<const void*, int32_t> mUnscaledFontRefs;
264 nsTHashSet<uint64_t> mStoredFontData;
265 nsTHashSet<ScaledFont*> mStoredFonts;
266 std::vector<RefPtr<ScaledFont>> mScaledFonts;
268 // SourceSurfaces can get deleted off the main thread, so we hold a map of the
269 // raw pointer to a ThreadSafeWeakPtr to protect against this.
270 nsTHashMap<void*, ThreadSafeWeakPtr<SourceSurface>> mStoredSurfaces;
272 ReferencePtr mCurrentDT;
273 ExternalSurfacesHolder mExternalSurfaces;
274 ExternalImagesHolder mExternalImages;
275 bool mExternalFonts;
278 typedef std::function<void(MemStream& aStream,
279 std::vector<RefPtr<ScaledFont>>& aScaledFonts)>
280 SerializeResourcesFn;
282 // WARNING: This should not be used in its existing state because
283 // it is likely to OOM because of large continguous allocations.
284 class DrawEventRecorderMemory : public DrawEventRecorderPrivate {
285 public:
286 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderMemory, override)
289 * Constructs a DrawEventRecorder that stores the recording in memory.
291 DrawEventRecorderMemory();
292 explicit DrawEventRecorderMemory(const SerializeResourcesFn& aSerialize);
294 RecorderType GetRecorderType() const override { return RecorderType::MEMORY; }
296 void RecordEvent(const RecordedEvent& aEvent) override;
298 void AddDependentSurface(uint64_t aDependencyId) override;
300 nsTHashSet<uint64_t>&& TakeDependentSurfaces();
303 * @return the current size of the recording (in chars).
305 size_t RecordingSize();
308 * Wipes the internal recording buffer, but the recorder does NOT forget which
309 * objects it has recorded. This can be used so that a recording can be copied
310 * and processed in chunks, releasing memory as it goes.
312 void WipeRecording();
313 bool Finish() override;
314 void FlushItem(IntRect) override;
316 MemStream mOutputStream;
317 /* The index stream is of the form:
318 * ItemIndex { size_t dataEnd; size_t extraDataEnd; }
319 * It gets concatenated to the end of mOutputStream in Finish()
320 * The last size_t in the stream is offset of the begining of the
321 * index.
323 MemStream mIndex;
325 protected:
326 virtual ~DrawEventRecorderMemory() = default;
328 private:
329 SerializeResourcesFn mSerializeCallback;
330 nsTHashSet<uint64_t> mDependentSurfaces;
332 void Flush() override;
335 } // namespace gfx
336 } // namespace mozilla
338 #endif /* MOZILLA_GFX_DRAWEVENTRECORDER_H_ */