| Flutter Impeller |

gpu_tracer_vk.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_GPU_TRACER_VK_H_
6 #define FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_GPU_TRACER_VK_H_
7
8 #include <memory>
9 #include <thread>
10
11 #include "impeller/renderer/backend/vulkan/context_vk.h"
12 #include "impeller/renderer/backend/vulkan/device_holder_vk.h"
13 #include "vulkan/vulkan_handles.hpp"
14
15 namespace impeller {
16
17 class GPUProbe;
18
19 /// @brief A class that uses timestamp queries to record the approximate GPU
20 /// execution time.
21 ///
22 /// To enable, add the following metadata to the application's Android manifest:
23 /// <meta-data
24 /// android:name="io.flutter.embedding.android.EnableVulkanGPUTracing"
25 /// android:value="false" />
26 class GPUTracerVK : public std::enable_shared_from_this<GPUTracerVK> {
27 public:
28 GPUTracerVK(std::weak_ptr<ContextVK> context, bool enable_gpu_tracing);
29
30 ~GPUTracerVK() = default;
31
32 /// @brief Create a GPUProbe to trace the execution of a command buffer on the
33 /// GPU.
34 std::unique_ptr<GPUProbe> CreateGPUProbe();
35
36 /// @brief Signal the start of a frame workload.
37 ///
38 /// Any cmd buffers that are created after this call and before
39 /// [MarkFrameEnd] will be attributed to the current frame.
40 void MarkFrameStart();
41
42 /// @brief Signal the end of a frame workload.
43 void MarkFrameEnd();
44
45 // visible for testing.
46 bool IsEnabled() const;
47
48 /// Initialize the set of query pools.
49 void InitializeQueryPool(const ContextVK& context);
50
51 private:
52 friend class GPUProbe;
53
54 static const constexpr size_t kTraceStatesSize = 16u;
55
56 /// @brief Signal that the cmd buffer is completed.
57 ///
58 /// If [frame_index] is std::nullopt, this frame recording is ignored.
59 void OnFenceComplete(size_t frame);
60
61 /// @brief Record a timestamp query into the provided cmd buffer to record
62 /// start time.
63 void RecordCmdBufferStart(const vk::CommandBuffer& buffer, GPUProbe& probe);
64
65 /// @brief Record a timestamp query into the provided cmd buffer to record end
66 /// time.
67 void RecordCmdBufferEnd(const vk::CommandBuffer& buffer, GPUProbe& probe);
68
69 std::weak_ptr<ContextVK> context_;
70
71 struct GPUTraceState {
72 size_t current_index = 0;
73 size_t pending_buffers = 0;
74 vk::UniqueQueryPool query_pool;
75 };
76
77 mutable Mutex trace_state_mutex_;
78 GPUTraceState trace_states_[kTraceStatesSize] IPLR_GUARDED_BY(
79 trace_state_mutex_);
80 size_t current_state_ IPLR_GUARDED_BY(trace_state_mutex_) = 0u;
81 std::vector<size_t> IPLR_GUARDED_BY(trace_state_mutex_) states_to_reset_ = {};
82
83 // The number of nanoseconds for each timestamp unit.
84 float timestamp_period_ = 1;
85
86 // If in_frame_ is not true, then this cmd buffer was started as a part of
87 // some non-frame workload like image decoding. We should not record this as
88 // part of the frame workload, as the gap between this non-frame and a
89 // frameworkload may be substantial. For example, support the engine creates a
90 // cmd buffer to perform an image upload at timestamp 0 and then 30 ms later
91 // actually renders a frame. Without the in_frame_ guard, the GPU frame time
92 // would include this 30ms gap during which the engine was idle.
93 bool in_frame_ = false;
94
95 // Track the raster thread id to avoid recording mipmap/image cmd buffers
96 // that are not guaranteed to start/end according to frame boundaries.
97 std::thread::id raster_thread_id_;
98 bool enabled_ = false;
99 };
100
101 class GPUProbe {
102 public:
103 explicit GPUProbe(const std::weak_ptr<GPUTracerVK>& tracer);
104
105 GPUProbe(GPUProbe&&) = delete;
106 GPUProbe& operator=(GPUProbe&&) = delete;
107
108 ~GPUProbe();
109
110 /// @brief Record a timestamp query into the provided cmd buffer to record
111 /// start time.
112 void RecordCmdBufferStart(const vk::CommandBuffer& buffer);
113
114 /// @brief Record a timestamp query into the provided cmd buffer to record end
115 /// time.
116 void RecordCmdBufferEnd(const vk::CommandBuffer& buffer);
117
118 private:
119 friend class GPUTracerVK;
120
121 std::weak_ptr<GPUTracerVK> tracer_;
122 std::optional<size_t> index_ = std::nullopt;
123 };
124
125 } // namespace impeller
126
127 #endif // FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_GPU_TRACER_VK_H_
impeller::ContextVK
Definition: context_vk.h:66
impeller::GPUProbe
Definition: gpu_tracer_vk.h:101
impeller::GPUProbe::operator=
GPUProbe & operator=(GPUProbe &&)=delete
impeller::GPUProbe::RecordCmdBufferStart
void RecordCmdBufferStart(const vk::CommandBuffer &buffer)
Record a timestamp query into the provided cmd buffer to record start time.
Definition: gpu_tracer_vk.cc:233
impeller::GPUProbe::GPUProbe
GPUProbe(GPUProbe &&)=delete
impeller::GPUProbe::GPUProbe
GPUProbe(const std::weak_ptr< GPUTracerVK > &tracer)
Definition: gpu_tracer_vk.cc:219
impeller::GPUProbe::~GPUProbe
~GPUProbe()
Definition: gpu_tracer_vk.cc:222
impeller::GPUProbe::RecordCmdBufferEnd
void RecordCmdBufferEnd(const vk::CommandBuffer &buffer)
Record a timestamp query into the provided cmd buffer to record end time.
Definition: gpu_tracer_vk.cc:241
impeller::GPUTracerVK
A class that uses timestamp queries to record the approximate GPU execution time.
Definition: gpu_tracer_vk.h:26
impeller::GPUTracerVK::MarkFrameStart
void MarkFrameStart()
Signal the start of a frame workload.
Definition: gpu_tracer_vk.cc:75
impeller::GPUTracerVK::MarkFrameEnd
void MarkFrameEnd()
Signal the end of a frame workload.
Definition: gpu_tracer_vk.cc:84
impeller::GPUTracerVK::CreateGPUProbe
std::unique_ptr< GPUProbe > CreateGPUProbe()
Create a GPUProbe to trace the execution of a command buffer on the GPU.
Definition: gpu_tracer_vk.cc:105
impeller::GPUTracerVK::InitializeQueryPool
void InitializeQueryPool(const ContextVK &context)
Initialize the set of query pools.
Definition: gpu_tracer_vk.cc:43
impeller::GPUTracerVK::~GPUTracerVK
~GPUTracerVK()=default
impeller::GPUTracerVK::GPUTracerVK
GPUTracerVK(std::weak_ptr< ContextVK > context, bool enable_gpu_tracing)
Definition: gpu_tracer_vk.cc:22
impeller::GPUTracerVK::IsEnabled
bool IsEnabled() const
Definition: gpu_tracer_vk.cc:71
device_holder_vk.h
impeller
Definition: allocation.cc:12
context_vk.h