7#include "flutter/fml/trace_event.h"
8#include "flutter/impeller/renderer/command_buffer.h"
17- (void)flutterPrepareForPresent:(nonnull
id<MTLCommandBuffer>)commandBuffer;
22#pragma GCC diagnostic push
23#pragma GCC diagnostic ignored "-Wunguarded-availability-new"
26 const std::shared_ptr<Context>& context,
27 CAMetalLayer* layer) {
28 TRACE_EVENT0(
"impeller",
"SurfaceMTL::WrapCurrentMetalLayerDrawable");
30 if (context ==
nullptr || !context->IsValid() || layer == nil) {
34 id<CAMetalDrawable> current_drawable = nil;
37 current_drawable = [layer nextDrawable];
40 if (!current_drawable) {
44 return current_drawable;
51 std::optional<IRect> clip_rect) {
57 if (!clip_rect.has_value()) {
61 root_size =
ISize(clip_rect->GetWidth(), clip_rect->GetHeight());
69 resolve_tex_desc.
size = root_size;
70 resolve_tex_desc.
usage =
81 std::shared_ptr<Texture> resolve_tex;
93 resolve_tex->SetLabel(
"ImpellerOnscreenResolve");
99 msaa_tex_desc.
format = resolve_tex->GetTextureDescriptor().format;
100 msaa_tex_desc.
size = resolve_tex->GetSize();
108 msaa_tex->SetLabel(
"ImpellerOnscreenColorMSAA");
117 auto render_target_desc = std::make_optional<RenderTarget>();
118 render_target_desc->SetColorAttachment(color0, 0u);
120 return render_target_desc;
124 const std::shared_ptr<Context>& context,
125 id<CAMetalDrawable> drawable,
126 std::optional<IRect> clip_rect) {
132 const std::shared_ptr<Context>& context,
134 std::optional<IRect> clip_rect,
135 id<CAMetalDrawable> drawable) {
136 bool partial_repaint_blit_required = ShouldPerformPartialRepaint(clip_rect);
143 partial_repaint_blit_required, clip_rect);
144 if (!render_target) {
151 auto source_texture = partial_repaint_blit_required
152 ? render_target->GetRenderTargetTexture()
157 std::shared_ptr<Texture> destination_texture;
158 if (partial_repaint_blit_required) {
162 auto destination_descriptor =
163 render_target->GetRenderTargetTexture()->GetTextureDescriptor();
170 destination_texture = render_target->GetRenderTargetTexture();
173 return std::unique_ptr<SurfaceMTL>(
new SurfaceMTL(
176 render_target->GetRenderTargetTexture(),
180 partial_repaint_blit_required,
185SurfaceMTL::SurfaceMTL(
const std::weak_ptr<Context>& context,
187 std::shared_ptr<Texture> resolve_texture,
188 id<CAMetalDrawable> drawable,
189 std::shared_ptr<Texture> source_texture,
190 std::shared_ptr<Texture> destination_texture,
192 std::optional<IRect> clip_rect)
195 resolve_texture_(
std::move(resolve_texture)),
197 source_texture_(
std::move(source_texture)),
198 destination_texture_(
std::move(destination_texture)),
199 requires_blit_(requires_blit),
200 clip_rect_(clip_rect) {}
205bool SurfaceMTL::ShouldPerformPartialRepaint(std::optional<IRect> damage_rect) {
209 if (!damage_rect.has_value()) {
214 if (damage_rect->IsEmpty()) {
227 auto context = context_.lock();
232 if (requires_blit_) {
233 if (!(source_texture_ && destination_texture_)) {
237 auto blit_command_buffer = context->CreateCommandBuffer();
238 if (!blit_command_buffer) {
241 auto blit_pass = blit_command_buffer->CreateBlitPass();
242 if (!clip_rect_.has_value()) {
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()) {
258 id<MTLCommandBuffer> command_buffer =
262 id<CAMetalDrawable> metal_drawable =
263 reinterpret_cast<id<CAMetalDrawable>
>(drawable_);
266 flutterPrepareForPresent:command_buffer];
273#if defined(FML_OS_IOS_SIMULATOR) && defined(FML_ARCH_CPU_X86_64)
274 constexpr bool alwaysWaitForScheduling =
true;
276 constexpr bool alwaysWaitForScheduling =
false;
282 if ([[NSThread currentThread] isMainThread] ||
283 [[MTLCaptureManager sharedCaptureManager] isCapturing] ||
284 alwaysWaitForScheduling) {
286 [command_buffer commit];
287#if defined(FML_OS_IOS_SIMULATOR) && defined(FML_ARCH_CPU_X86_64)
288 [command_buffer waitUntilCompleted];
290 [command_buffer waitUntilScheduled];
296 id<CAMetalDrawable>
drawable = drawable_;
297 [command_buffer addScheduledHandler:^(id<MTLCommandBuffer> buffer) {
300 [command_buffer commit];
306#pragma GCC diagnostic pop
An object that allocates device memory.
std::shared_ptr< Texture > CreateTexture(const TextureDescriptor &desc)
static ContextMTL & Cast(Context &base)
id< MTLCommandBuffer > CreateMTLCommandBuffer(const std::string &label) const
bool Present() const override
id< MTLDrawable > drawable() const
static std::unique_ptr< SurfaceMTL > MakeFromTexture(const std::shared_ptr< Context > &context, id< MTLTexture > texture, std::optional< IRect > clip_rect, id< CAMetalDrawable > drawable=nil)
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....
static std::unique_ptr< SurfaceMTL > MakeFromMetalLayerDrawable(const std::shared_ptr< Context > &context, id< CAMetalDrawable > drawable, std::optional< IRect > clip_rect=std::nullopt)
static std::shared_ptr< TextureMTL > Wrapper(TextureDescriptor desc, id< MTLTexture > texture, std::function< void()> deletion_proc=nullptr)
static std::shared_ptr< TextureMTL > Create(TextureDescriptor desc, id< MTLTexture > texture)
constexpr PixelFormat FromMTLPixelFormat(MTLPixelFormat format)
static std::optional< RenderTarget > WrapTextureWithRenderTarget(Allocator &allocator, id< MTLTexture > texture, bool requires_blit, std::optional< IRect > clip_rect)
std::shared_ptr< Texture > resolve_texture
std::shared_ptr< Texture > texture
static constexpr Color DarkSlateGray()
static constexpr TRect MakeSize(const TSize< U > &size)
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
CompressionType compression_type
#define TRACE_EVENT0(category_group, name)