Flutter Engine
ios_context_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_context_metal.h"
6 
7 #include "flutter/fml/logging.h"
8 #include "flutter/shell/common/persistent_cache.h"
9 #import "flutter/shell/platform/darwin/ios/ios_external_texture_metal.h"
10 #include "third_party/skia/include/gpu/GrContextOptions.h"
11 
12 namespace flutter {
13 
14 static GrContextOptions CreateMetalGrContextOptions() {
15  GrContextOptions options = {};
17  options.fShaderCacheStrategy = GrContextOptions::ShaderCacheStrategy::kSkSL;
18  }
20  options.fPersistentCache = PersistentCache::GetCacheForProcess();
21  return options;
22 }
23 
25  device_.reset([MTLCreateSystemDefaultDevice() retain]);
26  if (!device_) {
27  FML_DLOG(ERROR) << "Could not acquire Metal device.";
28  return;
29  }
30 
31  main_queue_.reset([device_ newCommandQueue]);
32 
33  if (!main_queue_) {
34  FML_DLOG(ERROR) << "Could not create Metal command queue.";
35  return;
36  }
37 
38  [main_queue_ setLabel:@"Flutter Main Queue"];
39 
40  const auto& context_options = CreateMetalGrContextOptions();
41 
42  // Skia expect arguments to `MakeMetal` transfer ownership of the reference in for release later
43  // when the GrDirectContext is collected.
44  main_context_ =
45  GrDirectContext::MakeMetal([device_ retain], [main_queue_ retain], context_options);
46  resource_context_ =
47  GrDirectContext::MakeMetal([device_ retain], [main_queue_ retain], context_options);
48 
49  if (!main_context_ || !resource_context_) {
50  FML_DLOG(ERROR) << "Could not create Skia Metal contexts.";
51  return;
52  }
53 
54  resource_context_->setResourceCacheLimits(0u, 0u);
55 
56  CVMetalTextureCacheRef texture_cache_raw = NULL;
57  auto cv_return = CVMetalTextureCacheCreate(kCFAllocatorDefault, // allocator
58  NULL, // cache attributes (NULL default)
59  device_.get(), // metal device
60  NULL, // texture attributes (NULL default)
61  &texture_cache_raw // [out] cache
62  );
63  if (cv_return != kCVReturnSuccess) {
64  FML_DLOG(ERROR) << "Could not create Metal texture cache.";
65  return;
66  }
67  texture_cache_.Reset(texture_cache_raw);
68 }
69 
71 
73  return device_;
74 }
75 
77  return main_queue_;
78 }
79 
81  // TODO(52150): Create a dedicated resource queue once multiple queues are supported in Skia.
82  return main_queue_;
83 }
84 
85 sk_sp<GrDirectContext> IOSContextMetal::GetMainContext() const {
86  return main_context_;
87 }
88 
89 sk_sp<GrDirectContext> IOSContextMetal::GetResourceContext() const {
90  return resource_context_;
91 }
92 
93 // |IOSContext|
94 sk_sp<GrDirectContext> IOSContextMetal::CreateResourceContext() {
95  return resource_context_;
96 }
97 
98 // |IOSContext|
99 std::unique_ptr<GLContextResult> IOSContextMetal::MakeCurrent() {
100  // This only makes sense for context that need to be bound to a specific thread.
101  return std::make_unique<GLContextDefaultResult>(true);
102 }
103 
104 // |IOSContext|
105 std::unique_ptr<Texture> IOSContextMetal::CreateExternalTexture(
106  int64_t texture_id,
107  fml::scoped_nsobject<NSObject<FlutterTexture>> texture) {
108  return std::make_unique<IOSExternalTextureMetal>(texture_id, texture_cache_, std::move(texture));
109 }
110 
111 } // namespace flutter
sk_sp< GrDirectContext > GetResourceContext() const
void reset(NST object=nil)
void Reset(T instance=nullptr)
Definition: cf_utils.h:43
fml::scoped_nsprotocol< id< MTLDevice > > GetDevice() const
fml::scoped_nsprotocol< id< MTLCommandQueue > > GetResourceCommandQueue() const
sk_sp< GrDirectContext > GetMainContext() const
fml::scoped_nsprotocol< id< MTLCommandQueue > > GetMainCommandQueue() const
static PersistentCache * GetCacheForProcess()
#define FML_DLOG(severity)
Definition: logging.h:85
static GrContextOptions CreateMetalGrContextOptions()