Flutter Engine
ios_surface_metal.mm
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #import "flutter/shell/platform/darwin/ios/ios_surface_metal.h"
6 
7 #include "flutter/shell/gpu/gpu_surface_metal.h"
8 #include "flutter/shell/gpu/gpu_surface_metal_delegate.h"
9 #include "flutter/shell/platform/darwin/ios/ios_context_metal.h"
10 
11 namespace flutter {
12 
13 static IOSContextMetal* CastToMetalContext(const std::shared_ptr<IOSContext>& context) {
14  return reinterpret_cast<IOSContextMetal*>(context.get());
15 }
16 
18  std::shared_ptr<IOSContext> context)
19  : IOSSurface(std::move(context)),
21  layer_(std::move(layer)) {
22  is_valid_ = layer_;
23  auto metal_context = CastToMetalContext(GetContext());
24  auto darwin_context = metal_context->GetDarwinContext().get();
25  command_queue_ = darwin_context.commandQueue;
26  device_ = darwin_context.device;
27 }
28 
29 // |IOSSurface|
31 
32 // |IOSSurface|
33 bool IOSSurfaceMetal::IsValid() const {
34  return is_valid_;
35 }
36 
37 // |IOSSurface|
38 void IOSSurfaceMetal::UpdateStorageSizeIfNecessary() {
39  // Nothing to do.
40 }
41 
42 // |IOSSurface|
43 std::unique_ptr<Surface> IOSSurfaceMetal::CreateGPUSurface(GrDirectContext* context) {
44  FML_DCHECK(context);
45  return std::make_unique<GPUSurfaceMetal>(this, // layer
46  sk_ref_sp(context) // context
47  );
48 }
49 
50 // |GPUSurfaceMetalDelegate|
51 GPUCAMetalLayerHandle IOSSurfaceMetal::GetCAMetalLayer(const SkISize& frame_info) const {
52  CAMetalLayer* layer = layer_.get();
53  layer.device = device_;
54 
55  layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
56  // Flutter needs to read from the color attachment in cases where there are effects such as
57  // backdrop filters.
58  layer.framebufferOnly = NO;
59 
60  const auto drawable_size = CGSizeMake(frame_info.width(), frame_info.height());
61  if (!CGSizeEqualToSize(drawable_size, layer.drawableSize)) {
62  layer.drawableSize = drawable_size;
63  }
64 
65  // When there are platform views in the scene, the drawable needs to be presented in the same
66  // transaction as the one created for platform views. When the drawable are being presented from
67  // the raster thread, there is no such transaction.
68  layer.presentsWithTransaction = [[NSThread currentThread] isMainThread];
69 
70  return layer;
71 }
72 
73 // |GPUSurfaceMetalDelegate|
74 bool IOSSurfaceMetal::PresentDrawable(GrMTLHandle drawable) const {
75  if (drawable == nullptr) {
76  FML_DLOG(ERROR) << "Could not acquire next Metal drawable from the SkSurface.";
77  return false;
78  }
79 
80  auto command_buffer =
81  fml::scoped_nsprotocol<id<MTLCommandBuffer>>([[command_queue_ commandBuffer] retain]);
82  [command_buffer.get() commit];
83  [command_buffer.get() waitUntilScheduled];
84 
85  [reinterpret_cast<id<CAMetalDrawable>>(drawable) present];
86  return true;
87 }
88 
89 // |GPUSurfaceMetalDelegate|
90 GPUMTLTextureInfo IOSSurfaceMetal::GetMTLTexture(const SkISize& frame_info) const {
91  FML_CHECK(false) << "render to texture not supported on ios";
92  return {.texture_id = -1, .texture = nullptr};
93 }
94 
95 // |GPUSurfaceMetalDelegate|
96 bool IOSSurfaceMetal::PresentTexture(GPUMTLTextureInfo texture) const {
97  FML_CHECK(false) << "render to texture not supported on ios";
98  return false;
99 }
100 
101 // |GPUSurfaceMetalDelegate|
102 bool IOSSurfaceMetal::AllowsDrawingWhenGpuDisabled() const {
103  return false;
104 }
105 
106 } // namespace flutter
std::shared_ptr< IOSContext > GetContext() const
Definition: ios_surface.mm:55
G_BEGIN_DECLS FlTexture * texture
#define FML_DCHECK(condition)
Definition: logging.h:86
Interface implemented by all platform surfaces that can present a metal backing store to the "screen"...
IOSSurfaceMetal(fml::scoped_nsobject< CAMetalLayer > layer, std::shared_ptr< IOSContext > context)
Definition: ref_ptr.h:252
static IOSContextMetal * CastToMetalContext(const std::shared_ptr< IOSContext > &context)
#define FML_CHECK(condition)
Definition: logging.h:68
#define FML_DLOG(severity)
Definition: logging.h:85