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