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<ShaderLibrary> GetShaderLibrary() const override;
108
109 // |Context|
110 std::shared_ptr<SamplerLibrary> GetSamplerLibrary() const override;
111
112 // |Context|
113 std::shared_ptr<PipelineLibrary> GetPipelineLibrary() const override;
114
115 // |Context|
116 std::shared_ptr<CommandBuffer> CreateCommandBuffer() const override;
117
118 // |Context|
119 std::shared_ptr<CommandQueue> GetCommandQueue() const override;
120
121 // |Context|
122 const std::shared_ptr<const Capabilities>& GetCapabilities() const override;
123
124 // |Context|
126
127 void SetCapabilities(const std::shared_ptr<const Capabilities>& capabilities);
128
129 // |Context|
131
132 // |Context|
133 void Shutdown() override;
134
135 id<MTLCommandBuffer> CreateMTLCommandBuffer(const std::string& label) const;
136
137 std::shared_ptr<const fml::SyncSwitch> GetIsGpuDisabledSyncSwitch() const;
138
139#ifdef IMPELLER_DEBUG
140 std::shared_ptr<GPUTracerMTL> GetGPUTracer() const;
141
142 const std::shared_ptr<ImpellerMetalCaptureManager> GetCaptureManager() const;
143#endif // IMPELLER_DEBUG
144
145 // |Context|
146 void StoreTaskForGPU(const fml::closure& task,
147 const fml::closure& failure) override;
148
149 // visible for testing.
151
152 // |Context|
153 [[nodiscard]] bool FinishQueue() override;
154
155 private:
156 class SyncSwitchObserver : public fml::SyncSwitch::Observer {
157 public:
158 explicit SyncSwitchObserver(ContextMTL& parent);
159 virtual ~SyncSwitchObserver() = default;
160 void OnSyncSwitchUpdate(bool new_value) override;
161
162 private:
163 ContextMTL& parent_;
164 };
165
166 struct PendingTasks {
167 fml::closure task;
168 fml::closure failure;
169 };
170
171 id<MTLDevice> device_ = nullptr;
172 id<MTLCommandQueue> command_queue_ = nullptr;
173 std::shared_ptr<ShaderLibraryMTL> shader_library_;
174 std::shared_ptr<PipelineLibraryMTL> pipeline_library_;
175 std::shared_ptr<SamplerLibrary> sampler_library_;
176 std::shared_ptr<AllocatorMTL> resource_allocator_;
177 std::shared_ptr<const Capabilities> device_capabilities_;
178 std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch_;
179 Mutex tasks_awaiting_gpu_mutex_;
180 std::deque<PendingTasks> tasks_awaiting_gpu_
181 IPLR_GUARDED_BY(tasks_awaiting_gpu_mutex_);
182 std::unique_ptr<SyncSwitchObserver> sync_switch_observer_;
183 std::shared_ptr<CommandQueue> command_queue_ip_;
184#ifdef IMPELLER_DEBUG
185 std::shared_ptr<GPUTracerMTL> gpu_tracer_;
186 std::shared_ptr<ImpellerMetalCaptureManager> capture_manager_;
187#endif // IMPELLER_DEBUG
188 bool is_valid_ = false;
189
190 ContextMTL(const Flags& flags,
191 id<MTLDevice> device,
192 id<MTLCommandQueue> command_queue,
193 NSArray<id<MTLLibrary>>* shader_libraries,
194 std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
195 std::optional<PixelFormat> pixel_format_override = std::nullopt);
196
197 std::shared_ptr<CommandBuffer> CreateCommandBufferInQueue(
198 id<MTLCommandQueue> queue) const;
199
200 ContextMTL(const ContextMTL&) = delete;
201
202 ContextMTL& operator=(const ContextMTL&) = delete;
203};
204
205} // namespace impeller
206
207#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:69
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.
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...
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)