7 #include "flutter/fml/closure.h"
14 : libraries_([libraries mutableCopy]) {
15 if (libraries_ == nil || libraries_.count == 0) {
22 ShaderLibraryMTL::~ShaderLibraryMTL() =
default;
24 bool ShaderLibraryMTL::IsValid()
const {
30 case ShaderStage::kVertex:
31 return MTLFunctionTypeVertex;
32 case ShaderStage::kFragment:
33 return MTLFunctionTypeFragment;
34 case ShaderStage::kUnknown:
35 case ShaderStage::kCompute:
36 return MTLFunctionTypeKernel;
41 std::shared_ptr<const ShaderFunction> ShaderLibraryMTL::GetFunction(
42 std::string_view name,
53 ShaderKey key(name, stage);
55 id<MTLFunction>
function = nil;
56 id<MTLLibrary> library = nil;
59 ReaderLock lock(libraries_mutex_);
61 if (
auto found = functions_.find(key); found != functions_.end()) {
65 for (
size_t i = 0, count = [libraries_ count]; i < count; i++) {
66 library = libraries_[i];
67 function = [library newFunctionWithName:@(name.data())];
73 if (
function == nil) {
79 <<
" was for an unexpected shader stage.";
83 auto func = std::shared_ptr<ShaderFunctionMTL>(
new ShaderFunctionMTL(
84 library_id_,
function, library, {name.data(), name.size()}, stage));
85 functions_[key] = func;
91 id<MTLDevice> ShaderLibraryMTL::GetDevice()
const {
92 ReaderLock lock(libraries_mutex_);
93 if (libraries_.count > 0u) {
94 return libraries_[0].device;
100 void ShaderLibraryMTL::RegisterFunction(std::string name,
102 std::shared_ptr<fml::Mapping> code,
103 RegistrationCallback callback) {
105 callback = [](
auto) {};
107 auto failure_callback = std::make_shared<fml::ScopedCleanupClosure>(
108 [callback]() { callback(
false); });
112 if (code ==
nullptr || code->GetMapping() ==
nullptr) {
115 auto device = GetDevice();
120 auto source = [[NSString alloc] initWithBytes:code->GetMapping()
121 length:code->GetSize()
122 encoding:NSUTF8StringEncoding];
124 auto weak_this = weak_from_this();
125 [device newLibraryWithSource:source
127 completionHandler:^(id<MTLLibrary> library, NSError* error) {
128 auto strong_this = weak_this.lock();
131 "dynamic shader stage could be registered.";
136 << error.localizedDescription.UTF8String;
139 reinterpret_cast<ShaderLibraryMTL*
>(strong_this.get())
140 ->RegisterLibrary(library);
141 failure_callback->Release();
147 void ShaderLibraryMTL::UnregisterFunction(std::string name,
ShaderStage stage) {
148 ReaderLock lock(libraries_mutex_);
152 bool found_library =
false;
153 for (
size_t i = [libraries_ count] - 1; i >= 0; i--) {
154 id<MTLFunction>
function =
155 [libraries_[i] newFunctionWithName:@(name.data())];
157 [libraries_ removeObjectAtIndex:i];
158 found_library =
true;
162 if (!found_library) {
164 <<
" was not found, so it couldn't be unregistered.";
169 ShaderKey key(name, stage);
171 auto found = functions_.find(key);
172 if (found == functions_.end()) {
174 <<
" was not found, so it couldn't be unregistered.";
178 functions_.erase(found);
181 void ShaderLibraryMTL::RegisterLibrary(id<MTLLibrary> library) {
182 WriterLock lock(libraries_mutex_);
183 [libraries_ addObject:library];
static MTLFunctionType ToMTLFunctionType(ShaderStage stage)