Make room for shifting GrContext to GrDirectContext

Change-Id: I6291b0c513c641c3bb49260031b501da42b11ede
Reviewed-on: https://skia-review.googlesource.com/c/190002
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrLegacyDirectContext.cpp b/src/gpu/GrLegacyDirectContext.cpp
new file mode 100644
index 0000000..490b62b
--- /dev/null
+++ b/src/gpu/GrLegacyDirectContext.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "GrContext.h"
+
+#include "GrContextPriv.h"
+#include "GrContextThreadSafeProxy.h"
+#include "GrContextThreadSafeProxyPriv.h"
+#include "GrGpu.h"
+
+#include "effects/GrSkSLFP.h"
+#include "gl/GrGLGpu.h"
+#include "mock/GrMockGpu.h"
+#include "text/GrStrikeCache.h"
+#ifdef SK_METAL
+#include "mtl/GrMtlTrampoline.h"
+#endif
+#ifdef SK_VULKAN
+#include "vk/GrVkGpu.h"
+#endif
+
+class SK_API GrLegacyDirectContext : public GrContext {
+public:
+    GrLegacyDirectContext(GrBackendApi backend, const GrContextOptions& options)
+            : INHERITED(backend, options)
+            , fAtlasManager(nullptr) {
+    }
+
+    ~GrLegacyDirectContext() override {
+        // this if-test protects against the case where the context is being destroyed
+        // before having been fully created
+        if (this->priv().getGpu()) {
+            this->flush();
+        }
+
+        delete fAtlasManager;
+    }
+
+    void abandonContext() override {
+        INHERITED::abandonContext();
+        fAtlasManager->freeAll();
+    }
+
+    void releaseResourcesAndAbandonContext() override {
+        INHERITED::releaseResourcesAndAbandonContext();
+        fAtlasManager->freeAll();
+    }
+
+    void freeGpuResources() override {
+        this->flush();
+        fAtlasManager->freeAll();
+
+        INHERITED::freeGpuResources();
+    }
+
+protected:
+    bool init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) override {
+        SkASSERT(caps && !FPFactoryCache);
+        SkASSERT(!fThreadSafeProxy);
+
+        FPFactoryCache.reset(new GrSkSLFPFactoryCache());
+        fThreadSafeProxy = GrContextThreadSafeProxyPriv::Make(this->backend(),
+                                                              this->options(),
+                                                              this->contextID(),
+                                                              caps, FPFactoryCache);
+
+        if (!INHERITED::init(std::move(caps), std::move(FPFactoryCache))) {
+            return false;
+        }
+
+        SkASSERT(this->caps());
+
+        GrDrawOpAtlas::AllowMultitexturing allowMultitexturing;
+        if (GrContextOptions::Enable::kNo == this->options().fAllowMultipleGlyphCacheTextures ||
+            // multitexturing supported only if range can represent the index + texcoords fully
+            !(this->caps()->shaderCaps()->floatIs32Bits() ||
+              this->caps()->shaderCaps()->integerSupport())) {
+            allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo;
+        } else {
+            allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
+        }
+
+        GrStrikeCache* glyphCache = this->priv().getGlyphCache();
+        GrProxyProvider* proxyProvider = this->priv().proxyProvider();
+
+        fAtlasManager = new GrAtlasManager(proxyProvider, glyphCache,
+                                           this->options().fGlyphCacheTextureMaximumBytes,
+                                           allowMultitexturing);
+        this->priv().addOnFlushCallbackObject(fAtlasManager);
+
+        return true;
+    }
+
+    GrAtlasManager* onGetAtlasManager() override { return fAtlasManager; }
+
+private:
+    GrAtlasManager* fAtlasManager;
+
+    typedef GrContext INHERITED;
+};
+
+sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> interface) {
+    GrContextOptions defaultOptions;
+    return MakeGL(std::move(interface), defaultOptions);
+}
+
+sk_sp<GrContext> GrContext::MakeGL(const GrContextOptions& options) {
+    return MakeGL(nullptr, options);
+}
+
+sk_sp<GrContext> GrContext::MakeGL() {
+    GrContextOptions defaultOptions;
+    return MakeGL(nullptr, defaultOptions);
+}
+
+sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> interface,
+                                   const GrContextOptions& options) {
+    sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kOpenGL, options));
+
+    context->fGpu = GrGLGpu::Make(std::move(interface), options, context.get());
+    if (!context->fGpu) {
+        return nullptr;
+    }
+
+    if (!context->init(context->fGpu->refCaps(), nullptr)) {
+        return nullptr;
+    }
+    return context;
+}
+
+sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions) {
+    GrContextOptions defaultOptions;
+    return MakeMock(mockOptions, defaultOptions);
+}
+
+sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions,
+                                     const GrContextOptions& options) {
+    sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kMock, options));
+
+    context->fGpu = GrMockGpu::Make(mockOptions, options, context.get());
+    if (!context->fGpu) {
+        return nullptr;
+    }
+
+    if (!context->init(context->fGpu->refCaps(), nullptr)) {
+        return nullptr;
+    }
+    return context;
+}
+
+sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext) {
+#ifdef SK_VULKAN
+    GrContextOptions defaultOptions;
+    return MakeVulkan(backendContext, defaultOptions);
+#else
+    return nullptr;
+#endif
+}
+
+sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext,
+                                       const GrContextOptions& options) {
+#ifdef SK_VULKAN
+    GrContextOptions defaultOptions;
+    sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kVulkan, options));
+
+    context->fGpu = GrVkGpu::Make(backendContext, options, context.get());
+    if (!context->fGpu) {
+        return nullptr;
+    }
+
+    if (!context->init(context->fGpu->refCaps(), nullptr)) {
+        return nullptr;
+    }
+    return context;
+#else
+    return nullptr;
+#endif
+}
+
+#ifdef SK_METAL
+sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue) {
+    GrContextOptions defaultOptions;
+    return MakeMetal(device, queue, defaultOptions);
+}
+
+sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue, const GrContextOptions& options) {
+    sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kMetal, options));
+
+    context->fGpu = GrMtlTrampoline::MakeGpu(context.get(), options, device, queue);
+    if (!context->fGpu) {
+        return nullptr;
+    }
+
+    if (!context->init(context->fGpu->refCaps(), nullptr)) {
+        return nullptr;
+    }
+    return context;
+}
+#endif
+