1 /* 2 * Copyright 2020 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/tracing.h> 20 21 #include <mutex> 22 23 namespace perfetto::protos { 24 class TracePacket; 25 } 26 27 namespace android { 28 29 class GpuMem; 30 31 class GpuMemTracer { 32 public: 33 class GpuMemDataSource : public perfetto::DataSource<GpuMemDataSource> { OnSetup(const SetupArgs &)34 virtual void OnSetup(const SetupArgs&) override{}; OnStart(const StartArgs &)35 virtual void OnStart(const StartArgs&) override { 36 std::unique_lock<std::mutex> lock(GpuMemTracer::sTraceMutex); 37 sTraceStarted = true; 38 sCondition.notify_all(); 39 } OnStop(const StopArgs &)40 virtual void OnStop(const StopArgs&) override{}; 41 }; 42 43 ~GpuMemTracer() = default; 44 45 // Sets up the perfetto tracing backend and data source. 46 void initialize(std::shared_ptr<GpuMem>); 47 // Registers the data source with the perfetto backend. Called as part of initialize() 48 // and should not be called manually outside of tests. Public to allow for substituting a 49 // perfetto::kInProcessBackend in tests. 50 void registerDataSource(); 51 52 // TODO(b/175904796): Refactor gpuservice lib to include perfetto lib and move the test 53 // functions into the unittests. 54 // Functions only used for testing with in-process backend. These functions require the static 55 // perfetto lib to be linked. If the tests have a perfetto linked, while libgpumemtracer.so also 56 // has one linked, they will both use different static states maintained in perfetto. Since the 57 // static perfetto states are not shared, tracing sessions created in the unit test are not 58 // recognized by GpuMemTracer. As a result, we cannot use any of the perfetto functions from 59 // this class, which defeats the purpose of the unit test. To solve this, we restrict all 60 // tracing functionality to this class, while the unit test validates the data. 61 // Sets up the perfetto in-process backend and calls into registerDataSource. 62 void initializeForTest(std::shared_ptr<GpuMem>); 63 // Creates a tracing session with in process backend, for testing. 64 std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest(); 65 // Read and filter the gpu memory packets from the created trace. 66 std::vector<perfetto::protos::TracePacket> readGpuMemTotalPacketsForTestBlocking( 67 perfetto::TracingSession* tracingSession); 68 69 static constexpr char kGpuMemDataSource[] = "android.gpu.memory"; 70 static std::condition_variable sCondition; 71 static std::mutex sTraceMutex; 72 static bool sTraceStarted; 73 74 private: 75 // Friend class for testing 76 friend class GpuMemTracerTest; 77 78 void threadLoop(bool infiniteLoop); 79 void traceInitialCounters(); 80 std::shared_ptr<GpuMem> mGpuMem; 81 // Count of how many tracer threads are currently active. Useful for testing. 82 std::atomic<int32_t> tracerThreadCount = 0; 83 }; 84 85 } // namespace android 86