Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | List of all members
impeller::SurfaceMTL Class Referencefinal

#include <surface_mtl.h>

Inheritance diagram for impeller::SurfaceMTL:
impeller::Surface

Public Member Functions

 ~SurfaceMTL () override
 
id< MTLDrawable > drawable () const
 
IRect coverage () const
 
bool Present () const override
 
- Public Member Functions inherited from impeller::Surface
 Surface ()
 
 Surface (const RenderTarget &target_desc)
 
virtual ~Surface ()
 
const ISizeGetSize () const
 
bool IsValid () const
 
const RenderTargetGetTargetRenderPassDescriptor () const
 
virtual bool Present () const
 

Static Public Member Functions

static id< CAMetalDrawable > GetMetalDrawableAndValidate (const std::shared_ptr< Context > &context, CAMetalLayer *layer)
 Wraps the current drawable of the given Metal layer to create a surface Impeller can render to. The surface must be created as late as possible and discarded immediately after rendering to it. More...
 
static std::unique_ptr< SurfaceMTLMakeFromMetalLayerDrawable (const std::shared_ptr< Context > &context, id< CAMetalDrawable > drawable, std::optional< IRect > clip_rect=std::nullopt)
 
static std::unique_ptr< SurfaceMTLMakeFromTexture (const std::shared_ptr< Context > &context, id< MTLTexture > texture, std::optional< IRect > clip_rect, id< CAMetalDrawable > drawable=nil)
 

Detailed Description

Definition at line 17 of file surface_mtl.h.

Constructor & Destructor Documentation

◆ ~SurfaceMTL()

impeller::SurfaceMTL::~SurfaceMTL ( )
overridedefault

Member Function Documentation

◆ coverage()

IRect impeller::SurfaceMTL::coverage ( ) const

Definition at line 221 of file surface_mtl.mm.

221 {
222 return IRect::MakeSize(resolve_texture_->GetSize());
223}
static constexpr TRect MakeSize(const TSize< U > &size)
Definition: rect.h:146

◆ drawable()

id< MTLDrawable > impeller::SurfaceMTL::drawable ( ) const
inline

Definition at line 56 of file surface_mtl.h.

56{ return drawable_; }

◆ GetMetalDrawableAndValidate()

id< CAMetalDrawable > impeller::SurfaceMTL::GetMetalDrawableAndValidate ( const std::shared_ptr< Context > &  context,
CAMetalLayer *  layer 
)
static

Wraps the current drawable of the given Metal layer to create a surface Impeller can render to. The surface must be created as late as possible and discarded immediately after rendering to it.

Parameters
[in]contextThe context
[in]layerThe layer whose current drawable to wrap to create a surface.
Returns
A pointer to the wrapped surface or null.

Definition at line 25 of file surface_mtl.mm.

27 {
28 TRACE_EVENT0("impeller", "SurfaceMTL::WrapCurrentMetalLayerDrawable");
29
30 if (context == nullptr || !context->IsValid() || layer == nil) {
31 return nullptr;
32 }
33
34 id<CAMetalDrawable> current_drawable = nil;
35 {
36 TRACE_EVENT0("impeller", "WaitForNextDrawable");
37 current_drawable = [layer nextDrawable];
38 }
39
40 if (!current_drawable) {
41 VALIDATION_LOG << "Could not acquire current drawable.";
42 return nullptr;
43 }
44 return current_drawable;
45}
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:131
#define VALIDATION_LOG
Definition: validation.h:73

◆ MakeFromMetalLayerDrawable()

std::unique_ptr< SurfaceMTL > impeller::SurfaceMTL::MakeFromMetalLayerDrawable ( const std::shared_ptr< Context > &  context,
id< CAMetalDrawable >  drawable,
std::optional< IRect clip_rect = std::nullopt 
)
static

Definition at line 123 of file surface_mtl.mm.

126 {
127 return SurfaceMTL::MakeFromTexture(context, drawable.texture, clip_rect,
128 drawable);
129}
id< MTLDrawable > drawable() const
Definition: surface_mtl.h:56
static std::unique_ptr< SurfaceMTL > MakeFromTexture(const std::shared_ptr< Context > &context, id< MTLTexture > texture, std::optional< IRect > clip_rect, id< CAMetalDrawable > drawable=nil)
Definition: surface_mtl.mm:131

◆ MakeFromTexture()

std::unique_ptr< SurfaceMTL > impeller::SurfaceMTL::MakeFromTexture ( const std::shared_ptr< Context > &  context,
id< MTLTexture >  texture,
std::optional< IRect clip_rect,
id< CAMetalDrawable >  drawable = nil 
)
static

Definition at line 131 of file surface_mtl.mm.

135 {
136 bool partial_repaint_blit_required = ShouldPerformPartialRepaint(clip_rect);
137
138 // The returned render target is the texture that Impeller will render the
139 // root pass to. If partial repaint is in use, this may be a new texture which
140 // is smaller than the given MTLTexture.
141 auto render_target =
142 WrapTextureWithRenderTarget(*context->GetResourceAllocator(), texture,
143 partial_repaint_blit_required, clip_rect);
144 if (!render_target) {
145 return nullptr;
146 }
147
148 // If partial repainting, set a "source" texture. The presence of a source
149 // texture and clip rect instructs the surface to blit this texture to the
150 // destination texture.
151 auto source_texture = partial_repaint_blit_required
152 ? render_target->GetRenderTargetTexture()
153 : nullptr;
154
155 // The final "destination" texture is the texture that will be presented. In
156 // this case, it's always the given drawable.
157 std::shared_ptr<Texture> destination_texture;
158 if (partial_repaint_blit_required) {
159 // If blitting for partial repaint, we need to wrap the drawable. Simply
160 // reuse the texture descriptor that was already formed for the new render
161 // target, but override the size with the drawable's size.
162 auto destination_descriptor =
163 render_target->GetRenderTargetTexture()->GetTextureDescriptor();
164 destination_descriptor.size = {static_cast<ISize::Type>(texture.width),
165 static_cast<ISize::Type>(texture.height)};
166 destination_texture = TextureMTL::Wrapper(destination_descriptor, texture);
167 } else {
168 // When not partial repaint blit is needed, the render target texture _is_
169 // the drawable texture.
170 destination_texture = render_target->GetRenderTargetTexture();
171 }
172
173 return std::unique_ptr<SurfaceMTL>(new SurfaceMTL(
174 context, // context
175 *render_target, // target
176 render_target->GetRenderTargetTexture(), // resolve_texture
177 drawable, // drawable
178 source_texture, // source_texture
179 destination_texture, // destination_texture
180 partial_repaint_blit_required, // requires_blit
181 clip_rect // clip_rect
182 ));
183}
static std::shared_ptr< TextureMTL > Wrapper(TextureDescriptor desc, id< MTLTexture > texture, std::function< void()> deletion_proc=nullptr)
Definition: texture_mtl.mm:40
FlTexture * texture
static std::optional< RenderTarget > WrapTextureWithRenderTarget(Allocator &allocator, id< MTLTexture > texture, bool requires_blit, std::optional< IRect > clip_rect)
Definition: surface_mtl.mm:47

◆ Present()

bool impeller::SurfaceMTL::Present ( ) const
overridevirtual

Reimplemented from impeller::Surface.

Definition at line 226 of file surface_mtl.mm.

226 {
227 auto context = context_.lock();
228 if (!context) {
229 return false;
230 }
231
232 if (requires_blit_) {
233 if (!(source_texture_ && destination_texture_)) {
234 return false;
235 }
236
237 auto blit_command_buffer = context->CreateCommandBuffer();
238 if (!blit_command_buffer) {
239 return false;
240 }
241 auto blit_pass = blit_command_buffer->CreateBlitPass();
242 if (!clip_rect_.has_value()) {
243 VALIDATION_LOG << "Missing clip rectangle.";
244 return false;
245 }
246 blit_pass->AddCopy(source_texture_, destination_texture_, std::nullopt,
247 clip_rect_->GetOrigin());
248 blit_pass->EncodeCommands(context->GetResourceAllocator());
249 if (!context->GetCommandQueue()->Submit({blit_command_buffer}).ok()) {
250 return false;
251 }
252 }
253#ifdef IMPELLER_DEBUG
254 ContextMTL::Cast(context.get())->GetGPUTracer()->MarkFrameEnd();
255#endif // IMPELLER_DEBUG
256
257 if (drawable_) {
258 id<MTLCommandBuffer> command_buffer =
259 ContextMTL::Cast(context.get())
260 ->CreateMTLCommandBuffer("Present Waiter Command Buffer");
261
262 id<CAMetalDrawable> metal_drawable =
263 reinterpret_cast<id<CAMetalDrawable>>(drawable_);
264 if ([metal_drawable conformsToProtocol:@protocol(FlutterMetalDrawable)]) {
265 [(id<FlutterMetalDrawable>)metal_drawable
266 flutterPrepareForPresent:command_buffer];
267 }
268
269 // Intel iOS simulators do not seem to give backpressure on Metal drawable
270 // aquisition, which can result in Impeller running head of the GPU
271 // workload by dozens of frames. Slow this process down by blocking
272 // on submit until the last command buffer is at least scheduled.
273#if defined(FML_OS_IOS_SIMULATOR) && defined(FML_ARCH_CPU_X86_64)
274 constexpr bool alwaysWaitForScheduling = true;
275#else
276 constexpr bool alwaysWaitForScheduling = false;
277#endif // defined(FML_OS_IOS_SIMULATOR) && defined(FML_ARCH_CPU_X86_64)
278
279 // If the threads have been merged, or there is a pending frame capture,
280 // then block on cmd buffer scheduling to ensure that the
281 // transaction/capture work correctly.
282 if ([[NSThread currentThread] isMainThread] ||
283 [[MTLCaptureManager sharedCaptureManager] isCapturing] ||
284 alwaysWaitForScheduling) {
285 TRACE_EVENT0("flutter", "waitUntilScheduled");
286 [command_buffer commit];
287#if defined(FML_OS_IOS_SIMULATOR) && defined(FML_ARCH_CPU_X86_64)
288 [command_buffer waitUntilCompleted];
289#else
290 [command_buffer waitUntilScheduled];
291#endif // defined(FML_OS_IOS_SIMULATOR) && defined(FML_ARCH_CPU_X86_64)
292 [drawable_ present];
293 } else {
294 // The drawable may come from a FlutterMetalLayer, so it can't be
295 // presented through the command buffer.
296 id<CAMetalDrawable> drawable = drawable_;
297 [command_buffer addScheduledHandler:^(id<MTLCommandBuffer> buffer) {
298 [drawable present];
299 }];
300 [command_buffer commit];
301 }
302 }
303
304 return true;
305}
static ContextMTL & Cast(Context &base)
Definition: backend_cast.h:13
id< MTLCommandBuffer > CreateMTLCommandBuffer(const std::string &label) const
Definition: context_mtl.mm:369
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126

The documentation for this class was generated from the following files: