summaryrefslogtreecommitdiffstats
path: root/gfx/layers/apz/src/CheckerboardEvent.h
blob: ad7fa83b2bd75c6726f11255f982254b9485045c (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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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_layers_CheckerboardEvent_h
#define mozilla_layers_CheckerboardEvent_h

#include "mozilla/DefineEnum.h"
#include "mozilla/Monitor.h"
#include "mozilla/TimeStamp.h"
#include <sstream>
#include "Units.h"
#include <vector>

namespace mozilla {
namespace layers {

/**
 * This class records information relevant to one "checkerboard event", which is
 * a contiguous set of frames where a given APZC was checkerboarding. The intent
 * of this class is to record enough information that it can provide actionable
 * steps to reduce the occurrence of checkerboarding. Furthermore, it records
 * information about the severity of the checkerboarding so as to allow
 * prioritizing the debugging of some checkerboarding events over others.
 */
class CheckerboardEvent final {
 public:
  // clang-format off
  MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
    RendertraceProperty, (
      Page,
      PaintedDisplayPort,
      RequestedDisplayPort,
      UserVisible
  ));
  // clang-format on

  static const char* sDescriptions[sRendertracePropertyCount];
  static const char* sColors[sRendertracePropertyCount];

 public:
  explicit CheckerboardEvent(bool aRecordTrace);

  /**
   * Gets the "severity" of the checkerboard event. This doesn't have units,
   * it's just useful for comparing two checkerboard events to see which one
   * is worse, for some implementation-specific definition of "worse".
   */
  uint32_t GetSeverity();

  /**
   * Gets the number of CSS pixels that were checkerboarded at the peak of the
   * checkerboard event.
   */
  uint32_t GetPeak();

  /**
   * Gets the length of the checkerboard event.
   */
  TimeDuration GetDuration();

  /**
   * Gets the raw log of the checkerboard event. This can be called any time,
   * although it really only makes sense to pull once the event is done, after
   * RecordFrameInfo returns true.
   */
  std::string GetLog();

  /**
   * Returns true iff this event is recording a detailed trace of the event.
   * This is the argument passed in to the constructor.
   */
  bool IsRecordingTrace();

  /**
   * Provide a new value for one of the rects that is tracked for
   * checkerboard events.
   */
  void UpdateRendertraceProperty(RendertraceProperty aProperty,
                                 const CSSRect& aRect,
                                 const std::string& aExtraInfo = std::string());

  /**
   * Provide the number of CSS pixels that are checkerboarded in a composite
   * at the current time.
   * @return true if the checkerboard event has completed. The caller should
   * stop updating this object once this happens.
   */
  bool RecordFrameInfo(uint32_t aCssPixelsCheckerboarded);

 private:
  /**
   * Helper method to do stuff when checkeboarding starts.
   */
  void StartEvent();
  /**
   * Helper method to do stuff when checkerboarding stops.
   */
  void StopEvent();

  /**
   * Helper method to log a rendertrace property and its value to the
   * rendertrace info buffer (mRendertraceInfo).
   */
  void LogInfo(RendertraceProperty aProperty, const TimeStamp& aTimestamp,
               const CSSRect& aRect, const std::string& aExtraInfo,
               const MonitorAutoLock& aProofOfLock);

  /**
   * Helper struct that holds a single rendertrace property value.
   */
  struct PropertyValue {
    RendertraceProperty mProperty;
    TimeStamp mTimeStamp;
    CSSRect mRect;
    std::string mExtraInfo;

    bool operator<(const PropertyValue& aOther) const;
  };

  /**
   * A circular buffer that stores the most recent BUFFER_SIZE values of a
   * given property.
   */
  class PropertyBuffer {
   public:
    PropertyBuffer();
    /**
     * Add a new value to the buffer, overwriting the oldest one if needed.
     */
    void Update(RendertraceProperty aProperty, const CSSRect& aRect,
                const std::string& aExtraInfo,
                const MonitorAutoLock& aProofOfLock);
    /**
     * Dump the recorded values, oldest to newest, to the given vector, and
     * remove them from this buffer.
     */
    void Flush(std::vector<PropertyValue>& aOut,
               const MonitorAutoLock& aProofOfLock);

   private:
    static const uint32_t BUFFER_SIZE = 5;

    /**
     * The index of the oldest value in the buffer. This is the next index
     * that will be written to.
     */
    uint32_t mIndex;
    PropertyValue mValues[BUFFER_SIZE];
  };

 private:
  /**
   * If true, we should log the various properties during the checkerboard
   * event. If false, we only need to record things we need for telemetry
   * measures.
   */
  const bool mRecordTrace;
  /**
   * A base time so that the other timestamps can be turned into durations.
   */
  const TimeStamp mOriginTime;
  /**
   * Whether or not a checkerboard event is currently occurring.
   */
  bool mCheckerboardingActive;

  /**
   * The start time of the checkerboard event.
   */
  TimeStamp mStartTime;
  /**
   * The end time of the checkerboard event.
   */
  TimeStamp mEndTime;
  /**
   * The sample time of the last frame recorded.
   */
  TimeStamp mLastSampleTime;
  /**
   * The number of contiguous frames with checkerboard.
   */
  uint32_t mFrameCount;
  /**
   * The total number of pixel-milliseconds of checkerboarding visible to
   * the user during the checkerboarding event.
   */
  uint64_t mTotalPixelMs;
  /**
   * The largest number of pixels of checkerboarding visible to the user
   * during any one frame, during this checkerboarding event.
   */
  uint32_t mPeakPixels;

  /**
   * Monitor that needs to be acquired before touching mBufferedProperties
   * or mRendertraceInfo.
   */
  mutable Monitor mRendertraceLock MOZ_UNANNOTATED;
  /**
   * A circular buffer to store some properties. This is used before the
   * checkerboarding actually starts, so that we have some data on what
   * was happening before the checkerboarding started.
   */
  PropertyBuffer mBufferedProperties[sRendertracePropertyCount];
  /**
   * The rendertrace info buffer that gives us info on what was happening
   * during the checkerboard event.
   */
  std::ostringstream mRendertraceInfo;
};

}  // namespace layers
}  // namespace mozilla

#endif  // mozilla_layers_CheckerboardEvent_h