blob: d4dfab94ebf564b80b347fb0157e7ffe0ade5d36 [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
36 using FrameEvent = perfetto::protos::pbzero::GraphicsFrameEvent;
37
38 ~FrameTracer() = default;
39
40 // Sets up the perfetto tracing backend and data source.
41 void initialize();
42 // Registers the data source with the perfetto backend. Called as part of initialize()
43 // and should not be called manually outside of tests. Public to allow for substituting a
44 // perfetto::kInProcessBackend in tests.
45 void registerDataSource();
46 // Starts tracking a new layer for tracing. Needs to be called once before traceTimestamp() or
47 // traceFence() for each layer.
48 void traceNewLayer(int32_t layerID, const std::string& layerName);
49 // Creates a trace point at the timestamp provided.
50 void traceTimestamp(int32_t layerID, uint64_t bufferID, uint64_t frameNumber, nsecs_t timestamp,
51 FrameEvent::BufferEventType type, nsecs_t duration = 0);
52 // Creates a trace point after the provided fence has been signalled. If a startTime is provided
53 // the trace will have be timestamped from startTime until fence signalling time. If no
54 // startTime is provided, a durationless trace point will be created timestamped at fence
55 // signalling time. If the fence hasn't signalled yet, the trace point will be created the next
56 // time after signalling a trace call for this buffer occurs.
57 void traceFence(int32_t layerID, uint64_t bufferID, uint64_t frameNumber,
58 const std::shared_ptr<FenceTime>& fence, FrameEvent::BufferEventType type,
59 nsecs_t startTime = 0);
60
61 // Takes care of cleanup when a layer is destroyed.
62 void onDestroy(int32_t layerID);
63
64 std::string miniDump();
65
66 static constexpr char kFrameTracerDataSource[] = "android.surfaceflinger.frame";
67
68 // The maximum amount of time a fence has to signal before it is discarded.
69 // Used to avoid fences from previous traces generating new trace points in later ones.
70 // Public for testing.
71 static constexpr nsecs_t kFenceSignallingDeadline = 60'000'000'000; // 60 seconds
72
73private:
74 struct PendingFence {
75 uint64_t frameNumber;
76 FrameEvent::BufferEventType type;
77 std::shared_ptr<FenceTime> fence;
78 nsecs_t startTime;
79 };
80
81 struct TraceRecord {
82 std::string layerName;
83 using BufferID = uint64_t;
84 std::unordered_map<BufferID, std::vector<PendingFence>> pendingFences;
85 };
86
87 // Checks if any pending fences for a layer and buffer have signalled and, if they have, creates
88 // trace points for them.
89 void tracePendingFencesLocked(FrameTracerDataSource::TraceContext& ctx, int32_t layerID,
90 uint64_t bufferID);
91 // Creates a trace point by translating a start time and an end time to a timestamp and
92 // duration. If startTime is later than end time it sets end time as the timestamp and the
93 // duration to 0. Used by traceFence().
94 void traceSpanLocked(FrameTracerDataSource::TraceContext& ctx, int32_t layerID,
95 uint64_t bufferID, uint64_t frameNumber, FrameEvent::BufferEventType type,
96 nsecs_t startTime, nsecs_t endTime);
97 void traceLocked(FrameTracerDataSource::TraceContext& ctx, int32_t layerID, uint64_t bufferID,
98 uint64_t frameNumber, nsecs_t timestamp, FrameEvent::BufferEventType type,
99 nsecs_t duration = 0);
100
101 std::mutex mTraceMutex;
102 std::unordered_map<int32_t, TraceRecord> mTraceTracker;
Raymond Chiu27b53722019-09-03 17:55:10 -0700103 std::once_flag mInitializationFlag;
Mikael Pessa90092f42019-08-26 17:22:04 -0700104};
105
106} // namespace android