1 /* 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 26 namespace android { 27 28 class FrameTracer { 29 public: 30 class FrameTracerDataSource : public perfetto::DataSource<FrameTracerDataSource> { OnSetup(const SetupArgs &)31 virtual void OnSetup(const SetupArgs&) override{}; OnStart(const StartArgs &)32 virtual void OnStart(const StartArgs&) override{}; OnStop(const StopArgs &)33 virtual void OnStop(const StopArgs&) override{}; 34 }; 35 36 static const uint64_t UNSPECIFIED_FRAME_NUMBER = std::numeric_limits<uint64_t>::max(); 37 38 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 75 private: 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; 105 std::once_flag mInitializationFlag; 106 }; 107 108 } // namespace android 109