Return a ContextInfo from Graphite's ContextFactory.

Previously, the context factory would return a tuple containing
pointers; this is brittle and makes it difficult to add elements
to the return type. Now it returns a named struct containing the
same information.

Change-Id: I4f1aa636b31704028bf6fbcb048a14dbc042c372
Bug: b/40044139
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/757116
Commit-Queue: Robert Phillips <robertphillips@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index ee7f515..3046eba 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -350,12 +350,13 @@
         // context options when we make the factory here.
         this->factory = std::make_unique<ContextFactory>();
 
-        auto [testCtx, ctx] = this->factory->getContextInfo(this->config.ctxType);
-        if (!ctx) {
+        skiatest::graphite::ContextInfo ctxInfo =
+                this->factory->getContextInfo(this->config.ctxType);
+        if (!ctxInfo.fContext) {
             return false;
         }
-        this->testContext = testCtx;
-        this->context = ctx;
+        this->testContext = ctxInfo.fTestContext;
+        this->context = ctxInfo.fContext;
 
         this->recorder = this->context->makeRecorder(ToolUtils::CreateTestingRecorderOptions());
         if (!this->recorder) {
@@ -602,8 +603,9 @@
 
         using ContextFactory = skiatest::graphite::ContextFactory;
 
-        ContextFactory factory{};
-        auto [testContext, ctx] = factory.getContextInfo(graphiteCtxType);
+        ContextFactory factory;
+        skiatest::graphite::ContextInfo ctxInfo = factory.getContextInfo(graphiteCtxType);
+        skgpu::graphite::Context* ctx = ctxInfo.fContext;
         if (ctx) {
             // TODO: Add graphite ctx queries for supported sample count by color type.
 #if 0
diff --git a/dm/DMGpuTestProcs.cpp b/dm/DMGpuTestProcs.cpp
index 4146376..aba40a4 100644
--- a/dm/DMGpuTestProcs.cpp
+++ b/dm/DMGpuTestProcs.cpp
@@ -129,7 +129,8 @@
             continue;
         }
 
-        auto [_, context] = factory.getContextInfo(contextType);
+        skiatest::graphite::ContextInfo ctxInfo = factory.getContextInfo(contextType);
+        skgpu::graphite::Context* context = ctxInfo.fContext;
         if (!context) {
             continue;
         }
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 5051138..3e55dab 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -2103,7 +2103,8 @@
     SkImageInfo ii = SkImageInfo::Make(src.size(), this->colorInfo());
 
     skiatest::graphite::ContextFactory factory(options);
-    auto [_, context] = factory.getContextInfo(fContextType);
+    skiatest::graphite::ContextInfo ctxInfo = factory.getContextInfo(fContextType);
+    skgpu::graphite::Context* context = ctxInfo.fContext;
     if (!context) {
         return Result::Fatal("Could not create a context.");
     }
diff --git a/fuzz/FuzzPrecompile.cpp b/fuzz/FuzzPrecompile.cpp
index 7bc7399..e5d8804 100644
--- a/fuzz/FuzzPrecompile.cpp
+++ b/fuzz/FuzzPrecompile.cpp
@@ -409,7 +409,7 @@
 DEF_FUZZ(Precompile, fuzz) {
     skiatest::graphite::ContextFactory factory;
 
-    sk_gpu_test::GrContextFactory::ContextType contextType;
+    skgpu::ContextType contextType;
 #if defined(SK_METAL)
     contextType = skgpu::ContextType::kMetal;
 #elif defined(SK_VULKAN)
@@ -418,7 +418,8 @@
     contextType = skgpu::ContextType::kMock;
 #endif
 
-    auto [_, context] = factory.getContextInfo(contextType);
+    skiatest::graphite::ContextInfo ctxInfo = factory.getContextInfo(contextType);
+    skgpu::graphite::Context* context = ctxInfo.fContext;
     if (!context) {
         return;
     }
diff --git a/tools/graphite/ContextFactory.cpp b/tools/graphite/ContextFactory.cpp
index b975df5..077023d 100644
--- a/tools/graphite/ContextFactory.cpp
+++ b/tools/graphite/ContextFactory.cpp
@@ -21,35 +21,22 @@
 
 namespace skiatest::graphite {
 
-ContextFactory::ContextInfo::ContextInfo(ContextInfo&& other)
-    : fType(other.fType)
-    , fTestContext(std::move(other.fTestContext))
-    , fContext(std::move(other.fContext)) {
-}
-
-ContextFactory::ContextInfo::ContextInfo(skgpu::ContextType type,
-                                         std::unique_ptr<GraphiteTestContext> testContext,
-                                         std::unique_ptr<skgpu::graphite::Context> context)
-    : fType(type)
-    , fTestContext(std::move(testContext))
-    , fContext(std::move(context)) {
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
 ContextFactory::ContextFactory(const skgpu::graphite::ContextOptions& options)
         : fOptions(options) {}
 
-ContextFactory::~ContextFactory() {}
+ContextInfo ContextFactory::AsContextInfo(const OwnedContextInfo& owned) {
+    return ContextInfo{owned.fTestContext.get(), owned.fContext.get()};
+}
 
-std::tuple<GraphiteTestContext*, skgpu::graphite::Context*> ContextFactory::getContextInfo(
-        skgpu::ContextType type) {
-
-    for (ContextInfo& c : fContexts) {
-        if (c.type() == type) {
-            return { c.testContext(), c.context() };
+ContextInfo ContextFactory::getContextInfo(skgpu::ContextType type) {
+    // Look for an existing ContextInfo that we can re-use.
+    for (const OwnedContextInfo& ctxInfo : fContexts) {
+        if (ctxInfo.fType == type) {
+            return AsContextInfo(ctxInfo);
         }
     }
 
+    // Create a new ContextInfo from this context type.
     std::unique_ptr<GraphiteTestContext> testCtx;
 
     switch (type) {
@@ -94,17 +81,16 @@
     }
 
     if (!testCtx) {
-        return {};
+        return ContextInfo{};
     }
 
     std::unique_ptr<skgpu::graphite::Context> context = testCtx->makeContext(fOptions);
     if (!context) {
-        return {};
+        return ContextInfo{};
     }
 
-    fContexts.push_back({ type, std::move(testCtx), std::move(context) });
-
-    return { fContexts.back().testContext(), fContexts.back().context() };
+    fContexts.push_back({type, std::move(testCtx), std::move(context)});
+    return AsContextInfo(fContexts.back());
 }
 
 } // namespace skiatest::graphite
diff --git a/tools/graphite/ContextFactory.h b/tools/graphite/ContextFactory.h
index a0a724f..a1ab81b 100644
--- a/tools/graphite/ContextFactory.h
+++ b/tools/graphite/ContextFactory.h
@@ -8,59 +8,49 @@
 #ifndef skiatest_graphite_ContextFactory_DEFINED
 #define skiatest_graphite_ContextFactory_DEFINED
 
-#include <vector>
 #include "include/core/SkRefCnt.h"
 #include "include/gpu/graphite/ContextOptions.h"
 #include "include/gpu/graphite/GraphiteTypes.h"
+#include "include/private/base/SkTArray.h"
 #include "tools/gpu/ContextType.h"
 #include "tools/graphite/GraphiteTestContext.h"
 
 namespace skgpu::graphite {
-    class Context;
+class Context;
 }
 
 namespace skiatest::graphite {
 
+struct ContextInfo {
+    GraphiteTestContext* fTestContext = nullptr;
+    skgpu::graphite::Context* fContext = nullptr;
+};
+
 class ContextFactory {
 public:
-    class ContextInfo {
-    public:
-        ContextInfo() = default;
-        ContextInfo(ContextInfo&& other);
-        ~ContextInfo() = default;
-
-        skgpu::ContextType type() const { return fType; }
-
-        skgpu::graphite::Context* context() const { return fContext.get(); }
-        GraphiteTestContext* testContext() const { return fTestContext.get(); }
-
-    private:
-        friend class ContextFactory; // for ctor
-
-        ContextInfo(skgpu::ContextType type,
-                    std::unique_ptr<GraphiteTestContext> testContext,
-                    std::unique_ptr<skgpu::graphite::Context> context);
-
-        skgpu::ContextType fType = skgpu::ContextType::kMock;
-        std::unique_ptr<GraphiteTestContext> fTestContext;
-        std::unique_ptr<skgpu::graphite::Context> fContext;
-    };
-
     explicit ContextFactory(const skgpu::graphite::ContextOptions&);
     ContextFactory() = default;
     ContextFactory(const ContextFactory&) = delete;
     ContextFactory& operator=(const ContextFactory&) = delete;
 
-    ~ContextFactory();
+    ~ContextFactory() = default;
 
-    std::tuple<GraphiteTestContext*, skgpu::graphite::Context*> getContextInfo(
-            skgpu::ContextType);
+    ContextInfo getContextInfo(skgpu::ContextType);
 
 private:
-    std::vector<ContextInfo> fContexts;
+    struct OwnedContextInfo {
+        // This holds the same data as ContextInfo, but uses unique_ptr to maintain ownership.
+        skgpu::ContextType fType = skgpu::ContextType::kMock;
+        std::unique_ptr<GraphiteTestContext> fTestContext;
+        std::unique_ptr<skgpu::graphite::Context> fContext;
+    };
+
+    static ContextInfo AsContextInfo(const OwnedContextInfo& ctx);
+
+    skia_private::TArray<OwnedContextInfo> fContexts;
     const skgpu::graphite::ContextOptions fOptions;
 };
 
-} // namespace skiatest::graphite
+}  // namespace skiatest::graphite
 
-#endif // skiatest_graphite_ContextFactory_DEFINED
+#endif  // skiatest_graphite_ContextFactory_DEFINED