Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / gpu / ganesh / mtl / GrMtlUtil.mm
1 /*
2  * Copyright 2017 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7
8 #include "src/gpu/ganesh/mtl/GrMtlUtil.h"
9
10 #include "include/gpu/GrBackendSurface.h"
11 #include "include/private/SkMutex.h"
12 #include "include/private/gpu/ganesh/GrTypesPriv.h"
13 #include "src/core/SkTraceEvent.h"
14 #include "src/gpu/ganesh/GrSurface.h"
15 #include "src/gpu/ganesh/mtl/GrMtlGpu.h"
16 #include "src/gpu/ganesh/mtl/GrMtlRenderTarget.h"
17 #include "src/gpu/ganesh/mtl/GrMtlTexture.h"
18 #include "src/sksl/SkSLCompiler.h"
19 #include "src/utils/SkShaderUtils.h"
20
21 #import <Metal/Metal.h>
22 #ifdef SK_BUILD_FOR_IOS
23 #import <UIKit/UIApplication.h>
24 #endif
25
26 #if !__has_feature(objc_arc)
27 #error This file must be compiled with Arc. Use -fobjc-arc flag
28 #endif
29
30 GR_NORETAIN_BEGIN
31
32 NSError* GrCreateMtlError(NSString* description, GrMtlErrorCode errorCode) {
33     NSDictionary* userInfo = [NSDictionary dictionaryWithObject:description
34                                                          forKey:NSLocalizedDescriptionKey];
35     return [NSError errorWithDomain:@"org.skia.ganesh"
36                                code:(NSInteger)errorCode
37                            userInfo:userInfo];
38 }
39
40 MTLTextureDescriptor* GrGetMTLTextureDescriptor(id<MTLTexture> mtlTexture) {
41     MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init];
42     texDesc.textureType = mtlTexture.textureType;
43     texDesc.pixelFormat = mtlTexture.pixelFormat;
44     texDesc.width = mtlTexture.width;
45     texDesc.height = mtlTexture.height;
46     texDesc.depth = mtlTexture.depth;
47     texDesc.mipmapLevelCount = mtlTexture.mipmapLevelCount;
48     texDesc.arrayLength = mtlTexture.arrayLength;
49     texDesc.sampleCount = mtlTexture.sampleCount;
50     if (@available(macOS 10.11, iOS 9.0, *)) {
51         texDesc.usage = mtlTexture.usage;
52     }
53     return texDesc;
54 }
55
56 // Print the source code for all shaders generated.
57 static const bool gPrintSKSL = false;
58 static const bool gPrintMSL = false;
59
60 bool GrSkSLToMSL(const GrMtlGpu* gpu,
61                  const std::string& sksl,
62                  SkSL::ProgramKind programKind,
63                  const SkSL::Program::Settings& settings,
64                  std::string* msl,
65                  SkSL::Program::Inputs* outInputs,
66                  GrContextOptions::ShaderErrorHandler* errorHandler) {
67 #ifdef SK_DEBUG
68     std::string src = SkShaderUtils::PrettyPrint(sksl);
69 #else
70     const std::string& src = sksl;
71 #endif
72     SkSL::Compiler* compiler = gpu->shaderCompiler();
73     std::unique_ptr<SkSL::Program> program =
74             gpu->shaderCompiler()->convertProgram(programKind,
75                                                   src,
76                                                   settings);
77     if (!program || !compiler->toMetal(*program, msl)) {
78         errorHandler->compileError(src.c_str(), compiler->errorText().c_str());
79         return false;
80     }
81
82     if (gPrintSKSL || gPrintMSL) {
83         SkShaderUtils::PrintShaderBanner(programKind);
84         if (gPrintSKSL) {
85             SkDebugf("SKSL:\n");
86             SkShaderUtils::PrintLineByLine(SkShaderUtils::PrettyPrint(sksl));
87         }
88         if (gPrintMSL) {
89             SkDebugf("MSL:\n");
90             SkShaderUtils::PrintLineByLine(SkShaderUtils::PrettyPrint(*msl));
91         }
92     }
93
94     *outInputs = program->fInputs;
95     return true;
96 }
97
98 id<MTLLibrary> GrCompileMtlShaderLibrary(const GrMtlGpu* gpu,
99                                          const std::string& msl,
100                                          GrContextOptions::ShaderErrorHandler* errorHandler) {
101     TRACE_EVENT0("skia.shaders", "driver_compile_shader");
102     auto nsSource = [[NSString alloc] initWithBytesNoCopy:const_cast<char*>(msl.c_str())
103                                                    length:msl.size()
104                                                  encoding:NSUTF8StringEncoding
105                                              freeWhenDone:NO];
106     MTLCompileOptions* options = [[MTLCompileOptions alloc] init];
107     // array<> is supported in MSL 2.0 on MacOS 10.13+ and iOS 11+,
108     // and in MSL 1.2 on iOS 10+ (but not MacOS).
109     if (@available(macOS 10.13, iOS 11.0, *)) {
110         options.languageVersion = MTLLanguageVersion2_0;
111 #if defined(SK_BUILD_FOR_IOS)
112     } else if (@available(macOS 10.12, iOS 10.0, *)) {
113         options.languageVersion = MTLLanguageVersion1_2;
114 #endif
115     }
116     if (gpu->caps()->shaderCaps()->canUseFastMath()) {
117         options.fastMathEnabled = YES;
118     }
119
120     NSError* error = nil;
121 #if defined(SK_BUILD_FOR_MAC)
122     id<MTLLibrary> compiledLibrary = GrMtlNewLibraryWithSource(gpu->device(), nsSource,
123                                                                options, &error);
124 #else
125     id<MTLLibrary> compiledLibrary = [gpu->device() newLibraryWithSource:nsSource
126                                                                  options:options
127                                                                    error:&error];
128 #endif
129     if (!compiledLibrary) {
130         errorHandler->compileError(msl.c_str(), error.debugDescription.UTF8String);
131         return nil;
132     }
133
134     return compiledLibrary;
135 }
136
137 void GrPrecompileMtlShaderLibrary(const GrMtlGpu* gpu,
138                                   const std::string& msl) {
139     auto nsSource = [[NSString alloc] initWithBytesNoCopy:const_cast<char*>(msl.c_str())
140                                                    length:msl.size()
141                                                  encoding:NSUTF8StringEncoding
142                                              freeWhenDone:NO];
143     // Do nothing after completion for now.
144     // TODO: cache the result somewhere so we can use it later.
145     MTLNewLibraryCompletionHandler completionHandler =
146             ^(id<MTLLibrary> library, NSError* error) {};
147     [gpu->device() newLibraryWithSource:nsSource
148                                 options:nil
149                       completionHandler:completionHandler];
150 }
151
152 // Wrapper to get atomic assignment for compiles and pipeline creation
153 class MtlCompileResult : public SkRefCnt {
154 public:
155     MtlCompileResult() : fCompiledObject(nil), fError(nil) {}
156     void set(id compiledObject, NSError* error) {
157         SkAutoMutexExclusive automutex(fMutex);
158         fCompiledObject = compiledObject;
159         fError = error;
160     }
161     std::pair<id, NSError*> get() {
162         SkAutoMutexExclusive automutex(fMutex);
163         return std::make_pair(fCompiledObject, fError);
164     }
165 private:
166     SkMutex fMutex;
167     id fCompiledObject SK_GUARDED_BY(fMutex);
168     NSError* fError SK_GUARDED_BY(fMutex);
169 };
170
171 id<MTLLibrary> GrMtlNewLibraryWithSource(id<MTLDevice> device, NSString* mslCode,
172                                          MTLCompileOptions* options, NSError** error) {
173     dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
174     sk_sp<MtlCompileResult> compileResult(new MtlCompileResult);
175     // We have to increment the ref for the Obj-C block manually because it won't do it for us
176     compileResult->ref();
177     MTLNewLibraryCompletionHandler completionHandler =
178             ^(id<MTLLibrary> library, NSError* compileError) {
179                 compileResult->set(library, compileError);
180                 dispatch_semaphore_signal(semaphore);
181                 compileResult->unref();
182             };
183
184     [device newLibraryWithSource: mslCode
185                          options: options
186                completionHandler: completionHandler];
187
188     // Wait 1 second for the compiler
189     constexpr auto kTimeoutNS = 1000000000UL;
190     if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, kTimeoutNS))) {
191         if (error) {
192             constexpr auto kTimeoutMS = kTimeoutNS/1000000UL;
193             NSString* description =
194                     [NSString stringWithFormat:@"Compilation took longer than %lu ms",
195                                                kTimeoutMS];
196             *error = GrCreateMtlError(description, GrMtlErrorCode::kTimeout);
197         }
198         return nil;
199     }
200
201     id<MTLLibrary> compiledLibrary;
202     std::tie(compiledLibrary, *error) = compileResult->get();
203
204     return compiledLibrary;
205 }
206
207 id<MTLRenderPipelineState> GrMtlNewRenderPipelineStateWithDescriptor(
208         id<MTLDevice> device, MTLRenderPipelineDescriptor* pipelineDescriptor, NSError** error) {
209     dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
210     sk_sp<MtlCompileResult> compileResult(new MtlCompileResult);
211     // We have to increment the ref for the Obj-C block manually because it won't do it for us
212     compileResult->ref();
213     MTLNewRenderPipelineStateCompletionHandler completionHandler =
214             ^(id<MTLRenderPipelineState> state, NSError* compileError) {
215                 compileResult->set(state, compileError);
216                 dispatch_semaphore_signal(semaphore);
217                 compileResult->unref();
218             };
219
220     [device newRenderPipelineStateWithDescriptor: pipelineDescriptor
221                                completionHandler: completionHandler];
222
223     // Wait 1 second for pipeline creation
224     constexpr auto kTimeoutNS = 1000000000UL;
225     if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, kTimeoutNS))) {
226         if (error) {
227             constexpr auto kTimeoutMS = kTimeoutNS/1000000UL;
228             NSString* description =
229                     [NSString stringWithFormat:@"Pipeline creation took longer than %lu ms",
230                                                kTimeoutMS];
231             *error = GrCreateMtlError(description, GrMtlErrorCode::kTimeout);
232         }
233         return nil;
234     }
235
236     id<MTLRenderPipelineState> pipelineState;
237     std::tie(pipelineState, *error) = compileResult->get();
238
239     return pipelineState;
240 }
241
242 id<MTLTexture> GrGetMTLTextureFromSurface(GrSurface* surface) {
243     id<MTLTexture> mtlTexture = nil;
244
245     GrMtlRenderTarget* renderTarget = static_cast<GrMtlRenderTarget*>(surface->asRenderTarget());
246     GrMtlTexture* texture;
247     if (renderTarget) {
248         // We should not be using this for multisampled rendertargets with a separate resolve
249         // texture.
250         if (renderTarget->resolveAttachment()) {
251             SkASSERT(renderTarget->numSamples() > 1);
252             SkASSERT(false);
253             return nil;
254         }
255         mtlTexture = renderTarget->colorMTLTexture();
256     } else {
257         texture = static_cast<GrMtlTexture*>(surface->asTexture());
258         if (texture) {
259             mtlTexture = texture->mtlTexture();
260         }
261     }
262     return mtlTexture;
263 }
264
265
266 //////////////////////////////////////////////////////////////////////////////
267 // CPP Utils
268
269 GrMTLPixelFormat GrGetMTLPixelFormatFromMtlTextureInfo(const GrMtlTextureInfo& info) {
270     id<MTLTexture> GR_NORETAIN mtlTexture = GrGetMTLTexture(info.fTexture.get());
271     return static_cast<GrMTLPixelFormat>(mtlTexture.pixelFormat);
272 }
273
274 uint32_t GrMtlFormatChannels(GrMTLPixelFormat mtlFormat) {
275     switch (mtlFormat) {
276         case MTLPixelFormatRGBA8Unorm:      return kRGBA_SkColorChannelFlags;
277         case MTLPixelFormatR8Unorm:         return kRed_SkColorChannelFlag;
278         case MTLPixelFormatA8Unorm:         return kAlpha_SkColorChannelFlag;
279         case MTLPixelFormatBGRA8Unorm:      return kRGBA_SkColorChannelFlags;
280 #if defined(SK_BUILD_FOR_IOS) && !TARGET_OS_SIMULATOR
281         case MTLPixelFormatB5G6R5Unorm:     return kRGB_SkColorChannelFlags;
282 #endif
283         case MTLPixelFormatRGBA16Float:     return kRGBA_SkColorChannelFlags;
284         case MTLPixelFormatR16Float:        return kRed_SkColorChannelFlag;
285         case MTLPixelFormatRG8Unorm:        return kRG_SkColorChannelFlags;
286         case MTLPixelFormatRGB10A2Unorm:    return kRGBA_SkColorChannelFlags;
287 #ifdef SK_BUILD_FOR_MAC
288         case MTLPixelFormatBGR10A2Unorm:    return kRGBA_SkColorChannelFlags;
289 #endif
290 #if defined(SK_BUILD_FOR_IOS) && !TARGET_OS_SIMULATOR
291         case MTLPixelFormatABGR4Unorm:      return kRGBA_SkColorChannelFlags;
292 #endif
293         case MTLPixelFormatRGBA8Unorm_sRGB: return kRGBA_SkColorChannelFlags;
294         case MTLPixelFormatR16Unorm:        return kRed_SkColorChannelFlag;
295         case MTLPixelFormatRG16Unorm:       return kRG_SkColorChannelFlags;
296 #ifdef SK_BUILD_FOR_IOS
297         case MTLPixelFormatETC2_RGB8:       return kRGB_SkColorChannelFlags;
298 #else
299         case MTLPixelFormatBC1_RGBA:        return kRGBA_SkColorChannelFlags;
300 #endif
301         case MTLPixelFormatRGBA16Unorm:     return kRGBA_SkColorChannelFlags;
302         case MTLPixelFormatRG16Float:       return kRG_SkColorChannelFlags;
303         case MTLPixelFormatStencil8:        return 0;
304
305         default:                            return 0;
306     }
307 }
308
309 GrColorFormatDesc GrMtlFormatDesc(GrMTLPixelFormat mtlFormat)  {
310     switch (mtlFormat) {
311         case MTLPixelFormatRGBA8Unorm:
312             return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
313         case MTLPixelFormatR8Unorm:
314             return GrColorFormatDesc::MakeR(8, GrColorTypeEncoding::kUnorm);
315         case MTLPixelFormatA8Unorm:
316             return GrColorFormatDesc::MakeAlpha(8, GrColorTypeEncoding::kUnorm);
317         case MTLPixelFormatBGRA8Unorm:
318             return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
319 #if defined(SK_BUILD_FOR_IOS) && !TARGET_OS_SIMULATOR
320         case MTLPixelFormatB5G6R5Unorm:
321             return GrColorFormatDesc::MakeRGB(5, 6, 5, GrColorTypeEncoding::kUnorm);
322 #endif
323         case MTLPixelFormatRGBA16Float:
324             return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kFloat);
325         case MTLPixelFormatR16Float:
326             return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kFloat);
327         case MTLPixelFormatRG8Unorm:
328             return GrColorFormatDesc::MakeRG(8, GrColorTypeEncoding::kUnorm);
329         case MTLPixelFormatRGB10A2Unorm:
330             return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
331 #ifdef SK_BUILD_FOR_MAC
332         case MTLPixelFormatBGR10A2Unorm:
333             return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
334 #endif
335 #if defined(SK_BUILD_FOR_IOS) && !TARGET_OS_SIMULATOR
336         case MTLPixelFormatABGR4Unorm:
337             return GrColorFormatDesc::MakeRGBA(4, GrColorTypeEncoding::kUnorm);
338 #endif
339         case MTLPixelFormatRGBA8Unorm_sRGB:
340             return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kSRGBUnorm);
341         case MTLPixelFormatR16Unorm:
342             return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kUnorm);
343         case MTLPixelFormatRG16Unorm:
344             return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kUnorm);
345         case MTLPixelFormatRGBA16Unorm:
346             return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kUnorm);
347         case MTLPixelFormatRG16Float:
348             return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kFloat);
349
350         // Compressed texture formats are not expected to have a description.
351 #ifdef SK_BUILD_FOR_IOS
352         case MTLPixelFormatETC2_RGB8: return GrColorFormatDesc::MakeInvalid();
353 #else
354         case MTLPixelFormatBC1_RGBA:  return GrColorFormatDesc::MakeInvalid();
355 #endif
356
357         // This type only describes color channels.
358         case MTLPixelFormatStencil8: return GrColorFormatDesc::MakeInvalid();
359
360         default:
361             return GrColorFormatDesc::MakeInvalid();
362     }
363 }
364
365 SkImage::CompressionType GrMtlBackendFormatToCompressionType(const GrBackendFormat& format) {
366     MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
367     return GrMtlFormatToCompressionType(mtlFormat);
368 }
369
370 bool GrMtlFormatIsCompressed(MTLPixelFormat mtlFormat) {
371     switch (mtlFormat) {
372 #ifdef SK_BUILD_FOR_IOS
373         case MTLPixelFormatETC2_RGB8:
374             return true;
375 #else
376         case MTLPixelFormatBC1_RGBA:
377             return true;
378 #endif
379         default:
380             return false;
381     }
382 }
383
384 SkImage::CompressionType GrMtlFormatToCompressionType(MTLPixelFormat mtlFormat) {
385     switch (mtlFormat) {
386 #ifdef SK_BUILD_FOR_IOS
387         case MTLPixelFormatETC2_RGB8: return SkImage::CompressionType::kETC2_RGB8_UNORM;
388 #else
389         case MTLPixelFormatBC1_RGBA:  return SkImage::CompressionType::kBC1_RGBA8_UNORM;
390 #endif
391         default:                      return SkImage::CompressionType::kNone;
392     }
393
394     SkUNREACHABLE;
395 }
396
397 int GrMtlTextureInfoSampleCount(const GrMtlTextureInfo& info) {
398     id<MTLTexture> texture = GrGetMTLTexture(info.fTexture.get());
399     if (!texture) {
400         return 0;
401     }
402     return texture.sampleCount;
403 }
404
405 size_t GrMtlBackendFormatBytesPerBlock(const GrBackendFormat& format) {
406     MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
407     return GrMtlFormatBytesPerBlock(mtlFormat);
408 }
409
410 size_t GrMtlFormatBytesPerBlock(MTLPixelFormat mtlFormat) {
411     switch (mtlFormat) {
412         case MTLPixelFormatInvalid:         return 0;
413         case MTLPixelFormatRGBA8Unorm:      return 4;
414         case MTLPixelFormatR8Unorm:         return 1;
415         case MTLPixelFormatA8Unorm:         return 1;
416         case MTLPixelFormatBGRA8Unorm:      return 4;
417 #ifdef SK_BUILD_FOR_IOS
418         case MTLPixelFormatB5G6R5Unorm:     return 2;
419 #endif
420         case MTLPixelFormatRGBA16Float:     return 8;
421         case MTLPixelFormatR16Float:        return 2;
422         case MTLPixelFormatRG8Unorm:        return 2;
423         case MTLPixelFormatRGB10A2Unorm:    return 4;
424 #ifdef SK_BUILD_FOR_MAC
425         case MTLPixelFormatBGR10A2Unorm:    return 4;
426 #endif
427 #ifdef SK_BUILD_FOR_IOS
428         case MTLPixelFormatABGR4Unorm:      return 2;
429 #endif
430         case MTLPixelFormatRGBA8Unorm_sRGB: return 4;
431         case MTLPixelFormatR16Unorm:        return 2;
432         case MTLPixelFormatRG16Unorm:       return 4;
433 #ifdef SK_BUILD_FOR_IOS
434         case MTLPixelFormatETC2_RGB8:       return 8;
435 #else
436         case MTLPixelFormatBC1_RGBA:        return 8;
437 #endif
438         case MTLPixelFormatRGBA16Unorm:     return 8;
439         case MTLPixelFormatRG16Float:       return 4;
440         case MTLPixelFormatStencil8:        return 1;
441
442         default:                            return 0;
443     }
444 }
445
446 int GrMtlBackendFormatStencilBits(const GrBackendFormat& format) {
447     MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
448     return GrMtlFormatStencilBits(mtlFormat);
449 }
450
451 int GrMtlFormatStencilBits(MTLPixelFormat mtlFormat) {
452     switch(mtlFormat) {
453      case MTLPixelFormatStencil8:
454          return 8;
455      default:
456          return 0;
457     }
458 }
459
460 #ifdef SK_BUILD_FOR_IOS
461 bool GrMtlIsAppInBackground() {
462     return [NSThread isMainThread] &&
463            ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground);
464 }
465 #endif
466
467 #if defined(SK_DEBUG) || GR_TEST_UTILS
468 bool GrMtlFormatIsBGRA8(GrMTLPixelFormat mtlFormat) {
469     return mtlFormat == MTLPixelFormatBGRA8Unorm;
470 }
471
472 const char* GrMtlFormatToStr(GrMTLPixelFormat mtlFormat) {
473     switch (mtlFormat) {
474         case MTLPixelFormatInvalid:         return "Invalid";
475         case MTLPixelFormatRGBA8Unorm:      return "RGBA8Unorm";
476         case MTLPixelFormatR8Unorm:         return "R8Unorm";
477         case MTLPixelFormatA8Unorm:         return "A8Unorm";
478         case MTLPixelFormatBGRA8Unorm:      return "BGRA8Unorm";
479 #ifdef SK_BUILD_FOR_IOS
480         case MTLPixelFormatB5G6R5Unorm:     return "B5G6R5Unorm";
481 #endif
482         case MTLPixelFormatRGBA16Float:     return "RGBA16Float";
483         case MTLPixelFormatR16Float:        return "R16Float";
484         case MTLPixelFormatRG8Unorm:        return "RG8Unorm";
485         case MTLPixelFormatRGB10A2Unorm:    return "RGB10A2Unorm";
486 #ifdef SK_BUILD_FOR_MAC
487         case MTLPixelFormatBGR10A2Unorm:    return "BGR10A2Unorm";
488 #endif
489 #ifdef SK_BUILD_FOR_IOS
490         case MTLPixelFormatABGR4Unorm:      return "ABGR4Unorm";
491 #endif
492         case MTLPixelFormatRGBA8Unorm_sRGB: return "RGBA8Unorm_sRGB";
493         case MTLPixelFormatR16Unorm:        return "R16Unorm";
494         case MTLPixelFormatRG16Unorm:       return "RG16Unorm";
495 #ifdef SK_BUILD_FOR_IOS
496         case MTLPixelFormatETC2_RGB8:       return "ETC2_RGB8";
497 #else
498         case MTLPixelFormatBC1_RGBA:        return "BC1_RGBA";
499 #endif
500         case MTLPixelFormatRGBA16Unorm:     return "RGBA16Unorm";
501         case MTLPixelFormatRG16Float:       return "RG16Float";
502         case MTLPixelFormatStencil8:        return "Stencil8";
503
504         default:                            return "Unknown";
505     }
506 }
507
508 #endif
509
510 GR_NORETAIN_END