Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
context_mtl.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_METAL_CONTEXT_MTL_H_
6#define FLUTTER_IMPELLER_RENDERER_BACKEND_METAL_CONTEXT_MTL_H_
7
8#include <Metal/Metal.h>
9
10#include <deque>
11#include <string>
12
15#include "fml/closure.h"
26
27#if TARGET_OS_SIMULATOR
28#define IMPELLER_CA_METAL_LAYER_AVAILABLE API_AVAILABLE(macos(10.11), ios(13.0))
29#else // TARGET_OS_SIMULATOR
30#define IMPELLER_CA_METAL_LAYER_AVAILABLE API_AVAILABLE(macos(10.11), ios(8.0))
31#endif // TARGET_OS_SIMULATOR
32
33namespace impeller {
34
35/// @brief Creates and manages a Metal capture scope that supports frame capture
36/// when using the FlutterMetalLayer backed drawable.
38 public:
39 /// @brief Construct a new capture manager from the provided Metal device.
40 explicit ImpellerMetalCaptureManager(id<MTLDevice> device);
41
43
44 /// Whether or not the Impeller capture scope is active.
45 ///
46 /// This is distinct from whether or not there is a session recording the
47 /// capture. That can be checked with `[[MTLCaptureManager
48 /// sharedCaptureManager] isCapturing].`
49 bool CaptureScopeActive() const;
50
51 /// @brief Begin a new capture scope, no-op if the scope has already started.
52 void StartCapture();
53
54 /// @brief End the current capture scope.
55 void FinishCapture();
56
57 private:
58 id<MTLCaptureScope> current_capture_scope_;
59 bool scope_active_ = false;
60
63};
64
65class ContextMTL final : public Context,
66 public BackendCast<ContextMTL, Context>,
67 public std::enable_shared_from_this<ContextMTL> {
68 public:
69 static std::shared_ptr<ContextMTL> Create(
70 const Flags& flags,
71 const std::vector<std::string>& shader_library_paths,
72 std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch);
73
74 static std::shared_ptr<ContextMTL> Create(
75 const Flags& flags,
76 const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries_data,
77 std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
78 const std::string& label,
79 std::optional<PixelFormat> pixel_format_override = std::nullopt);
80
81 static std::shared_ptr<ContextMTL> Create(
82 const Flags& flags,
83 id<MTLDevice> device,
84 id<MTLCommandQueue> command_queue,
85 const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries_data,
86 std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
87 const std::string& label);
88
89 // |Context|
90 ~ContextMTL() override;
91
92 // |Context|
93 BackendType GetBackendType() const override;
94
95 id<MTLDevice> GetMTLDevice() const;
96
97 // |Context|
98 std::string DescribeGpuModel() const override;
99
100 // |Context|
101 bool IsValid() const override;
102
103 // |Context|
104 std::shared_ptr<Allocator> GetResourceAllocator() const override;
105
106 // |Context|
107 std::shared_ptr<const GpuSubmissionTracker> GetSubmissionTracker()
108 const override;
109
110 // Mutable tracker for command buffer submission bookkeeping.
111 const std::shared_ptr<GpuSubmissionTracker>& GetMutableSubmissionTracker()
112 const;
113
114 // |Context|
115 std::shared_ptr<ShaderLibrary> GetShaderLibrary() const override;
116
117 // |Context|
118 std::shared_ptr<SamplerLibrary> GetSamplerLibrary() const override;
119
120 // |Context|
121 std::shared_ptr<PipelineLibrary> GetPipelineLibrary() const override;
122
123 // |Context|
124 std::shared_ptr<CommandBuffer> CreateCommandBuffer() const override;
125
126 // |Context|
127 std::shared_ptr<CommandQueue> GetCommandQueue() const override;
128
129 // |Context|
130 const std::shared_ptr<const Capabilities>& GetCapabilities() const override;
131
132 // |Context|
134
135 void SetCapabilities(const std::shared_ptr<const Capabilities>& capabilities);
136
137 // |Context|
139
140 // |Context|
141 void Shutdown() override;
142
143 id<MTLCommandBuffer> CreateMTLCommandBuffer(const std::string& label) const;
144
145 std::shared_ptr<const fml::SyncSwitch> GetIsGpuDisabledSyncSwitch() const;
146
147#ifdef IMPELLER_DEBUG
148 std::shared_ptr<GPUTracerMTL> GetGPUTracer() const;
149
150 const std::shared_ptr<ImpellerMetalCaptureManager> GetCaptureManager() const;
151#endif // IMPELLER_DEBUG
152
153 // |Context|
154 void StoreTaskForGPU(const fml::closure& task,
155 const fml::closure& failure) override;
156
157 // visible for testing.
159
160 // |Context|
161 [[nodiscard]] bool FinishQueue() override;
162
163 private:
164 class SyncSwitchObserver : public fml::SyncSwitch::Observer {
165 public:
166 explicit SyncSwitchObserver(ContextMTL& parent);
167 virtual ~SyncSwitchObserver() = default;
168 void OnSyncSwitchUpdate(bool new_value) override;
169
170 private:
171 ContextMTL& parent_;
172 };
173
174 struct PendingTasks {
175 fml::closure task;
176 fml::closure failure;
177 };
178
179 id<MTLDevice> device_ = nullptr;
180 id<MTLCommandQueue> command_queue_ = nullptr;
181 std::shared_ptr<ShaderLibraryMTL> shader_library_;
182 std::shared_ptr<PipelineLibraryMTL> pipeline_library_;
183 std::shared_ptr<SamplerLibrary> sampler_library_;
184 std::shared_ptr<AllocatorMTL> resource_allocator_;
185 std::shared_ptr<const Capabilities> device_capabilities_;
186 std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch_;
187 std::shared_ptr<GpuSubmissionTracker> submission_tracker_ =
188 std::make_shared<GpuSubmissionTracker>();
189 Mutex tasks_awaiting_gpu_mutex_;
190 std::deque<PendingTasks> tasks_awaiting_gpu_
191 IPLR_GUARDED_BY(tasks_awaiting_gpu_mutex_);
192 std::unique_ptr<SyncSwitchObserver> sync_switch_observer_;
193 std::shared_ptr<CommandQueue> command_queue_ip_;
194#ifdef IMPELLER_DEBUG
195 std::shared_ptr<GPUTracerMTL> gpu_tracer_;
196 std::shared_ptr<ImpellerMetalCaptureManager> capture_manager_;
197#endif // IMPELLER_DEBUG
198 bool is_valid_ = false;
199
200 ContextMTL(const Flags& flags,
201 id<MTLDevice> device,
202 id<MTLCommandQueue> command_queue,
203 NSArray<id<MTLLibrary>>* shader_libraries,
204 std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
205 std::optional<PixelFormat> pixel_format_override = std::nullopt);
206
207 std::shared_ptr<CommandBuffer> CreateCommandBufferInQueue(
208 id<MTLCommandQueue> queue) const;
209
210 ContextMTL(const ContextMTL&) = delete;
211
212 ContextMTL& operator=(const ContextMTL&) = delete;
213};
214
215} // namespace impeller
216
217#endif // FLUTTER_IMPELLER_RENDERER_BACKEND_METAL_CONTEXT_MTL_H_
Observes changes to the SyncSwitch.
Definition sync_switch.h:25
To do anything rendering related with Impeller, you need a context.
Definition context.h:70
std::shared_ptr< SamplerLibrary > GetSamplerLibrary() const override
Returns the library of combined image samplers used in shaders.
std::shared_ptr< CommandBuffer > CreateCommandBuffer() const override
Create a new command buffer. Command buffers can be used to encode graphics, blit,...
id< MTLCommandBuffer > CreateMTLCommandBuffer(const std::string &label) const
void SetCapabilities(const std::shared_ptr< const Capabilities > &capabilities)
std::shared_ptr< PipelineLibrary > GetPipelineLibrary() const override
Returns the library of pipelines used by render or compute commands.
std::shared_ptr< CommandQueue > GetCommandQueue() const override
Return the graphics queue for submitting command buffers.
const std::shared_ptr< const Capabilities > & GetCapabilities() const override
Get the capabilities of Impeller context. All optionally supported feature of the platform,...
static std::shared_ptr< ContextMTL > Create(const Flags &flags, const std::vector< std::string > &shader_library_paths, std::shared_ptr< const fml::SyncSwitch > is_gpu_disabled_sync_switch)
std::string DescribeGpuModel() const override
RuntimeStageBackend GetRuntimeStageBackend() const override
Retrieve the runtime stage for this context type.
BackendType GetBackendType() const override
Get the graphics backend of an Impeller context.
bool FinishQueue() override
Wait until all previously submitted command buffers are processed and displayed by the GPU.
std::shared_ptr< const GpuSubmissionTracker > GetSubmissionTracker() const override
Returns the tracker recording GPU completion of command buffer submissions, or nullptr if the backend...
void Shutdown() override
Force all pending asynchronous work to finish. This is achieved by deleting all owned concurrent mess...
void StoreTaskForGPU(const fml::closure &task, const fml::closure &failure) override
std::shared_ptr< ShaderLibrary > GetShaderLibrary() const override
Returns the library of shaders used to specify the programmable stages of a pipeline.
bool UpdateOffscreenLayerPixelFormat(PixelFormat format) override
std::shared_ptr< Allocator > GetResourceAllocator() const override
Returns the allocator used to create textures and buffers on the device.
bool IsValid() const override
Determines if a context is valid. If the caller ever receives an invalid context, they must discard i...
const std::shared_ptr< GpuSubmissionTracker > & GetMutableSubmissionTracker() const
id< MTLDevice > GetMTLDevice() const
std::shared_ptr< const fml::SyncSwitch > GetIsGpuDisabledSyncSwitch() const
Creates and manages a Metal capture scope that supports frame capture when using the FlutterMetalLaye...
Definition context_mtl.h:37
void FinishCapture()
End the current capture scope.
void StartCapture()
Begin a new capture scope, no-op if the scope has already started.
VkDevice device
Definition main.cc:69
VkQueue queue
Definition main.cc:71
uint32_t uint32_t * format
std::function< void()> closure
Definition closure.h:14
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition formats.h:99
#define IPLR_GUARDED_BY(x)