7 #include "flutter/fml/trace_event.h"
18 #pragma GCC diagnostic push
19 #pragma GCC diagnostic ignored "-Wunguarded-availability-new"
22 const std::shared_ptr<Context>& context,
23 CAMetalLayer* layer) {
24 TRACE_EVENT0(
"impeller",
"SurfaceMTL::WrapCurrentMetalLayerDrawable");
26 if (context ==
nullptr || !context->IsValid() || layer == nil) {
30 id<CAMetalDrawable> current_drawable = nil;
32 TRACE_EVENT0(
"impeller",
"WaitForNextDrawable");
33 current_drawable = [layer nextDrawable];
36 if (!current_drawable) {
40 return current_drawable;
45 id<MTLTexture> texture,
47 std::optional<IRect> clip_rect) {
53 if (!clip_rect.has_value()) {
57 root_size =
ISize(clip_rect->size.width, clip_rect->size.height);
59 root_size = {
static_cast<ISize::Type>(texture.width),
65 resolve_tex_desc.
size = root_size;
77 std::shared_ptr<Texture> resolve_tex;
82 resolve_tex = std::make_shared<TextureMTL>(resolve_tex_desc, texture);
89 resolve_tex->SetLabel(
"ImpellerOnscreenResolve");
95 msaa_tex_desc.
format = resolve_tex->GetTextureDescriptor().format;
96 msaa_tex_desc.
size = resolve_tex->GetSize();
104 msaa_tex->SetLabel(
"ImpellerOnscreenColorMSAA");
113 auto render_target_desc = std::make_optional<RenderTarget>();
114 render_target_desc->SetColorAttachment(color0, 0u);
116 return render_target_desc;
120 const std::shared_ptr<Context>& context,
121 id<CAMetalDrawable> drawable,
122 std::optional<IRect> clip_rect) {
128 const std::shared_ptr<Context>& context,
129 id<MTLTexture> texture,
130 std::optional<IRect> clip_rect,
131 id<CAMetalDrawable> drawable) {
132 bool partial_repaint_blit_required = ShouldPerformPartialRepaint(clip_rect);
139 partial_repaint_blit_required, clip_rect);
140 if (!render_target) {
147 auto source_texture = partial_repaint_blit_required
148 ? render_target->GetRenderTargetTexture()
153 std::shared_ptr<Texture> destination_texture;
154 if (partial_repaint_blit_required) {
158 auto destination_descriptor =
159 render_target->GetRenderTargetTexture()->GetTextureDescriptor();
160 destination_descriptor.size = {
static_cast<ISize::Type>(texture.width),
166 destination_texture = render_target->GetRenderTargetTexture();
169 return std::unique_ptr<SurfaceMTL>(
new SurfaceMTL(
172 render_target->GetRenderTargetTexture(),
176 partial_repaint_blit_required,
181 SurfaceMTL::SurfaceMTL(
const std::weak_ptr<Context>& context,
183 std::shared_ptr<Texture> resolve_texture,
184 id<CAMetalDrawable> drawable,
185 std::shared_ptr<Texture> source_texture,
186 std::shared_ptr<Texture> destination_texture,
188 std::optional<IRect> clip_rect)
191 resolve_texture_(
std::move(resolve_texture)),
193 source_texture_(
std::move(source_texture)),
194 destination_texture_(
std::move(destination_texture)),
195 requires_blit_(requires_blit),
196 clip_rect_(clip_rect) {}
201 bool SurfaceMTL::ShouldPerformPartialRepaint(std::optional<IRect> damage_rect) {
205 if (!damage_rect.has_value()) {
210 if (damage_rect->size.width <= 0 || damage_rect->size.height <= 0) {
223 auto context = context_.lock();
228 if (requires_blit_) {
229 if (!(source_texture_ && destination_texture_)) {
233 auto blit_command_buffer = context->CreateCommandBuffer();
234 if (!blit_command_buffer) {
237 auto blit_pass = blit_command_buffer->CreateBlitPass();
238 if (!clip_rect_.has_value()) {
242 blit_pass->AddCopy(source_texture_, destination_texture_, std::nullopt,
244 blit_pass->EncodeCommands(context->GetResourceAllocator());
245 if (!blit_command_buffer->SubmitCommands()) {
251 id<MTLCommandBuffer> command_buffer =
257 if ([[NSThread currentThread] isMainThread] ||
258 [[MTLCaptureManager sharedCaptureManager] isCapturing]) {
259 TRACE_EVENT0(
"flutter",
"waitUntilScheduled");
260 [command_buffer commit];
261 [command_buffer waitUntilScheduled];
264 [command_buffer presentDrawable:drawable_];
265 [command_buffer commit];
271 #pragma GCC diagnostic pop