Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/2d/DrawEventRecorder.h
Line
Count
Source (jump to first uncovered line)
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/. */
6
7
#ifndef MOZILLA_GFX_DRAWEVENTRECORDER_H_
8
#define MOZILLA_GFX_DRAWEVENTRECORDER_H_
9
10
#include "2D.h"
11
#include "RecordedEvent.h"
12
#include "RecordingTypes.h"
13
#include "mozilla/FStream.h"
14
15
#include <unordered_set>
16
#include <unordered_map>
17
#include <functional>
18
19
namespace mozilla {
20
namespace gfx {
21
22
class PathRecording;
23
24
class DrawEventRecorderPrivate : public DrawEventRecorder
25
{
26
public:
27
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderPrivate, override)
28
29
  DrawEventRecorderPrivate();
30
0
  virtual ~DrawEventRecorderPrivate() { }
31
0
  virtual bool Finish() override { ClearResources(); return true; }
32
0
  virtual void FlushItem(IntRect) { }
33
0
  void DetachResources() {
34
0
    // The iteration is a bit awkward here because our iterator will
35
0
    // be invalidated by the removal
36
0
    for (auto font = mStoredFonts.begin(); font != mStoredFonts.end(); ) {
37
0
      auto oldFont = font++;
38
0
      (*oldFont)->RemoveUserData(reinterpret_cast<UserDataKey*>(this));
39
0
    }
40
0
    for (auto surface = mStoredSurfaces.begin(); surface != mStoredSurfaces.end(); ) {
41
0
      auto oldSurface = surface++;
42
0
      (*oldSurface)->RemoveUserData(reinterpret_cast<UserDataKey*>(this));
43
0
    }
44
0
    mStoredFonts.clear();
45
0
    mStoredSurfaces.clear();
46
0
  }
47
48
0
  void ClearResources() {
49
0
    mStoredObjects.clear();
50
0
    mStoredFontData.clear();
51
0
    mScaledFonts.clear();
52
0
  }
53
54
  template<class S>
55
0
  void WriteHeader(S& aStream) {
56
0
    WriteElement(aStream, kMagicInt);
57
0
    WriteElement(aStream, kMajorRevision);
58
0
    WriteElement(aStream, kMinorRevision);
59
0
  }
Unexecuted instantiation: void mozilla::gfx::DrawEventRecorderPrivate::WriteHeader<std::__1::basic_ofstream<char, std::__1::char_traits<char> > >(std::__1::basic_ofstream<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: void mozilla::gfx::DrawEventRecorderPrivate::WriteHeader<mozilla::gfx::MemStream>(mozilla::gfx::MemStream&)
60
61
  virtual void RecordEvent(const RecordedEvent &aEvent) = 0;
62
  void WritePath(const PathRecording *aPath);
63
64
0
  void AddStoredObject(const ReferencePtr aObject) {
65
0
    mStoredObjects.insert(aObject);
66
0
  }
67
68
0
  void RemoveStoredObject(const ReferencePtr aObject) {
69
0
    mStoredObjects.erase(aObject);
70
0
  }
71
72
0
  void AddScaledFont(ScaledFont* aFont) {
73
0
    if (mStoredFonts.insert(aFont).second &&
74
0
        WantsExternalFonts()) {
75
0
      mScaledFonts.push_back(aFont);
76
0
    }
77
0
  }
78
79
0
  void RemoveScaledFont(ScaledFont* aFont) {
80
0
    mStoredFonts.erase(aFont);
81
0
  }
82
83
0
  void AddSourceSurface(SourceSurface* aSurface) {
84
0
    mStoredSurfaces.insert(aSurface);
85
0
  }
86
87
0
  void RemoveSourceSurface(SourceSurface* aSurface) {
88
0
    mStoredSurfaces.erase(aSurface);
89
0
  }
90
91
0
  bool HasStoredObject(const ReferencePtr aObject) {
92
0
    return mStoredObjects.find(aObject) != mStoredObjects.end();
93
0
  }
94
95
0
  void AddStoredFontData(const uint64_t aFontDataKey) {
96
0
    mStoredFontData.insert(aFontDataKey);
97
0
  }
98
99
0
  bool HasStoredFontData(const uint64_t aFontDataKey) {
100
0
    return mStoredFontData.find(aFontDataKey) != mStoredFontData.end();
101
0
  }
102
103
0
  bool WantsExternalFonts() const { return mExternalFonts; }
104
105
  void TakeExternalSurfaces(std::vector<RefPtr<SourceSurface>>& aSurfaces)
106
  {
107
    aSurfaces = std::move(mExternalSurfaces);
108
  }
109
110
  virtual void StoreSourceSurfaceRecording(SourceSurface *aSurface,
111
                                           const char *aReason);
112
113
protected:
114
  void StoreExternalSurfaceRecording(SourceSurface* aSurface,
115
                                     uint64_t aKey);
116
117
  virtual void Flush() = 0;
118
119
  std::unordered_set<const void*> mStoredObjects;
120
  std::unordered_set<uint64_t> mStoredFontData;
121
  std::unordered_set<ScaledFont*> mStoredFonts;
122
  std::vector<RefPtr<ScaledFont>> mScaledFonts;
123
  std::unordered_set<SourceSurface*> mStoredSurfaces;
124
  std::vector<RefPtr<SourceSurface>> mExternalSurfaces;
125
  bool mExternalFonts;
126
};
127
128
class DrawEventRecorderFile : public DrawEventRecorderPrivate
129
{
130
  using char_type = filesystem::Path::value_type;
131
public:
132
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderFile, override)
133
  explicit DrawEventRecorderFile(const char_type* aFilename);
134
  ~DrawEventRecorderFile();
135
136
  void RecordEvent(const RecordedEvent &aEvent) override;
137
138
  /**
139
   * Returns whether a recording file is currently open.
140
   */
141
  bool IsOpen();
142
143
  /**
144
   * Opens new file with the provided name. The recorder does NOT forget which
145
   * objects it has recorded. This can be used with Close, so that a recording
146
   * can be processed in chunks. The file must not already be open.
147
   */
148
  void OpenNew(const char_type* aFilename);
149
150
  /**
151
   * Closes the file so that it can be processed. The recorder does NOT forget
152
   * which objects it has recorded. This can be used with OpenNew, so that a
153
   * recording can be processed in chunks. The file must be open.
154
   */
155
  void Close();
156
157
private:
158
  void Flush() override;
159
160
  mozilla::OFStream mOutputStream;
161
};
162
163
typedef std::function<void(MemStream &aStream, std::vector<RefPtr<ScaledFont>> &aScaledFonts)> SerializeResourcesFn;
164
165
// WARNING: This should not be used in its existing state because
166
// it is likely to OOM because of large continguous allocations.
167
class DrawEventRecorderMemory : public DrawEventRecorderPrivate
168
{
169
public:
170
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderMemory, override)
171
172
  /**
173
   * Constructs a DrawEventRecorder that stores the recording in memory.
174
   */
175
  DrawEventRecorderMemory();
176
  explicit DrawEventRecorderMemory(const SerializeResourcesFn &aSerialize);
177
178
  void RecordEvent(const RecordedEvent &aEvent) override;
179
180
  /**
181
   * @return the current size of the recording (in chars).
182
   */
183
  size_t RecordingSize();
184
185
  /**
186
   * Wipes the internal recording buffer, but the recorder does NOT forget which
187
   * objects it has recorded. This can be used so that a recording can be copied
188
   * and processed in chunks, releasing memory as it goes.
189
   */
190
  void WipeRecording();
191
  bool Finish() override;
192
  void FlushItem(IntRect) override;
193
194
  MemStream mOutputStream;
195
  /* The index stream is of the form:
196
   * ItemIndex { size_t dataEnd; size_t extraDataEnd; }
197
   * It gets concatenated to the end of mOutputStream in Finish()
198
   * The last size_t in the stream is offset of the begining of the
199
   * index.
200
   */
201
  MemStream mIndex;
202
203
protected:
204
0
  ~DrawEventRecorderMemory() {};
205
206
private:
207
  SerializeResourcesFn mSerializeCallback;
208
209
  void Flush() override;
210
};
211
212
} // namespace gfx
213
} // namespace mozilla
214
215
#endif /* MOZILLA_GFX_DRAWEVENTRECORDER_H_ */