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_AutoProfilerStyleMarker_h
8 #define mozilla_AutoProfilerStyleMarker_h
9 
10 #include "mozilla/Attributes.h"
11 #include "mozilla/ProfilerMarkers.h"
12 #include "mozilla/ServoTraversalStatistics.h"
13 #include "mozilla/TimeStamp.h"
14 
15 namespace mozilla {
16 
17 class MOZ_RAII AutoProfilerStyleMarker {
18  public:
AutoProfilerStyleMarker(UniquePtr<ProfileChunkedBuffer> aCause,const Maybe<uint64_t> & aInnerWindowID)19   explicit AutoProfilerStyleMarker(UniquePtr<ProfileChunkedBuffer> aCause,
20                                    const Maybe<uint64_t>& aInnerWindowID)
21       : mActive(profiler_thread_is_being_profiled_for_markers()),
22         mStartTime(TimeStamp::Now()),
23         mCause(std::move(aCause)),
24         mInnerWindowID(aInnerWindowID) {
25     if (!mActive) {
26       return;
27     }
28     MOZ_ASSERT(!ServoTraversalStatistics::sActive,
29                "Nested AutoProfilerStyleMarker");
30     ServoTraversalStatistics::sSingleton = ServoTraversalStatistics();
31     ServoTraversalStatistics::sActive = true;
32   }
33 
~AutoProfilerStyleMarker()34   ~AutoProfilerStyleMarker() {
35     if (!mActive) {
36       return;
37     }
38 
39     struct StyleMarker {
40       static constexpr mozilla::Span<const char> MarkerTypeName() {
41         return mozilla::MakeStringSpan("Styles");
42       }
43       static void StreamJSONMarkerData(
44           baseprofiler::SpliceableJSONWriter& aWriter,
45           uint32_t aElementsTraversed, uint32_t aElementsStyled,
46           uint32_t aElementsMatched, uint32_t aStylesShared,
47           uint32_t aStylesReused) {
48         aWriter.IntProperty("elementsTraversed", aElementsTraversed);
49         aWriter.IntProperty("elementsStyled", aElementsStyled);
50         aWriter.IntProperty("elementsMatched", aElementsMatched);
51         aWriter.IntProperty("stylesShared", aStylesShared);
52         aWriter.IntProperty("stylesReused", aStylesReused);
53       }
54       static MarkerSchema MarkerTypeDisplay() {
55         using MS = MarkerSchema;
56         MS schema{MS::Location::MarkerChart, MS::Location::MarkerTable,
57                   MS::Location::TimelineOverview};
58         schema.AddKeyLabelFormat("elementsTraversed", "Elements traversed",
59                                  MS::Format::Integer);
60         schema.AddKeyLabelFormat("elementsStyled", "Elements styled",
61                                  MS::Format::Integer);
62         schema.AddKeyLabelFormat("elementsMatched", "Elements matched",
63                                  MS::Format::Integer);
64         schema.AddKeyLabelFormat("stylesShared", "Styles shared",
65                                  MS::Format::Integer);
66         schema.AddKeyLabelFormat("stylesReused", "Styles reused",
67                                  MS::Format::Integer);
68         return schema;
69       }
70     };
71 
72     ServoTraversalStatistics::sActive = false;
73     profiler_add_marker("Styles", geckoprofiler::category::LAYOUT,
74                         {MarkerTiming::IntervalUntilNowFrom(mStartTime),
75                          MarkerStack::TakeBacktrace(std::move(mCause)),
76                          MarkerInnerWindowId(mInnerWindowID)},
77                         StyleMarker{},
78                         ServoTraversalStatistics::sSingleton.mElementsTraversed,
79                         ServoTraversalStatistics::sSingleton.mElementsStyled,
80                         ServoTraversalStatistics::sSingleton.mElementsMatched,
81                         ServoTraversalStatistics::sSingleton.mStylesShared,
82                         ServoTraversalStatistics::sSingleton.mStylesReused);
83   }
84 
85  private:
86   bool mActive;
87   TimeStamp mStartTime;
88   UniquePtr<ProfileChunkedBuffer> mCause;
89   Maybe<uint64_t> mInnerWindowID;
90 };
91 
92 }  // namespace mozilla
93 
94 #endif  // mozilla_AutoProfilerStyleMarker_h
95