Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
 

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.
 
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 18 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 57 of file surface_mtl.h.

57{ 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)
#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:57
static std::unique_ptr< SurfaceMTL > MakeFromTexture(const std::shared_ptr< Context > &context, id< MTLTexture > texture, std::optional< IRect > clip_rect, id< CAMetalDrawable > drawable=nil)

◆ 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)
FlTexture * texture
static std::optional< RenderTarget > WrapTextureWithRenderTarget(Allocator &allocator, id< MTLTexture > texture, bool requires_blit, std::optional< IRect > clip_rect)

◆ 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 // If the threads have been merged, or there is a pending frame capture,
270 // then block on cmd buffer scheduling to ensure that the
271 // transaction/capture work correctly.
272 if ([[NSThread currentThread] isMainThread] ||
273 [[MTLCaptureManager sharedCaptureManager] isCapturing]) {
274 TRACE_EVENT0("flutter", "waitUntilScheduled");
275 [command_buffer commit];
276 [command_buffer waitUntilScheduled];
277 [drawable_ present];
278 } else {
279 // The drawable may come from a FlutterMetalLayer, so it can't be
280 // presented through the command buffer.
281 id<CAMetalDrawable> drawable = drawable_;
282 [command_buffer addScheduledHandler:^(id<MTLCommandBuffer> buffer) {
283 [drawable present];
284 }];
285 [command_buffer commit];
286 }
287 }
288
289 return true;
290}
static ContextMTL & Cast(Context &base)
id< MTLCommandBuffer > CreateMTLCommandBuffer(const std::string &label) const
static const uint8_t buffer[]

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