summaryrefslogtreecommitdiff
path: root/gfx/2d/DrawEventRecorder.h
blob: a789379d29da92da8e2d8c5c27544a973e40a692 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef MOZILLA_GFX_DRAWEVENTRECORDER_H_
#define MOZILLA_GFX_DRAWEVENTRECORDER_H_

#include "2D.h"
#include "RecordedEvent.h"
#include <ostream>
#include <fstream>

#if defined(_MSC_VER)
#include <unordered_set>
#else
#include <set>
#endif

namespace mozilla {
namespace gfx {

class PathRecording;

class DrawEventRecorderPrivate : public DrawEventRecorder
{
public:
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderPrivate)
  explicit DrawEventRecorderPrivate(std::ostream *aStream);
  virtual ~DrawEventRecorderPrivate() { }

  void WriteHeader();

  void RecordEvent(const RecordedEvent &aEvent);
  void WritePath(const PathRecording *aPath);

  void AddStoredObject(const ReferencePtr aObject) {
    mStoredObjects.insert(aObject);
  }

  void RemoveStoredObject(const ReferencePtr aObject) {
    mStoredObjects.erase(aObject);
  }

  bool HasStoredObject(const ReferencePtr aObject) {
    return mStoredObjects.find(aObject) != mStoredObjects.end();
  }

  void AddStoredFontData(const uint64_t aFontDataKey) {
    mStoredFontData.insert(aFontDataKey);
  }

  bool HasStoredFontData(const uint64_t aFontDataKey) {
    return mStoredFontData.find(aFontDataKey) != mStoredFontData.end();
  }

protected:
  std::ostream *mOutputStream;

  virtual void Flush() = 0;

#if defined(_MSC_VER)
  typedef std::unordered_set<const void*> ObjectSet;
  typedef std::unordered_set<uint64_t> Uint64Set;
#else
  typedef std::set<const void*> ObjectSet;
  typedef std::set<uint64_t> Uint64Set;
#endif

  ObjectSet mStoredObjects;
  Uint64Set mStoredFontData;
};

class DrawEventRecorderFile : public DrawEventRecorderPrivate
{
public:
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderFile)
  explicit DrawEventRecorderFile(const char *aFilename);
  ~DrawEventRecorderFile();

  /**
   * Returns whether a recording file is currently open.
   */
  bool IsOpen();

  /**
   * Opens new file with the provided name. The recorder does NOT forget which
   * objects it has recorded. This can be used with Close, so that a recording
   * can be processed in chunks. The file must not already be open.
   */
  void OpenNew(const char *aFilename);

  /**
   * Closes the file so that it can be processed. The recorder does NOT forget
   * which objects it has recorded. This can be used with OpenNew, so that a
   * recording can be processed in chunks. The file must be open.
   */
  void Close();

private:
  virtual void Flush();

  std::ofstream mOutputFile;
};

class DrawEventRecorderMemory final : public DrawEventRecorderPrivate
{
public:
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderMemory)

  /**
   * Constructs a DrawEventRecorder that stores the recording in memory.
   */
  DrawEventRecorderMemory();

  /**
   * @return the current size of the recording (in chars).
   */
  size_t RecordingSize();

  /**
   * Copies at most aBufferLen chars of the recording into aBuffer.
   *
   * @param aBuffer buffer to receive the recording chars
   * @param aBufferLen length of aBuffer
   * @return true if copied successfully
   */
  bool CopyRecording(char* aBuffer, size_t aBufferLen);

  /**
   * Wipes the internal recording buffer, but the recorder does NOT forget which
   * objects it has recorded. This can be used so that a recording can be copied
   * and processed in chunks, releasing memory as it goes.
   */
  void WipeRecording();

private:
  ~DrawEventRecorderMemory() {};

  void Flush() final;

  std::stringstream mMemoryStream;
};

} // namespace gfx
} // namespace mozilla

#endif /* MOZILLA_GFX_DRAWEVENTRECORDER_H_ */