text: /*
   * Copyright 2017 Google Inc.
   *
   * Use of this source code is governed by a BSD-style license that can be
   * found in the LICENSE file.
   */
  
  #ifndef GrMtlUtil_DEFINED
  #define GrMtlUtil_DEFINED
  
  #import <Metal/Metal.h>
  
  #include "include/gpu/GrBackendSurface.h"
  #include "include/private/GrTypesPriv.h"
  #include "src/sksl/ir/SkSLProgram.h"
  
  #if !__has_feature(objc_arc)
  #error This file must be compiled with Arc. Use -fobjc-arc flag
  #endif
  
  class GrMtlGpu;
  class GrSurface;
  
  // Apple doesn't define specific versions per se -- these are for convenience's sake
  // * Metal 1.0: iOS only
  // * Metal 1.1: Adds MacOS support, new memory model, MetalKit
  // * Metal 1.2: MTLHeap and MTLFence, tessellation
  // * Metal 2.0: MTLEvent, argument buffers, raster order groups
  #if defined(SK_BUILD_FOR_MAC)
  #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
  #define GR_METAL_SDK_VERSION 200
  #elif __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
  #define GR_METAL_SDK_VERSION 120
  #else
  #define GR_METAL_SDK_VERSION 110
  #endif
  #else
  #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000 || __TV_OS_VERSION_MAX_ALLOWED >= 120000
  #define GR_METAL_SDK_VERSION 200
  #elif __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __TV_OS_VERSION_MAX_ALLOWED >= 110000
  #define GR_METAL_SDK_VERSION 120
  #elif __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 || __TV_OS_VERSION_MAX_ALLOWED >= 100000
  #define GR_METAL_SDK_VERSION 110
  #else
  #define GR_METAL_SDK_VERSION 100
  #endif
  #endif
  
  #if GR_METAL_SDK_VERSION >= 200
  #define GR_METAL_SDK_SUPPORTS_EVENTS
  #endif
  
  /**
   * Returns the Metal texture format for the given GrPixelConfig
   */
  bool GrPixelConfigToMTLFormat(GrPixelConfig config, MTLPixelFormat* format);
  
  /**
   * Returns a id<MTLTexture> to the MTLTexture pointed at by the const void*.
   */
  SK_ALWAYS_INLINE id<MTLTexture> GrGetMTLTexture(const void* mtlTexture)  {
      return (__bridge id<MTLTexture>)mtlTexture;
  }
  
  /**
   * Returns a const void* to whatever the id object is pointing to.
   */
  SK_ALWAYS_INLINE const void* GrGetPtrFromId(id idObject) {
      return (__bridge const void*)idObject;
  }
  
  /**
   * Returns a const void* to whatever the id object is pointing to.
   * Will call CFRetain on the object.
   */
  SK_ALWAYS_INLINE const void* GrRetainPtrFromId(id idObject) {
      return (__bridge_retained const void*)idObject;
  }
  
  
  /**
   * Returns a MTLTextureDescriptor which describes the MTLTexture. Useful when creating a duplicate
   * MTLTexture without the same storage allocation.
   */
  MTLTextureDescriptor* GrGetMTLTextureDescriptor(id<MTLTexture> mtlTexture);
  
  /**
   * Returns a compiled MTLLibrary created from MSL code generated by SkSLC
   */
  id<MTLLibrary> GrCompileMtlShaderLibrary(const GrMtlGpu* gpu,
                                           const char* shaderString,
                                           SkSL::Program::Kind kind,
                                           const SkSL::Program::Settings& settings,
                                           SkSL::Program::Inputs* outInputs);
  
  /**
   * Replacement for newLibraryWithSource:options:error that has a timeout.
   */
  id<MTLLibrary> GrMtlNewLibraryWithSource(id<MTLDevice>, NSString* mslCode,
                                           MTLCompileOptions*, bool* timedout);
  
  /**
   * Replacement for newRenderPipelineStateWithDescriptor:error that has a timeout.
   */
  id<MTLRenderPipelineState> GrMtlNewRenderPipelineStateWithDescriptor(
          id<MTLDevice>, MTLRenderPipelineDescriptor*, bool* timedout);
  
  /**
   * Returns a MTLTexture corresponding to the GrSurface.
   */
  id<MTLTexture> GrGetMTLTextureFromSurface(GrSurface* surface);
  
  size_t GrMtlBytesPerFormat(MTLPixelFormat);
  
  static inline MTLPixelFormat GrBackendFormatAsMTLPixelFormat(const GrBackendFormat& format) {
      return static_cast<MTLPixelFormat>(format.asMtlFormat());
  }
  
  #endif
  