Flutter iOS Embedder
ios_surface_metal_skia.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 
6 
7 #include "flutter/shell/gpu/gpu_surface_metal_delegate.h"
8 #include "flutter/shell/gpu/gpu_surface_metal_skia.h"
10 
11 @protocol FlutterMetalDrawable <MTLDrawable>
12 - (void)flutterPrepareForPresent:(nonnull id<MTLCommandBuffer>)commandBuffer;
13 @end
14 
15 namespace flutter {
16 
17 static IOSContextMetalSkia* CastToMetalContext(const std::shared_ptr<IOSContext>& context) {
18  return reinterpret_cast<IOSContextMetalSkia*>(context.get());
19 }
20 
21 IOSSurfaceMetalSkia::IOSSurfaceMetalSkia(const fml::scoped_nsobject<CAMetalLayer>& layer,
22  std::shared_ptr<IOSContext> context)
23  : IOSSurface(std::move(context)),
24  GPUSurfaceMetalDelegate(MTLRenderTargetType::kCAMetalLayer),
25  layer_(layer) {
26  is_valid_ = layer_;
27  auto metal_context = CastToMetalContext(GetContext());
28  auto darwin_context = metal_context->GetDarwinContext().get();
29  command_queue_ = darwin_context.commandQueue;
30  device_ = darwin_context.device;
31 }
32 
33 // |IOSSurface|
35 
36 // |IOSSurface|
37 bool IOSSurfaceMetalSkia::IsValid() const {
38  return is_valid_;
39 }
40 
41 // |IOSSurface|
42 void IOSSurfaceMetalSkia::UpdateStorageSizeIfNecessary() {
43  // Nothing to do.
44 }
45 
46 // |IOSSurface|
47 std::unique_ptr<Surface> IOSSurfaceMetalSkia::CreateGPUSurface(GrDirectContext* context) {
48  FML_DCHECK(context);
49  return std::make_unique<GPUSurfaceMetalSkia>(this, // delegate
50  sk_ref_sp(context), // context
51  GetContext()->GetMsaaSampleCount() // sample count
52  );
53 }
54 
55 // |GPUSurfaceMetalDelegate|
56 GPUCAMetalLayerHandle IOSSurfaceMetalSkia::GetCAMetalLayer(const SkISize& frame_info) const {
57  CAMetalLayer* layer = layer_.get();
58  layer.device = device_;
59 
60  layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
61  // Flutter needs to read from the color attachment in cases where there are effects such as
62  // backdrop filters. Flutter plugins that create platform views may also read from the layer.
63  layer.framebufferOnly = NO;
64 
65  const auto drawable_size = CGSizeMake(frame_info.width(), frame_info.height());
66  if (!CGSizeEqualToSize(drawable_size, layer.drawableSize)) {
67  layer.drawableSize = drawable_size;
68  }
69 
70  // When there are platform views in the scene, the drawable needs to be presented in the same
71  // transaction as the one created for platform views. When the drawable are being presented from
72  // the raster thread, there is no such transaction.
73  layer.presentsWithTransaction = [[NSThread currentThread] isMainThread];
74 
75  return layer;
76 }
77 
78 // |GPUSurfaceMetalDelegate|
79 bool IOSSurfaceMetalSkia::PresentDrawable(GrMTLHandle drawable) const {
80  if (drawable == nullptr) {
81  FML_DLOG(ERROR) << "Could not acquire next Metal drawable from the SkSurface.";
82  return false;
83  }
84 
85  auto command_buffer =
86  fml::scoped_nsprotocol<id<MTLCommandBuffer>>([[command_queue_ commandBuffer] retain]);
87 
88  id<CAMetalDrawable> metal_drawable = reinterpret_cast<id<CAMetalDrawable>>(drawable);
89  if ([metal_drawable conformsToProtocol:@protocol(FlutterMetalDrawable)]) {
90  [(id<FlutterMetalDrawable>)metal_drawable flutterPrepareForPresent:command_buffer.get()];
91  }
92 
93  [command_buffer.get() commit];
94  [command_buffer.get() waitUntilScheduled];
95 
96  [metal_drawable present];
97  return true;
98 }
99 
100 // |GPUSurfaceMetalDelegate|
101 GPUMTLTextureInfo IOSSurfaceMetalSkia::GetMTLTexture(const SkISize& frame_info) const {
102  FML_CHECK(false) << "render to texture not supported on ios";
103  return {.texture_id = -1, .texture = nullptr};
104 }
105 
106 // |GPUSurfaceMetalDelegate|
107 bool IOSSurfaceMetalSkia::PresentTexture(GPUMTLTextureInfo texture) const {
108  FML_CHECK(false) << "render to texture not supported on ios";
109  return false;
110 }
111 
112 // |GPUSurfaceMetalDelegate|
113 bool IOSSurfaceMetalSkia::AllowsDrawingWhenGpuDisabled() const {
114  return false;
115 }
116 
117 } // namespace flutter
flutter::CastToMetalContext
static IOSContextMetalSkia * CastToMetalContext(const std::shared_ptr< IOSContext > &context)
Definition: ios_surface_metal_skia.mm:17
ios_surface_metal_skia.h
flutter::IOSSurfaceMetalSkia::~IOSSurfaceMetalSkia
~IOSSurfaceMetalSkia()
flutter::IOSSurface
Definition: ios_surface.h:25
FlutterMetalDrawable-p
Definition: FlutterMetalLayer.h:33
ios_context_metal_skia.h
flutter::IOSContextMetalSkia
Definition: ios_context_metal_skia.h:19
flutter
Definition: accessibility_bridge.h:28
flutter::IOSSurfaceMetalSkia::IOSSurfaceMetalSkia
IOSSurfaceMetalSkia(const fml::scoped_nsobject< CAMetalLayer > &layer, std::shared_ptr< IOSContext > context)
Definition: ios_surface_metal_skia.mm:21
flutter::IOSSurface::GetContext
std::shared_ptr< IOSContext > GetContext() const
Definition: ios_surface.mm:57