Add basic metal build files for backend

Bug: skia:
Change-Id: Iddeeb91b378bdb61d200070d8faa3610299ab733
Reviewed-on: https://skia-review.googlesource.com/21533
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 463e0b5..f5d1dd6 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -30,6 +30,7 @@
   skia_use_mesa = false
   skia_use_piex = !is_win
   skia_use_zlib = true
+  skia_use_metal = false
 
   skia_android_serial = ""
   skia_enable_android_framework_defines = false
@@ -96,6 +97,9 @@
 if (skia_use_vulkan) {
   skia_public_includes += [ "include/gpu/vk" ]
 }
+if (skia_use_metal) {
+  skia_public_includes += [ "include/gpu/mtl" ]
+}
 
 # Skia public API, generally provided by :skia.
 config("skia_public") {
@@ -528,6 +532,12 @@
     deps += [ "//third_party/spirv-tools" ]
     public_defines += [ "SK_ENABLE_SPIRV_VALIDATION" ]
   }
+
+  if (skia_use_metal) {
+    public_defines += [ "SK_METAL" ]
+    sources += skia_metal_sources
+    libs += [ "Metal.framework" ]
+  }
 }
 
 optional("jpeg") {
diff --git a/gn/gpu.gni b/gn/gpu.gni
index e4ffe2f..622d8d1 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -559,6 +559,13 @@
   "$_src/gpu/vk/GrVkVertexBuffer.h",
 ]
 
+skia_metal_sources = [
+  "$_src/gpu/mtl/GrMtlGpu.h",
+  "$_src/gpu/mtl/GrMtlGpu.mm",
+  "$_src/gpu/mtl/GrMtlTrampoline.h",
+  "$_src/gpu/mtl/GrMtlTrampoline.mm",
+]
+
 skia_native_gpu_sources = [
   "$_src/gpu/gl/GrGLDefaultInterface_native.cpp",
   "$_src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp",
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index a14a8ea..2175d92 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -185,6 +185,7 @@
  * Possible 3D APIs that may be used by Ganesh.
  */
 enum GrBackend {
+    kMetal_GrBackend,
     kOpenGL_GrBackend,
     kVulkan_GrBackend,
     kMock_GrBackend,
diff --git a/src/gpu/GrGpuFactory.cpp b/src/gpu/GrGpuFactory.cpp
index 1fc19c1..7cfec4a 100644
--- a/src/gpu/GrGpuFactory.cpp
+++ b/src/gpu/GrGpuFactory.cpp
@@ -12,6 +12,9 @@
 #ifdef SK_VULKAN
 #include "vk/GrVkGpu.h"
 #endif
+#ifdef SK_METAL
+#include "mtl/GrMtlTrampoline.h"
+#endif
 
 GrGpu* GrGpu::Create(GrBackend backend,
                      GrBackendContext backendContext,
@@ -24,6 +27,10 @@
         case kVulkan_GrBackend:
             return GrVkGpu::Create(backendContext, options, context);
 #endif
+#ifdef SK_METAL
+        case kMetal_GrBackend:
+            return GrMtlTrampoline::CreateGpu(backendContext, options, context);
+#endif
         case kMock_GrBackend:
             return GrMockGpu::Create(backendContext, options, context);
         default:
diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h
new file mode 100644
index 0000000..dd565ae
--- /dev/null
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -0,0 +1,154 @@
+/*
+ * 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 GrMtlGpu_DEFINED
+#define GrMtlGpu_DEFINED
+
+#include "GrGpu.h"
+#include "GrRenderTarget.h"
+#include "GrSemaphore.h"
+#include "GrTexture.h"
+
+#import <Metal/Metal.h>
+
+class GrSemaphore;
+
+class GrMtlGpu : public GrGpu {
+public:
+    static GrGpu* Create(GrBackendContext backendContext, const GrContextOptions& options,
+                         GrContext* context);
+
+    ~GrMtlGpu() override {}
+
+    bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
+                             GrPixelConfig readConfig, DrawPreference*,
+                             ReadPixelTempDrawInfo*) override { return false; }
+
+    bool onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
+                              GrPixelConfig srcConfig, DrawPreference*,
+                              WritePixelTempDrawInfo*) override { return false; }
+
+    bool onCopySurface(GrSurface* dst,
+                       GrSurface* src,
+                       const SkIRect& srcRect,
+                       const SkIPoint& dstPoint) override { return false; }
+
+    void onQueryMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings&,
+                                 int* effectiveSampleCnt, SamplePattern*) override {}
+
+    GrGpuCommandBuffer* createCommandBuffer(const GrGpuCommandBuffer::LoadAndStoreInfo&,
+                                            const GrGpuCommandBuffer::LoadAndStoreInfo&) override {
+        return nullptr;
+    }
+
+    GrFence SK_WARN_UNUSED_RESULT insertFence() override { return 0; }
+    bool waitFence(GrFence, uint64_t) override { return true; }
+    void deleteFence(GrFence) const override {}
+
+    sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override {
+        return nullptr;
+    }
+    sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+                                            GrWrapOwnership ownership) override { return nullptr; }
+    void insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override {}
+    void waitSemaphore(sk_sp<GrSemaphore> semaphore) override {}
+    sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override { return nullptr; }
+
+private:
+    GrMtlGpu(GrContext* context, const GrContextOptions& options) : INHERITED(context) {
+        id<MTLDevice> device = MTLCreateSystemDefaultDevice();
+
+        MTLTextureDescriptor* txDesc = [[MTLTextureDescriptor alloc] init];
+        txDesc.textureType = MTLTextureType3D;
+        txDesc.height = 64;
+        txDesc.width = 64;
+        txDesc.depth = 64;
+        txDesc.pixelFormat = MTLPixelFormatBGRA8Unorm;
+        txDesc.arrayLength = 1;
+        txDesc.mipmapLevelCount = 1;
+        fTestHeaderTexture = [device newTextureWithDescriptor:txDesc];
+    }
+
+    void onResetContext(uint32_t resetBits) override {}
+
+    void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
+
+    sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
+                                     const SkTArray<GrMipLevel>& texels) override {
+        return nullptr;
+    }
+
+    sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&,
+                                          GrSurfaceOrigin,
+                                          GrBackendTextureFlags,
+                                          int sampleCnt,
+                                          GrWrapOwnership) override {
+        return nullptr;
+    }
+
+    sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&,
+                                                    GrSurfaceOrigin) override {
+        return nullptr;
+    }
+
+    sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&,
+                                                             GrSurfaceOrigin,
+                                                             int sampleCnt) override {
+        return nullptr;
+    }
+
+    GrBuffer* onCreateBuffer(size_t, GrBufferType, GrAccessPattern, const void*) override {
+        return nullptr;
+    }
+
+    gr_instanced::InstancedRendering* onCreateInstancedRendering() override { return nullptr; }
+
+    bool onReadPixels(GrSurface* surface,
+                      int left, int top, int width, int height,
+                      GrPixelConfig,
+                      void* buffer,
+                      size_t rowBytes) override {
+        return false;
+    }
+
+    bool onWritePixels(GrSurface* surface,
+                       int left, int top, int width, int height,
+                       GrPixelConfig config, const SkTArray<GrMipLevel>& texels) override {
+        return false;
+    }
+
+    bool onTransferPixels(GrTexture* texture,
+                          int left, int top, int width, int height,
+                          GrPixelConfig config, GrBuffer* transferBuffer,
+                          size_t offset, size_t rowBytes) override {
+        return false;
+    }
+
+    void onResolveRenderTarget(GrRenderTarget* target) override { return; }
+
+    GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget*,
+                                                                int width,
+                                                                int height) override {
+        return nullptr;
+    }
+
+    void clearStencil(GrRenderTarget* target) override  {}
+
+    GrBackendObject createTestingOnlyBackendTexture(void* pixels, int w, int h,
+                                                    GrPixelConfig config, bool isRT) override {
+        return 0;
+    }
+    bool isTestingOnlyBackendTexture(GrBackendObject ) const override { return false; }
+    void deleteTestingOnlyBackendTexture(GrBackendObject, bool abandonTexture) override {}
+
+    id<MTLTexture> fTestHeaderTexture;
+
+    typedef GrGpu INHERITED;
+};
+
+#endif
+
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
new file mode 100644
index 0000000..c19dcdf
--- /dev/null
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrMtlGpu.h"
+
+GrGpu* GrMtlGpu::Create(GrBackendContext backendContext, const GrContextOptions& options,
+                        GrContext* context) {
+    return nullptr;
+}
+
diff --git a/src/gpu/mtl/GrMtlTrampoline.h b/src/gpu/mtl/GrMtlTrampoline.h
new file mode 100644
index 0000000..acce98c
--- /dev/null
+++ b/src/gpu/mtl/GrMtlTrampoline.h
@@ -0,0 +1,28 @@
+/*
+ * 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 GrMtlTrampoline_DEFINED
+#define GrMtlTrampoline_DEFINED
+
+#include "GrTypes.h"
+
+class GrContext;
+class GrGpu;
+struct GrContextOptions;
+
+/*
+ * This class is used to hold functions which trampoline from the Ganesh cpp code to the GrMtl
+ * objective-c files.
+ */
+class GrMtlTrampoline {
+public:
+    static GrGpu* CreateGpu(GrBackendContext backendContext, const GrContextOptions& options,
+                            GrContext* context);
+};
+
+#endif
+
diff --git a/src/gpu/mtl/GrMtlTrampoline.mm b/src/gpu/mtl/GrMtlTrampoline.mm
new file mode 100644
index 0000000..ea91ebb
--- /dev/null
+++ b/src/gpu/mtl/GrMtlTrampoline.mm
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrMtlTrampoline.h"
+
+#include "GrMtlGpu.h"
+
+GrGpu* GrMtlTrampoline::CreateGpu(GrBackendContext backendContext,
+                                  const GrContextOptions& options,
+                                  GrContext* context) {
+    return GrMtlGpu::Create(backendContext, options, context);
+}
+