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 ProfilerMarkerPayload_h
8 #define ProfilerMarkerPayload_h
9 
10 #include "mozilla/Attributes.h"
11 #include "mozilla/Maybe.h"
12 #include "mozilla/RefPtr.h"
13 #include "mozilla/TimeStamp.h"
14 #include "mozilla/UniquePtrExtensions.h"
15 
16 #include "nsString.h"
17 #include "GeckoProfiler.h"
18 
19 #include "js/Utility.h"
20 #include "gfxASurface.h"
21 
22 namespace mozilla {
23 namespace layers {
24 class Layer;
25 }  // namespace layers
26 }  // namespace mozilla
27 
28 class SpliceableJSONWriter;
29 class UniqueStacks;
30 
31 // This is an abstract class that can be implemented to supply data to be
32 // attached with a profiler marker.
33 //
34 // When subclassing this, note that the destructor can be called on any thread,
35 // i.e. not necessarily on the thread that created the object.
36 class ProfilerMarkerPayload {
37  public:
38   explicit ProfilerMarkerPayload(UniqueProfilerBacktrace aStack = nullptr)
mStack(Move (aStack))39       : mStack(Move(aStack)) {}
40 
41   ProfilerMarkerPayload(const mozilla::TimeStamp& aStartTime,
42                         const mozilla::TimeStamp& aEndTime,
43                         UniqueProfilerBacktrace aStack = nullptr)
mStartTime(aStartTime)44       : mStartTime(aStartTime), mEndTime(aEndTime), mStack(Move(aStack)) {}
45 
~ProfilerMarkerPayload()46   virtual ~ProfilerMarkerPayload() {}
47 
48   virtual void StreamPayload(SpliceableJSONWriter& aWriter,
49                              const mozilla::TimeStamp& aProcessStartTime,
50                              UniqueStacks& aUniqueStacks) = 0;
51 
GetStartTime()52   mozilla::TimeStamp GetStartTime() const { return mStartTime; }
53 
54  protected:
55   void StreamCommonProps(const char* aMarkerType, SpliceableJSONWriter& aWriter,
56                          const mozilla::TimeStamp& aProcessStartTime,
57                          UniqueStacks& aUniqueStacks);
58 
SetStack(UniqueProfilerBacktrace aStack)59   void SetStack(UniqueProfilerBacktrace aStack) {
60     mStack = mozilla::Move(aStack);
61   }
62 
63  private:
64   mozilla::TimeStamp mStartTime;
65   mozilla::TimeStamp mEndTime;
66   UniqueProfilerBacktrace mStack;
67 };
68 
69 #define DECL_STREAM_PAYLOAD                                               \
70   virtual void StreamPayload(SpliceableJSONWriter& aWriter,               \
71                              const mozilla::TimeStamp& aProcessStartTime, \
72                              UniqueStacks& aUniqueStacks) override;
73 
74 class TracingMarkerPayload : public ProfilerMarkerPayload {
75  public:
76   TracingMarkerPayload(const char* aCategory, TracingKind aKind,
77                        UniqueProfilerBacktrace aCause = nullptr)
mCategory(aCategory)78       : mCategory(aCategory), mKind(aKind) {
79     if (aCause) {
80       SetStack(Move(aCause));
81     }
82   }
83 
84   DECL_STREAM_PAYLOAD
85 
86  private:
87   const char* mCategory;
88   TracingKind mKind;
89 };
90 
91 class IOMarkerPayload : public ProfilerMarkerPayload {
92  public:
IOMarkerPayload(const char * aSource,const char * aFilename,const mozilla::TimeStamp & aStartTime,const mozilla::TimeStamp & aEndTime,UniqueProfilerBacktrace aStack)93   IOMarkerPayload(const char* aSource, const char* aFilename,
94                   const mozilla::TimeStamp& aStartTime,
95                   const mozilla::TimeStamp& aEndTime,
96                   UniqueProfilerBacktrace aStack)
97       : ProfilerMarkerPayload(aStartTime, aEndTime, Move(aStack)),
98         mSource(aSource),
99         mFilename(aFilename ? strdup(aFilename) : nullptr) {
100     MOZ_ASSERT(aSource);
101   }
102 
103   DECL_STREAM_PAYLOAD
104 
105  private:
106   const char* mSource;
107   mozilla::UniqueFreePtr<char> mFilename;
108 };
109 
110 class DOMEventMarkerPayload : public ProfilerMarkerPayload {
111  public:
DOMEventMarkerPayload(const nsAString & aEventType,uint16_t aPhase,const mozilla::TimeStamp & aTimeStamp,const mozilla::TimeStamp & aStartTime,const mozilla::TimeStamp & aEndTime)112   DOMEventMarkerPayload(const nsAString& aEventType, uint16_t aPhase,
113                         const mozilla::TimeStamp& aTimeStamp,
114                         const mozilla::TimeStamp& aStartTime,
115                         const mozilla::TimeStamp& aEndTime)
116       : ProfilerMarkerPayload(aStartTime, aEndTime),
117         mTimeStamp(aTimeStamp),
118         mEventType(aEventType),
119         mPhase(aPhase) {}
120 
121   DECL_STREAM_PAYLOAD
122 
123  private:
124   mozilla::TimeStamp mTimeStamp;
125   nsString mEventType;
126   uint16_t mPhase;
127 };
128 
129 class UserTimingMarkerPayload : public ProfilerMarkerPayload {
130  public:
UserTimingMarkerPayload(const nsAString & aName,const mozilla::TimeStamp & aStartTime)131   UserTimingMarkerPayload(const nsAString& aName,
132                           const mozilla::TimeStamp& aStartTime)
133       : ProfilerMarkerPayload(aStartTime, aStartTime),
134         mEntryType("mark"),
135         mName(aName) {}
136 
UserTimingMarkerPayload(const nsAString & aName,const mozilla::Maybe<nsString> & aStartMark,const mozilla::Maybe<nsString> & aEndMark,const mozilla::TimeStamp & aStartTime,const mozilla::TimeStamp & aEndTime)137   UserTimingMarkerPayload(const nsAString& aName,
138                           const mozilla::Maybe<nsString>& aStartMark,
139                           const mozilla::Maybe<nsString>& aEndMark,
140                           const mozilla::TimeStamp& aStartTime,
141                           const mozilla::TimeStamp& aEndTime)
142       : ProfilerMarkerPayload(aStartTime, aEndTime),
143         mEntryType("measure"),
144         mName(aName),
145         mStartMark(aStartMark),
146         mEndMark(aEndMark) {}
147 
148   DECL_STREAM_PAYLOAD
149 
150  private:
151   // Either "mark" or "measure".
152   const char* mEntryType;
153   nsString mName;
154   mozilla::Maybe<nsString> mStartMark;
155   mozilla::Maybe<nsString> mEndMark;
156 };
157 
158 // Contains the translation applied to a 2d layer so we can track the layer
159 // position at each frame.
160 class LayerTranslationMarkerPayload : public ProfilerMarkerPayload {
161  public:
LayerTranslationMarkerPayload(mozilla::layers::Layer * aLayer,mozilla::gfx::Point aPoint,mozilla::TimeStamp aStartTime)162   LayerTranslationMarkerPayload(mozilla::layers::Layer* aLayer,
163                                 mozilla::gfx::Point aPoint,
164                                 mozilla::TimeStamp aStartTime)
165       : ProfilerMarkerPayload(aStartTime, aStartTime),
166         mLayer(aLayer),
167         mPoint(aPoint) {}
168 
169   DECL_STREAM_PAYLOAD
170 
171  private:
172   mozilla::layers::Layer* mLayer;
173   mozilla::gfx::Point mPoint;
174 };
175 
176 #include "Units.h"  // For ScreenIntPoint
177 
178 // Tracks when a vsync occurs according to the HardwareComposer.
179 class VsyncMarkerPayload : public ProfilerMarkerPayload {
180  public:
VsyncMarkerPayload(mozilla::TimeStamp aVsyncTimestamp)181   explicit VsyncMarkerPayload(mozilla::TimeStamp aVsyncTimestamp)
182       : ProfilerMarkerPayload(aVsyncTimestamp, aVsyncTimestamp),
183         mVsyncTimestamp(aVsyncTimestamp) {}
184 
185   DECL_STREAM_PAYLOAD
186 
187  private:
188   mozilla::TimeStamp mVsyncTimestamp;
189 };
190 
191 class GCSliceMarkerPayload : public ProfilerMarkerPayload {
192  public:
GCSliceMarkerPayload(const mozilla::TimeStamp & aStartTime,const mozilla::TimeStamp & aEndTime,JS::UniqueChars && aTimingJSON)193   GCSliceMarkerPayload(const mozilla::TimeStamp& aStartTime,
194                        const mozilla::TimeStamp& aEndTime,
195                        JS::UniqueChars&& aTimingJSON)
196       : ProfilerMarkerPayload(aStartTime, aEndTime),
197         mTimingJSON(mozilla::Move(aTimingJSON)) {}
198 
199   DECL_STREAM_PAYLOAD
200 
201  private:
202   JS::UniqueChars mTimingJSON;
203 };
204 
205 class GCMajorMarkerPayload : public ProfilerMarkerPayload {
206  public:
GCMajorMarkerPayload(const mozilla::TimeStamp & aStartTime,const mozilla::TimeStamp & aEndTime,JS::UniqueChars && aTimingJSON)207   GCMajorMarkerPayload(const mozilla::TimeStamp& aStartTime,
208                        const mozilla::TimeStamp& aEndTime,
209                        JS::UniqueChars&& aTimingJSON)
210       : ProfilerMarkerPayload(aStartTime, aEndTime),
211         mTimingJSON(mozilla::Move(aTimingJSON)) {}
212 
213   DECL_STREAM_PAYLOAD
214 
215  private:
216   JS::UniqueChars mTimingJSON;
217 };
218 
219 class GCMinorMarkerPayload : public ProfilerMarkerPayload {
220  public:
GCMinorMarkerPayload(const mozilla::TimeStamp & aStartTime,const mozilla::TimeStamp & aEndTime,JS::UniqueChars && aTimingData)221   GCMinorMarkerPayload(const mozilla::TimeStamp& aStartTime,
222                        const mozilla::TimeStamp& aEndTime,
223                        JS::UniqueChars&& aTimingData)
224       : ProfilerMarkerPayload(aStartTime, aEndTime),
225         mTimingData(mozilla::Move(aTimingData)) {}
226 
227   DECL_STREAM_PAYLOAD
228 
229  private:
230   JS::UniqueChars mTimingData;
231 };
232 
233 class HangMarkerPayload : public ProfilerMarkerPayload {
234  public:
HangMarkerPayload(const mozilla::TimeStamp & aStartTime,const mozilla::TimeStamp & aEndTime)235   HangMarkerPayload(const mozilla::TimeStamp& aStartTime,
236                     const mozilla::TimeStamp& aEndTime)
237       : ProfilerMarkerPayload(aStartTime, aEndTime) {}
238 
239   DECL_STREAM_PAYLOAD
240  private:
241 };
242 
243 #endif  // ProfilerMarkerPayload_h
244