Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
13#include "vulkan/vulkan_handles.hpp"
14
15namespace impeller {
16
17class 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" />
26class 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
101class GPUProbe {
102 public:
103 explicit GPUProbe(const std::weak_ptr<GPUTracerVK>& tracer);
104
105 GPUProbe(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_
void RecordCmdBufferStart(const vk::CommandBuffer &buffer)
Record a timestamp query into the provided cmd buffer to record start time.
GPUProbe(GPUProbe &&)=delete
GPUProbe & operator=(GPUProbe &&)=delete
void RecordCmdBufferEnd(const vk::CommandBuffer &buffer)
Record a timestamp query into the provided cmd buffer to record end time.
A class that uses timestamp queries to record the approximate GPU execution time.
void MarkFrameStart()
Signal the start of a frame workload.
void MarkFrameEnd()
Signal the end of a frame workload.
size_t current_state_ IPLR_GUARDED_BY(trace_state_mutex_)=0u
std::unique_ptr< GPUProbe > CreateGPUProbe()
Create a GPUProbe to trace the execution of a command buffer on the GPU.
void InitializeQueryPool(const ContextVK &context)
Initialize the set of query pools.
double frame
Definition examples.cpp:31
static const uint8_t buffer[]
#define IPLR_GUARDED_BY(x)