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_layers_CheckerboardEvent_h 8 #define mozilla_layers_CheckerboardEvent_h 9 10 #include "mozilla/DefineEnum.h" 11 #include "mozilla/Monitor.h" 12 #include "mozilla/TimeStamp.h" 13 #include <sstream> 14 #include "Units.h" 15 #include <vector> 16 17 namespace mozilla { 18 namespace layers { 19 20 /** 21 * This class records information relevant to one "checkerboard event", which is 22 * a contiguous set of frames where a given APZC was checkerboarding. The intent 23 * of this class is to record enough information that it can provide actionable 24 * steps to reduce the occurrence of checkerboarding. Furthermore, it records 25 * information about the severity of the checkerboarding so as to allow 26 * prioritizing the debugging of some checkerboarding events over others. 27 */ 28 class CheckerboardEvent final { 29 public: 30 // clang-format off 31 MOZ_DEFINE_ENUM_AT_CLASS_SCOPE( 32 RendertraceProperty, ( 33 Page, 34 PaintedCriticalDisplayPort, 35 PaintedDisplayPort, 36 RequestedDisplayPort, 37 UserVisible 38 )); 39 // clang-format on 40 41 static const char* sDescriptions[sRendertracePropertyCount]; 42 static const char* sColors[sRendertracePropertyCount]; 43 44 public: 45 explicit CheckerboardEvent(bool aRecordTrace); 46 47 /** 48 * Gets the "severity" of the checkerboard event. This doesn't have units, 49 * it's just useful for comparing two checkerboard events to see which one 50 * is worse, for some implementation-specific definition of "worse". 51 */ 52 uint32_t GetSeverity(); 53 54 /** 55 * Gets the number of CSS pixels that were checkerboarded at the peak of the 56 * checkerboard event. 57 */ 58 uint32_t GetPeak(); 59 60 /** 61 * Gets the length of the checkerboard event. 62 */ 63 TimeDuration GetDuration(); 64 65 /** 66 * Gets the raw log of the checkerboard event. This can be called any time, 67 * although it really only makes sense to pull once the event is done, after 68 * RecordFrameInfo returns true. 69 */ 70 std::string GetLog(); 71 72 /** 73 * Returns true iff this event is recording a detailed trace of the event. 74 * This is the argument passed in to the constructor. 75 */ 76 bool IsRecordingTrace(); 77 78 /** 79 * Provide a new value for one of the rects that is tracked for 80 * checkerboard events. 81 */ 82 void UpdateRendertraceProperty(RendertraceProperty aProperty, 83 const CSSRect& aRect, 84 const std::string& aExtraInfo = std::string()); 85 86 /** 87 * Provide the number of CSS pixels that are checkerboarded in a composite 88 * at the current time. 89 * @return true if the checkerboard event has completed. The caller should 90 * stop updating this object once this happens. 91 */ 92 bool RecordFrameInfo(uint32_t aCssPixelsCheckerboarded); 93 94 private: 95 /** 96 * Helper method to do stuff when checkeboarding starts. 97 */ 98 void StartEvent(); 99 /** 100 * Helper method to do stuff when checkerboarding stops. 101 */ 102 void StopEvent(); 103 104 /** 105 * Helper method to log a rendertrace property and its value to the 106 * rendertrace info buffer (mRendertraceInfo). 107 */ 108 void LogInfo(RendertraceProperty aProperty, const TimeStamp& aTimestamp, 109 const CSSRect& aRect, const std::string& aExtraInfo, 110 const MonitorAutoLock& aProofOfLock); 111 112 /** 113 * Helper struct that holds a single rendertrace property value. 114 */ 115 struct PropertyValue { 116 RendertraceProperty mProperty; 117 TimeStamp mTimeStamp; 118 CSSRect mRect; 119 std::string mExtraInfo; 120 121 bool operator<(const PropertyValue& aOther) const; 122 }; 123 124 /** 125 * A circular buffer that stores the most recent BUFFER_SIZE values of a 126 * given property. 127 */ 128 class PropertyBuffer { 129 public: 130 PropertyBuffer(); 131 /** 132 * Add a new value to the buffer, overwriting the oldest one if needed. 133 */ 134 void Update(RendertraceProperty aProperty, const CSSRect& aRect, 135 const std::string& aExtraInfo, 136 const MonitorAutoLock& aProofOfLock); 137 /** 138 * Dump the recorded values, oldest to newest, to the given vector, and 139 * remove them from this buffer. 140 */ 141 void Flush(std::vector<PropertyValue>& aOut, 142 const MonitorAutoLock& aProofOfLock); 143 144 private: 145 static const uint32_t BUFFER_SIZE = 5; 146 147 /** 148 * The index of the oldest value in the buffer. This is the next index 149 * that will be written to. 150 */ 151 uint32_t mIndex; 152 PropertyValue mValues[BUFFER_SIZE]; 153 }; 154 155 private: 156 /** 157 * If true, we should log the various properties during the checkerboard 158 * event. If false, we only need to record things we need for telemetry 159 * measures. 160 */ 161 const bool mRecordTrace; 162 /** 163 * A base time so that the other timestamps can be turned into durations. 164 */ 165 const TimeStamp mOriginTime; 166 /** 167 * Whether or not a checkerboard event is currently occurring. 168 */ 169 bool mCheckerboardingActive; 170 171 /** 172 * The start time of the checkerboard event. 173 */ 174 TimeStamp mStartTime; 175 /** 176 * The end time of the checkerboard event. 177 */ 178 TimeStamp mEndTime; 179 /** 180 * The sample time of the last frame recorded. 181 */ 182 TimeStamp mLastSampleTime; 183 /** 184 * The number of contiguous frames with checkerboard. 185 */ 186 uint32_t mFrameCount; 187 /** 188 * The total number of pixel-milliseconds of checkerboarding visible to 189 * the user during the checkerboarding event. 190 */ 191 uint64_t mTotalPixelMs; 192 /** 193 * The largest number of pixels of checkerboarding visible to the user 194 * during any one frame, during this checkerboarding event. 195 */ 196 uint32_t mPeakPixels; 197 198 /** 199 * Monitor that needs to be acquired before touching mBufferedProperties 200 * or mRendertraceInfo. 201 */ 202 mutable Monitor mRendertraceLock; 203 /** 204 * A circular buffer to store some properties. This is used before the 205 * checkerboarding actually starts, so that we have some data on what 206 * was happening before the checkerboarding started. 207 */ 208 PropertyBuffer mBufferedProperties[sRendertracePropertyCount]; 209 /** 210 * The rendertrace info buffer that gives us info on what was happening 211 * during the checkerboard event. 212 */ 213 std::ostringstream mRendertraceInfo; 214 }; 215 216 } // namespace layers 217 } // namespace mozilla 218 219 #endif // mozilla_layers_CheckerboardEvent_h 220