Flutter Engine
 
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 private:
153 class SyncSwitchObserver : public fml::SyncSwitch::Observer {
154 public:
155 explicit SyncSwitchObserver(ContextMTL& parent);
156 virtual ~SyncSwitchObserver() = default;
157 void OnSyncSwitchUpdate(bool new_value) override;
158
159 private:
160 ContextMTL& parent_;
161 };
162
163 struct PendingTasks {
164 fml::closure task;
165 fml::closure failure;
166 };
167
168 id<MTLDevice> device_ = nullptr;
169 id<MTLCommandQueue> command_queue_ = nullptr;
170 std::shared_ptr<ShaderLibraryMTL> shader_library_;
171 std::shared_ptr<PipelineLibraryMTL> pipeline_library_;
172 std::shared_ptr<SamplerLibrary> sampler_library_;
173 std::shared_ptr<AllocatorMTL> resource_allocator_;
174 std::shared_ptr<const Capabilities> device_capabilities_;
175 std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch_;
176 Mutex tasks_awaiting_gpu_mutex_;
177 std::deque<PendingTasks> tasks_awaiting_gpu_
178 IPLR_GUARDED_BY(tasks_awaiting_gpu_mutex_);
179 std::unique_ptr<SyncSwitchObserver> sync_switch_observer_;
180 std::shared_ptr<CommandQueue> command_queue_ip_;
181#ifdef IMPELLER_DEBUG
182 std::shared_ptr<GPUTracerMTL> gpu_tracer_;
183 std::shared_ptr<ImpellerMetalCaptureManager> capture_manager_;
184#endif // IMPELLER_DEBUG
185 bool is_valid_ = false;
186
187 ContextMTL(const Flags& flags,
188 id<MTLDevice> device,
189 id<MTLCommandQueue> command_queue,
190 NSArray<id<MTLLibrary>>* shader_libraries,
191 std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
192 std::optional<PixelFormat> pixel_format_override = std::nullopt);
193
194 std::shared_ptr<CommandBuffer> CreateCommandBufferInQueue(
195 id<MTLCommandQueue> queue) const;
196
197 ContextMTL(const ContextMTL&) = delete;
198
199 ContextMTL& operator=(const ContextMTL&) = delete;
200};
201
202} // namespace impeller
203
204#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:65
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.
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)