Flutter Impeller
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. 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 217 of file surface_mtl.mm.

217  {
218  return IRect::MakeSize(resolve_texture_->GetSize());
219 }

References impeller::TRect< int64_t >::MakeSize().

◆ drawable()

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

Definition at line 56 of file surface_mtl.h.

56 { return drawable_; }

Referenced by MakeFromMetalLayerDrawable(), and MakeFromTexture().

◆ 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 21 of file surface_mtl.mm.

23  {
24  TRACE_EVENT0("impeller", "SurfaceMTL::WrapCurrentMetalLayerDrawable");
25 
26  if (context == nullptr || !context->IsValid() || layer == nil) {
27  return nullptr;
28  }
29 
30  id<CAMetalDrawable> current_drawable = nil;
31  {
32  TRACE_EVENT0("impeller", "WaitForNextDrawable");
33  current_drawable = [layer nextDrawable];
34  }
35 
36  if (!current_drawable) {
37  VALIDATION_LOG << "Could not acquire current drawable.";
38  return nullptr;
39  }
40  return current_drawable;
41 }

References VALIDATION_LOG.

◆ 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 119 of file surface_mtl.mm.

122  {
123  return SurfaceMTL::MakeFromTexture(context, drawable.texture, clip_rect,
124  drawable);
125 }

References drawable(), and MakeFromTexture().

◆ 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 127 of file surface_mtl.mm.

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

References drawable(), impeller::TextureMTL::Wrapper(), and impeller::WrapTextureWithRenderTarget().

Referenced by MakeFromMetalLayerDrawable().

◆ Present()

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

Reimplemented from impeller::Surface.

Definition at line 222 of file surface_mtl.mm.

222  {
223  auto context = context_.lock();
224  if (!context) {
225  return false;
226  }
227 
228  if (requires_blit_) {
229  if (!(source_texture_ && destination_texture_)) {
230  return false;
231  }
232 
233  auto blit_command_buffer = context->CreateCommandBuffer();
234  if (!blit_command_buffer) {
235  return false;
236  }
237  auto blit_pass = blit_command_buffer->CreateBlitPass();
238  if (!clip_rect_.has_value()) {
239  VALIDATION_LOG << "Missing clip rectangle.";
240  return false;
241  }
242  blit_pass->AddCopy(source_texture_, destination_texture_, std::nullopt,
243  clip_rect_->origin);
244  blit_pass->EncodeCommands(context->GetResourceAllocator());
245  if (!blit_command_buffer->SubmitCommands()) {
246  return false;
247  }
248  }
249 
250  if (drawable_) {
251  id<MTLCommandBuffer> command_buffer =
252  ContextMTL::Cast(context.get())
253  ->CreateMTLCommandBuffer("Present Waiter Command Buffer");
254  // If the threads have been merged, or there is a pending frame capture,
255  // then block on cmd buffer scheduling to ensure that the
256  // transaction/capture work correctly.
257  if ([[NSThread currentThread] isMainThread] ||
258  [[MTLCaptureManager sharedCaptureManager] isCapturing]) {
259  TRACE_EVENT0("flutter", "waitUntilScheduled");
260  [command_buffer commit];
261  [command_buffer waitUntilScheduled];
262  [drawable_ present];
263  } else {
264  [command_buffer presentDrawable:drawable_];
265  [command_buffer commit];
266  }
267  }
268 
269  return true;
270 }

References impeller::BackendCast< ContextMTL, Context >::Cast(), impeller::ContextMTL::CreateMTLCommandBuffer(), and VALIDATION_LOG.


The documentation for this class was generated from the following files:
impeller::TSize< int64_t >::Type
int64_t Type
Definition: size.h:19
impeller::WrapTextureWithRenderTarget
static std::optional< RenderTarget > WrapTextureWithRenderTarget(Allocator &allocator, id< MTLTexture > texture, bool requires_blit, std::optional< IRect > clip_rect)
Definition: surface_mtl.mm:43
impeller::SurfaceMTL::MakeFromTexture
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:127
impeller::SurfaceMTL::drawable
id< MTLDrawable > drawable() const
Definition: surface_mtl.h:56
impeller::TextureMTL::Wrapper
static std::shared_ptr< TextureMTL > Wrapper(TextureDescriptor desc, id< MTLTexture > texture, std::function< void()> deletion_proc=nullptr)
Definition: texture_mtl.mm:38
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:60
impeller::TRect< int64_t >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:52
impeller::BackendCast< ContextMTL, Context >::Cast
static ContextMTL & Cast(Context &base)
Definition: backend_cast.h:14
impeller::ContextMTL::CreateMTLCommandBuffer
id< MTLCommandBuffer > CreateMTLCommandBuffer(const std::string &label) const
Definition: context_mtl.mm:370