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 /* Tools for collecting and reporting layout and style telemetry */
8 
9 #ifndef mozilla_LayoutTelemetryTools_h
10 #define mozilla_LayoutTelemetryTools_h
11 
12 #include "mozilla/EnumeratedArray.h"
13 #include "mozilla/EnumeratedRange.h"
14 #include "mozilla/FlushType.h"
15 #include "mozilla/Saturate.h"
16 #include "mozilla/TimeStamp.h"
17 
18 #define LAYOUT_TELEMETRY_RECORD(subsystem) \
19   layout_telemetry::AutoRecord a(layout_telemetry::LayoutSubsystem::subsystem)
20 
21 #define LAYOUT_TELEMETRY_RECORD_BASE(subsystem)     \
22   layout_telemetry::AutoRecord a(&mLayoutTelemetry, \
23                                  layout_telemetry::LayoutSubsystem::subsystem)
24 
25 namespace mozilla {
26 namespace layout_telemetry {
27 
28 enum class FlushKind : uint8_t { Style, Layout, Count };
29 
30 enum class LayoutSubsystem : uint8_t {
31   Restyle,
32   Reflow,
33   ReflowFlex,
34   ReflowGrid,
35   ReflowTable,
36   ReflowText,
37   Count
38 };
39 
40 using LayoutSubsystemDurations =
41     EnumeratedArray<LayoutSubsystem, LayoutSubsystem::Count, double>;
42 using LayoutFlushCount =
43     EnumeratedArray<FlushKind, FlushKind::Count, SaturateUint8>;
44 
45 struct Data {
46   Data();
47 
48   void IncReqsPerFlush(FlushType aFlushType);
49   void IncFlushesPerTick(FlushType aFlushType);
50 
51   void PingTelemetry();
52 
53   // Send the current number of flush requests for aFlushType to telemetry and
54   // reset the count.
55   void PingReqsPerFlushTelemetry(FlushType aFlushType);
56 
57   // Send the current non-zero number of style and layout flushes to telemetry
58   // and reset the count.
59   void PingFlushPerTickTelemetry(FlushType aFlushType);
60 
61   // Send the current non-zero time spent under style and layout processing this
62   // tick to telemetry and reset the total.
63   void PingTotalMsPerTickTelemetry(FlushType aFlushType);
64 
65   // Send the current per-tick telemetry for `aFlushType`.
66   void PingPerTickTelemetry(FlushType aFlushType);
67 
68   LayoutFlushCount mReqsPerFlush;
69   LayoutFlushCount mFlushesPerTick;
70   LayoutSubsystemDurations mLayoutSubsystemDurationMs;
71 };
72 
73 class AutoRecord {
74  public:
75   explicit AutoRecord(LayoutSubsystem aSubsystem);
76   AutoRecord(Data* aLayoutTelemetry, LayoutSubsystem aSubsystem);
77   ~AutoRecord();
78 
79  private:
80   AutoRecord* mParentRecord;
81   Data* mLayoutTelemetry;
82   LayoutSubsystem mSubsystem;
83   TimeStamp mStartTime;
84   double mDurationMs;
85 };
86 
87 }  // namespace layout_telemetry
88 }  // namespace mozilla
89 
90 #endif  // !mozilla_LayoutTelemetryTools_h
91