Move caps and FP factory cache to GrContext_Base

Both GrContext and GrContextThreadSafeProxy had their own copies. This centralizes ownership and standardizes how all the contexts get initialized.

Change-Id: Ib2e418fbb53fcd6b0054789ef30a5fc4a3d80b20
Reviewed-on: https://skia-review.googlesource.com/c/189305
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrBaseContextPriv.h b/src/gpu/GrBaseContextPriv.h
index 4b44d37..ab99684 100644
--- a/src/gpu/GrBaseContextPriv.h
+++ b/src/gpu/GrBaseContextPriv.h
@@ -20,6 +20,11 @@
 
     const GrContextOptions& options() const { return fContext->options(); }
 
+    const GrCaps* caps() const { return fContext->caps(); }
+    sk_sp<const GrCaps> refCaps() const { return fContext->refCaps(); }
+
+    sk_sp<GrSkSLFPFactoryCache> fpFactoryCache() { return fContext->fpFactoryCache(); }
+
 private:
     explicit GrBaseContextPriv(GrContext_Base* context) : fContext(context) {}
     GrBaseContextPriv(const GrBaseContextPriv&); // unimpl
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 382b08c..e1588ae 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -67,20 +67,24 @@
     fGlyphCache = nullptr;
 }
 
-bool GrContext::initCommon() {
+bool GrContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) {
     ASSERT_SINGLE_OWNER
-    SkASSERT(fCaps);  // needs to have been initialized by derived classes
     SkASSERT(fThreadSafeProxy); // needs to have been initialized by derived classes
 
+    if (!INHERITED::init(std::move(caps), std::move(FPFactoryCache))) {
+        return false;
+    }
+
+    SkASSERT(this->caps());
+
     if (fGpu) {
-        fCaps = fGpu->refCaps();
-        fResourceCache = new GrResourceCache(fCaps.get(), &fSingleOwner, this->contextID());
+        fResourceCache = new GrResourceCache(this->caps(), &fSingleOwner, this->contextID());
         fResourceProvider = new GrResourceProvider(fGpu.get(), fResourceCache, &fSingleOwner,
                                                    this->options().fExplicitlyAllocateGPUResources);
-        fProxyProvider =
-                new GrProxyProvider(fResourceProvider, fResourceCache, fCaps, &fSingleOwner);
+        fProxyProvider = new GrProxyProvider(fResourceProvider, fResourceCache,
+                                             this->refCaps(), &fSingleOwner);
     } else {
-        fProxyProvider = new GrProxyProvider(this->contextID(), fCaps, &fSingleOwner);
+        fProxyProvider = new GrProxyProvider(this->contextID(), this->refCaps(), &fSingleOwner);
     }
 
     if (fResourceCache) {
@@ -127,7 +131,7 @@
                                                this->options().fSortRenderTargets,
                                                this->options().fReduceOpListSplitting));
 
-    fGlyphCache = new GrStrikeCache(fCaps.get(), this->options().fGlyphCacheTextureMaximumBytes);
+    fGlyphCache = new GrStrikeCache(this->caps(), this->options().fGlyphCacheTextureMaximumBytes);
 
     fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB, this, this->contextID()));
 
@@ -268,18 +272,18 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-int GrContext::maxTextureSize() const { return fCaps->maxTextureSize(); }
+int GrContext::maxTextureSize() const { return this->caps()->maxTextureSize(); }
 
-int GrContext::maxRenderTargetSize() const { return fCaps->maxRenderTargetSize(); }
+int GrContext::maxRenderTargetSize() const { return this->caps()->maxRenderTargetSize(); }
 
 bool GrContext::colorTypeSupportedAsImage(SkColorType colorType) const {
     GrPixelConfig config = SkColorType2GrPixelConfig(colorType);
-    return fCaps->isConfigTexturable(config);
+    return this->caps()->isConfigTexturable(config);
 }
 
 int GrContext::maxSurfaceSampleCountForColorType(SkColorType colorType) const {
     GrPixelConfig config = SkColorType2GrPixelConfig(colorType);
-    return fCaps->maxRenderTargetSampleCount(config);
+    return this->caps()->maxRenderTargetSampleCount(config);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1007,7 +1011,7 @@
         if (!GrPixelConfigToColorType(config, &colorType)) {
             return nullptr;
         }
-        localFormat = fContext->fCaps->getBackendFormatFromColorType(colorType);
+        localFormat = fContext->caps()->getBackendFormatFromColorType(colorType);
     }
 
     return this->makeDeferredRenderTargetContext(localFormat, fit, width, height, config,
@@ -1061,7 +1065,9 @@
     return renderTargetContext;
 }
 
-sk_sp<GrSkSLFPFactoryCache> GrContextPriv::getFPFactoryCache() { return fContext->fFPFactoryCache; }
+sk_sp<GrSkSLFPFactoryCache> GrContextPriv::fpFactoryCache() {
+    return fContext->fpFactoryCache();
+}
 
 std::unique_ptr<GrFragmentProcessor> GrContext::createPMToUPMEffect(
         std::unique_ptr<GrFragmentProcessor> fp) {
@@ -1097,7 +1103,7 @@
 }
 
 bool GrContext::supportsDistanceFieldText() const {
-    return fCaps->shaderCaps()->supportsDistanceFieldText();
+    return this->caps()->shaderCaps()->supportsDistanceFieldText();
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1147,7 +1153,7 @@
     writer.appendString("backend", kBackendStr[(unsigned)fContext->backend()]);
 
     writer.appendName("caps");
-    fContext->fCaps->dumpJSON(&writer);
+    fContext->caps()->dumpJSON(&writer);
 
     writer.appendName("gpu");
     fContext->fGpu->dumpJSON(&writer);
diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h
index c3ccb1c..02dc7a3 100644
--- a/src/gpu/GrContextPriv.h
+++ b/src/gpu/GrContextPriv.h
@@ -34,6 +34,11 @@
 
     const GrContextOptions& options() const { return fContext->options(); }
 
+    const GrCaps* caps() const { return fContext->caps(); }
+    sk_sp<const GrCaps> refCaps() const { return fContext->refCaps(); }
+
+    sk_sp<GrSkSLFPFactoryCache> fpFactoryCache();
+
     // from GrImageContext
 
     // from GrRecordingContext
@@ -43,8 +48,6 @@
      */
     static sk_sp<GrContext> MakeDDL(const sk_sp<GrContextThreadSafeProxy>&);
 
-    const GrCaps* caps() const { return fContext->fCaps.get(); }
-
     sk_sp<GrOpMemoryPool> refOpMemoryPool();
     GrOpMemoryPool* opMemoryPool();
 
@@ -284,8 +287,6 @@
 
     GrContextOptions::PersistentCache* getPersistentCache() { return fContext->fPersistentCache; }
 
-    sk_sp<GrSkSLFPFactoryCache> getFPFactoryCache();
-
     /** This is only useful for debug purposes */
     SkDEBUGCODE(GrSingleOwner* debugSingleOwner() const { return &fContext->fSingleOwner; } )
 
diff --git a/src/gpu/GrContextThreadSafeProxy.cpp b/src/gpu/GrContextThreadSafeProxy.cpp
index bb70cf6..6540879 100644
--- a/src/gpu/GrContextThreadSafeProxy.cpp
+++ b/src/gpu/GrContextThreadSafeProxy.cpp
@@ -15,16 +15,19 @@
 #include "SkSurface_Gpu.h"
 #include "SkSurfaceCharacterization.h"
 
-GrContextThreadSafeProxy::GrContextThreadSafeProxy(sk_sp<const GrCaps> caps, uint32_t contextID,
-                                                   GrBackendApi backend,
+GrContextThreadSafeProxy::GrContextThreadSafeProxy(GrBackendApi backend,
                                                    const GrContextOptions& options,
-                                                   sk_sp<GrSkSLFPFactoryCache> cache)
-        : INHERITED(backend, options, contextID)
-        , fCaps(std::move(caps))
-        , fFPFactoryCache(std::move(cache)) {}
+                                                   uint32_t contextID)
+        : INHERITED(backend, options, contextID) {
+}
 
 GrContextThreadSafeProxy::~GrContextThreadSafeProxy() = default;
 
+bool GrContextThreadSafeProxy::init(sk_sp<const GrCaps> caps,
+                                    sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) {
+    return INHERITED::init(std::move(caps), std::move(FPFactoryCache));
+}
+
 bool GrContextThreadSafeProxy::matches(GrContext_Base* context) const {
     return context->priv().contextID() == this->contextID();
 }
@@ -44,34 +47,35 @@
         return SkSurfaceCharacterization(); // return an invalid characterization
     }
 
-    if (!fCaps->mipMapSupport()) {
+    if (!this->caps()->mipMapSupport()) {
         isMipMapped = false;
     }
 
-    GrPixelConfig config = fCaps->getConfigFromBackendFormat(backendFormat, ii.colorType());
+    GrPixelConfig config = this->caps()->getConfigFromBackendFormat(backendFormat, ii.colorType());
     if (config == kUnknown_GrPixelConfig) {
         return SkSurfaceCharacterization(); // return an invalid characterization
     }
 
-    if (!SkSurface_Gpu::Valid(fCaps.get(), config, ii.colorSpace())) {
+    if (!SkSurface_Gpu::Valid(this->caps(), config, ii.colorSpace())) {
         return SkSurfaceCharacterization(); // return an invalid characterization
     }
 
-    sampleCnt = fCaps->getRenderTargetSampleCount(sampleCnt, config);
+    sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, config);
     if (!sampleCnt) {
         return SkSurfaceCharacterization(); // return an invalid characterization
     }
 
     GrFSAAType FSAAType = GrFSAAType::kNone;
     if (sampleCnt > 1) {
-        FSAAType = fCaps->usesMixedSamples() ? GrFSAAType::kMixedSamples : GrFSAAType::kUnifiedMSAA;
+        FSAAType = this->caps()->usesMixedSamples() ? GrFSAAType::kMixedSamples
+                                                    : GrFSAAType::kUnifiedMSAA;
     }
 
     if (willUseGLFBO0 && isTextureable) {
         return SkSurfaceCharacterization(); // return an invalid characterization
     }
 
-    if (isTextureable && !fCaps->isConfigTexturable(config)) {
+    if (isTextureable && !this->caps()->isConfigTexturable(config)) {
         // Skia doesn't agree that this is textureable.
         return SkSurfaceCharacterization(); // return an invalid characterization
     }
@@ -87,6 +91,22 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-sk_sp<GrSkSLFPFactoryCache> GrContextThreadSafeProxyPriv::fpFactoryCache() const {
-    return fProxy->fFPFactoryCache;
+sk_sp<GrSkSLFPFactoryCache> GrContextThreadSafeProxyPriv::fpFactoryCache() {
+    return fProxy->fpFactoryCache();
 }
+
+sk_sp<GrContextThreadSafeProxy> GrContextThreadSafeProxyPriv::Make(
+                             GrBackendApi backend,
+                             const GrContextOptions& options,
+                             uint32_t contextID,
+                             sk_sp<const GrCaps> caps,
+                             sk_sp<GrSkSLFPFactoryCache> cache) {
+    sk_sp<GrContextThreadSafeProxy> proxy(new GrContextThreadSafeProxy(backend, options,
+                                                                       contextID));
+
+    if (!proxy->init(std::move(caps), std::move(cache))) {
+        return nullptr;
+    }
+    return proxy;
+}
+
diff --git a/src/gpu/GrContextThreadSafeProxyPriv.h b/src/gpu/GrContextThreadSafeProxyPriv.h
index 63920aa..d23e55a 100644
--- a/src/gpu/GrContextThreadSafeProxyPriv.h
+++ b/src/gpu/GrContextThreadSafeProxyPriv.h
@@ -22,11 +22,17 @@
 
     const GrContextOptions& options() const { return fProxy->options(); }
 
-    //
-    const GrCaps* caps() const { return fProxy->fCaps.get(); }
-    sk_sp<const GrCaps> refCaps() const { return fProxy->fCaps; }
+    const GrCaps* caps() const { return fProxy->caps(); }
+    sk_sp<const GrCaps> refCaps() const { return fProxy->refCaps(); }
 
-    sk_sp<GrSkSLFPFactoryCache> fpFactoryCache() const;
+    sk_sp<GrSkSLFPFactoryCache> fpFactoryCache();
+
+    // GrContextThreadSafeProxyPriv
+    static sk_sp<GrContextThreadSafeProxy> Make(GrBackendApi,
+                                                const GrContextOptions&,
+                                                uint32_t contextID,
+                                                sk_sp<const GrCaps>,
+                                                sk_sp<GrSkSLFPFactoryCache>);
 
 private:
     explicit GrContextThreadSafeProxyPriv(GrContextThreadSafeProxy* proxy) : fProxy(proxy) {}
diff --git a/src/gpu/GrContext_Base.cpp b/src/gpu/GrContext_Base.cpp
index 684f0b6..7f71df5 100644
--- a/src/gpu/GrContext_Base.cpp
+++ b/src/gpu/GrContext_Base.cpp
@@ -7,6 +7,9 @@
 
 #include "GrContext_Base.h"
 
+#include "GrCaps.h"
+#include "GrSkSLFPFactoryCache.h"
+
 static int32_t next_id() {
     static std::atomic<int32_t> nextID{1};
     int32_t id;
@@ -26,4 +29,16 @@
 
 GrContext_Base::~GrContext_Base() { }
 
+const GrCaps* GrContext_Base::caps() const { return fCaps.get(); }
+sk_sp<const GrCaps> GrContext_Base::refCaps() const { return fCaps; }
+
+sk_sp<GrSkSLFPFactoryCache> GrContext_Base::fpFactoryCache() { return fFPFactoryCache; }
+
+bool GrContext_Base::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) {
+    SkASSERT(caps && FPFactoryCache);
+
+    fCaps = caps;
+    fFPFactoryCache = FPFactoryCache;
+    return true;
+}
 
diff --git a/src/gpu/GrDDLContext.cpp b/src/gpu/GrDDLContext.cpp
index 462c48b..6b72e4e 100644
--- a/src/gpu/GrDDLContext.cpp
+++ b/src/gpu/GrDDLContext.cpp
@@ -19,9 +19,6 @@
 public:
     GrDDLContext(sk_sp<GrContextThreadSafeProxy> proxy)
             : INHERITED(proxy->backend(), proxy->priv().options(), proxy->priv().contextID()) {
-        fCaps = proxy->priv().refCaps();
-        fFPFactoryCache = proxy->priv().fpFactoryCache();
-        SkASSERT(fFPFactoryCache);
         fThreadSafeProxy = std::move(proxy);
     }
 
@@ -43,14 +40,16 @@
     }
 
 protected:
-    bool init() override {
-        SkASSERT(fCaps);  // should've been set in ctor
+    bool init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) override {
+        SkASSERT(caps && FPFactoryCache);
         SkASSERT(fThreadSafeProxy); // should've been set in the ctor
 
-        if (!INHERITED::initCommon()) {
+        if (!INHERITED::init(std::move(caps), std::move(FPFactoryCache))) {
             return false;
         }
 
+        SkASSERT(this->caps());
+
         return true;
     }
 
@@ -66,9 +65,7 @@
 sk_sp<GrContext> GrContextPriv::MakeDDL(const sk_sp<GrContextThreadSafeProxy>& proxy) {
     sk_sp<GrContext> context(new GrDDLContext(proxy));
 
-    // Note: we aren't creating a Gpu here. This causes the resource provider & cache to
-    // also not be created
-    if (!context->init()) {
+    if (!context->init(proxy->priv().refCaps(), proxy->priv().fpFactoryCache())) {
         return nullptr;
     }
     return context;
diff --git a/src/gpu/GrDirectContext.cpp b/src/gpu/GrDirectContext.cpp
index 9fdb3b8..fb2adf6 100644
--- a/src/gpu/GrDirectContext.cpp
+++ b/src/gpu/GrDirectContext.cpp
@@ -10,6 +10,7 @@
 
 #include "GrContextPriv.h"
 #include "GrContextThreadSafeProxy.h"
+#include "GrContextThreadSafeProxyPriv.h"
 #include "GrGpu.h"
 
 #include "effects/GrSkSLFP.h"
@@ -58,23 +59,27 @@
     }
 
 protected:
-    bool init() override {
-        SkASSERT(fCaps);  // should've been set in ctor
+    bool init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) override {
+        SkASSERT(caps && !FPFactoryCache);
         SkASSERT(!fThreadSafeProxy);
-        SkASSERT(!fFPFactoryCache);
-        fFPFactoryCache.reset(new GrSkSLFPFactoryCache());
-        fThreadSafeProxy.reset(new GrContextThreadSafeProxy(fCaps, this->contextID(),
-                                                            this->backend(),
-                                                            this->options(), fFPFactoryCache));
 
-        if (!INHERITED::initCommon()) {
+        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
-            !(fCaps->shaderCaps()->floatIs32Bits() || fCaps->shaderCaps()->integerSupport())) {
+            !(this->caps()->shaderCaps()->floatIs32Bits() ||
+              this->caps()->shaderCaps()->integerSupport())) {
             allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo;
         } else {
             allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
@@ -122,8 +127,7 @@
         return nullptr;
     }
 
-    context->fCaps = context->fGpu->refCaps();
-    if (!context->init()) {
+    if (!context->init(context->fGpu->refCaps(), nullptr)) {
         return nullptr;
     }
     return context;
@@ -143,8 +147,7 @@
         return nullptr;
     }
 
-    context->fCaps = context->fGpu->refCaps();
-    if (!context->init()) {
+    if (!context->init(context->fGpu->refCaps(), nullptr)) {
         return nullptr;
     }
     return context;
@@ -170,8 +173,7 @@
         return nullptr;
     }
 
-    context->fCaps = context->fGpu->refCaps();
-    if (!context->init()) {
+    if (!context->init(context->fGpu->refCaps(), nullptr)) {
         return nullptr;
     }
     return context;
@@ -194,8 +196,7 @@
         return nullptr;
     }
 
-    context->fCaps = context->fGpu->refCaps();
-    if (!context->init()) {
+    if (!context->init(context->fGpu->refCaps(), nullptr)) {
         return nullptr;
     }
     return context;
diff --git a/src/gpu/GrImageContextPriv.h b/src/gpu/GrImageContextPriv.h
index 3247f10..7bbfc28 100644
--- a/src/gpu/GrImageContextPriv.h
+++ b/src/gpu/GrImageContextPriv.h
@@ -20,6 +20,11 @@
 
     const GrContextOptions& options() const { return fContext->options(); }
 
+    const GrCaps* caps() const { return fContext->caps(); }
+    sk_sp<const GrCaps> refCaps() const { return fContext->refCaps(); }
+
+    sk_sp<GrSkSLFPFactoryCache> fpFactoryCache() { return fContext->fpFactoryCache(); }
+
     // from GrImageContext
 
 private:
diff --git a/src/gpu/GrRecordingContextPriv.h b/src/gpu/GrRecordingContextPriv.h
index c5b27bc..e4cd3c4 100644
--- a/src/gpu/GrRecordingContextPriv.h
+++ b/src/gpu/GrRecordingContextPriv.h
@@ -20,6 +20,11 @@
 
     const GrContextOptions& options() const { return fContext->options(); }
 
+    const GrCaps* caps() const { return fContext->caps(); }
+    sk_sp<const GrCaps> refCaps() const { return fContext->refCaps(); }
+
+    sk_sp<GrSkSLFPFactoryCache> fpFactoryCache(); // { return fContext->getFPFactoryCache(); }
+
     // from GrImageContext
 
     // from GrRecordingContext
diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp
index 7463c28..3b2b43c 100644
--- a/src/gpu/effects/GrSkSLFP.cpp
+++ b/src/gpu/effects/GrSkSLFP.cpp
@@ -234,7 +234,7 @@
 std::unique_ptr<GrSkSLFP> GrSkSLFP::Make(GrContext* context, int index, const char* name,
                                          const char* sksl, const void* inputs,
                                          size_t inputSize) {
-    return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->priv().getFPFactoryCache(),
+    return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->priv().fpFactoryCache(),
                                                   context->priv().caps()->shaderCaps(),
                                                   index, name, sksl, inputs, inputSize));
 }