xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/FrameTracer/FrameTracer.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2019 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #pragma once
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <perfetto/trace/android/graphics_frame_event.pbzero.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <perfetto/tracing.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <ui/FenceTime.h>
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker #include <mutex>
24*38e8c45fSAndroid Build Coastguard Worker #include <unordered_map>
25*38e8c45fSAndroid Build Coastguard Worker 
26*38e8c45fSAndroid Build Coastguard Worker namespace android {
27*38e8c45fSAndroid Build Coastguard Worker 
28*38e8c45fSAndroid Build Coastguard Worker class FrameTracer {
29*38e8c45fSAndroid Build Coastguard Worker public:
30*38e8c45fSAndroid Build Coastguard Worker     class FrameTracerDataSource : public perfetto::DataSource<FrameTracerDataSource> {
OnSetup(const SetupArgs &)31*38e8c45fSAndroid Build Coastguard Worker         virtual void OnSetup(const SetupArgs&) override{};
OnStart(const StartArgs &)32*38e8c45fSAndroid Build Coastguard Worker         virtual void OnStart(const StartArgs&) override{};
OnStop(const StopArgs &)33*38e8c45fSAndroid Build Coastguard Worker         virtual void OnStop(const StopArgs&) override{};
34*38e8c45fSAndroid Build Coastguard Worker     };
35*38e8c45fSAndroid Build Coastguard Worker 
36*38e8c45fSAndroid Build Coastguard Worker     static const uint64_t UNSPECIFIED_FRAME_NUMBER = std::numeric_limits<uint64_t>::max();
37*38e8c45fSAndroid Build Coastguard Worker 
38*38e8c45fSAndroid Build Coastguard Worker     using FrameEvent = perfetto::protos::pbzero::GraphicsFrameEvent;
39*38e8c45fSAndroid Build Coastguard Worker 
40*38e8c45fSAndroid Build Coastguard Worker     ~FrameTracer() = default;
41*38e8c45fSAndroid Build Coastguard Worker 
42*38e8c45fSAndroid Build Coastguard Worker     // Sets up the perfetto tracing backend and data source.
43*38e8c45fSAndroid Build Coastguard Worker     void initialize();
44*38e8c45fSAndroid Build Coastguard Worker     // Registers the data source with the perfetto backend. Called as part of initialize()
45*38e8c45fSAndroid Build Coastguard Worker     // and should not be called manually outside of tests. Public to allow for substituting a
46*38e8c45fSAndroid Build Coastguard Worker     // perfetto::kInProcessBackend in tests.
47*38e8c45fSAndroid Build Coastguard Worker     void registerDataSource();
48*38e8c45fSAndroid Build Coastguard Worker     // Starts tracking a new layer for tracing. Needs to be called once before traceTimestamp() or
49*38e8c45fSAndroid Build Coastguard Worker     // traceFence() for each layer.
50*38e8c45fSAndroid Build Coastguard Worker     void traceNewLayer(int32_t layerId, const std::string& layerName);
51*38e8c45fSAndroid Build Coastguard Worker     // Creates a trace point at the timestamp provided.
52*38e8c45fSAndroid Build Coastguard Worker     void traceTimestamp(int32_t layerId, uint64_t bufferID, uint64_t frameNumber, nsecs_t timestamp,
53*38e8c45fSAndroid Build Coastguard Worker                         FrameEvent::BufferEventType type, nsecs_t duration = 0);
54*38e8c45fSAndroid Build Coastguard Worker     // Creates a trace point after the provided fence has been signalled. If a startTime is provided
55*38e8c45fSAndroid Build Coastguard Worker     // the trace will have be timestamped from startTime until fence signalling time. If no
56*38e8c45fSAndroid Build Coastguard Worker     // startTime is provided, a durationless trace point will be created timestamped at fence
57*38e8c45fSAndroid Build Coastguard Worker     // signalling time. If the fence hasn't signalled yet, the trace point will be created the next
58*38e8c45fSAndroid Build Coastguard Worker     // time after signalling a trace call for this buffer occurs.
59*38e8c45fSAndroid Build Coastguard Worker     void traceFence(int32_t layerId, uint64_t bufferID, uint64_t frameNumber,
60*38e8c45fSAndroid Build Coastguard Worker                     const std::shared_ptr<FenceTime>& fence, FrameEvent::BufferEventType type,
61*38e8c45fSAndroid Build Coastguard Worker                     nsecs_t startTime = 0);
62*38e8c45fSAndroid Build Coastguard Worker 
63*38e8c45fSAndroid Build Coastguard Worker     // Takes care of cleanup when a layer is destroyed.
64*38e8c45fSAndroid Build Coastguard Worker     void onDestroy(int32_t layerId);
65*38e8c45fSAndroid Build Coastguard Worker 
66*38e8c45fSAndroid Build Coastguard Worker     std::string miniDump();
67*38e8c45fSAndroid Build Coastguard Worker 
68*38e8c45fSAndroid Build Coastguard Worker     static constexpr char kFrameTracerDataSource[] = "android.surfaceflinger.frame";
69*38e8c45fSAndroid Build Coastguard Worker 
70*38e8c45fSAndroid Build Coastguard Worker     // The maximum amount of time a fence has to signal before it is discarded.
71*38e8c45fSAndroid Build Coastguard Worker     // Used to avoid fences from previous traces generating new trace points in later ones.
72*38e8c45fSAndroid Build Coastguard Worker     // Public for testing.
73*38e8c45fSAndroid Build Coastguard Worker     static constexpr nsecs_t kFenceSignallingDeadline = 60'000'000'000; // 60 seconds
74*38e8c45fSAndroid Build Coastguard Worker 
75*38e8c45fSAndroid Build Coastguard Worker private:
76*38e8c45fSAndroid Build Coastguard Worker     struct PendingFence {
77*38e8c45fSAndroid Build Coastguard Worker         uint64_t frameNumber;
78*38e8c45fSAndroid Build Coastguard Worker         FrameEvent::BufferEventType type;
79*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<FenceTime> fence;
80*38e8c45fSAndroid Build Coastguard Worker         nsecs_t startTime;
81*38e8c45fSAndroid Build Coastguard Worker     };
82*38e8c45fSAndroid Build Coastguard Worker 
83*38e8c45fSAndroid Build Coastguard Worker     struct TraceRecord {
84*38e8c45fSAndroid Build Coastguard Worker         std::string layerName;
85*38e8c45fSAndroid Build Coastguard Worker         using BufferID = uint64_t;
86*38e8c45fSAndroid Build Coastguard Worker         std::unordered_map<BufferID, std::vector<PendingFence>> pendingFences;
87*38e8c45fSAndroid Build Coastguard Worker     };
88*38e8c45fSAndroid Build Coastguard Worker 
89*38e8c45fSAndroid Build Coastguard Worker     // Checks if any pending fences for a layer and buffer have signalled and, if they have, creates
90*38e8c45fSAndroid Build Coastguard Worker     // trace points for them.
91*38e8c45fSAndroid Build Coastguard Worker     void tracePendingFencesLocked(FrameTracerDataSource::TraceContext& ctx, int32_t layerId,
92*38e8c45fSAndroid Build Coastguard Worker                                   uint64_t bufferID);
93*38e8c45fSAndroid Build Coastguard Worker     // Creates a trace point by translating a start time and an end time to a timestamp and
94*38e8c45fSAndroid Build Coastguard Worker     // duration. If startTime is later than end time it sets end time as the timestamp and the
95*38e8c45fSAndroid Build Coastguard Worker     // duration to 0. Used by traceFence().
96*38e8c45fSAndroid Build Coastguard Worker     void traceSpanLocked(FrameTracerDataSource::TraceContext& ctx, int32_t layerId,
97*38e8c45fSAndroid Build Coastguard Worker                          uint64_t bufferID, uint64_t frameNumber, FrameEvent::BufferEventType type,
98*38e8c45fSAndroid Build Coastguard Worker                          nsecs_t startTime, nsecs_t endTime);
99*38e8c45fSAndroid Build Coastguard Worker     void traceLocked(FrameTracerDataSource::TraceContext& ctx, int32_t layerId, uint64_t bufferID,
100*38e8c45fSAndroid Build Coastguard Worker                      uint64_t frameNumber, nsecs_t timestamp, FrameEvent::BufferEventType type,
101*38e8c45fSAndroid Build Coastguard Worker                      nsecs_t duration = 0);
102*38e8c45fSAndroid Build Coastguard Worker 
103*38e8c45fSAndroid Build Coastguard Worker     std::mutex mTraceMutex;
104*38e8c45fSAndroid Build Coastguard Worker     std::unordered_map<int32_t, TraceRecord> mTraceTracker;
105*38e8c45fSAndroid Build Coastguard Worker     std::once_flag mInitializationFlag;
106*38e8c45fSAndroid Build Coastguard Worker };
107*38e8c45fSAndroid Build Coastguard Worker 
108*38e8c45fSAndroid Build Coastguard Worker } // namespace android
109