xref: /aosp_15_r20/external/skia/tools/graphite/ContextFactory.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2021 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "tools/graphite/ContextFactory.h"
9 
10 #include "include/gpu/graphite/Context.h"
11 #include "src/gpu/graphite/Caps.h"
12 #include "src/gpu/graphite/ContextPriv.h"
13 
14 #ifdef SK_DAWN
15 #include "tools/graphite/dawn/GraphiteDawnTestContext.h"
16 #endif
17 #ifdef SK_METAL
18 #include "tools/graphite/mtl/GraphiteMtlTestContext.h"
19 #endif
20 #ifdef SK_VULKAN
21 #include "tools/graphite/vk/GraphiteVulkanTestContext.h"
22 #endif
23 
24 namespace skiatest::graphite {
25 
26 ContextFactory::OwnedContextInfo::OwnedContextInfo() = default;
27 
OwnedContextInfo(skgpu::ContextType type,std::unique_ptr<GraphiteTestContext> testContext,std::unique_ptr<skgpu::graphite::Context> context)28 ContextFactory::OwnedContextInfo::OwnedContextInfo(
29         skgpu::ContextType type,
30         std::unique_ptr<GraphiteTestContext> testContext,
31         std::unique_ptr<skgpu::graphite::Context> context)
32         : fType(type), fTestContext(std::move(testContext)), fContext(std::move(context)) {}
33 
~OwnedContextInfo()34 ContextFactory::OwnedContextInfo::~OwnedContextInfo() {
35     // If we created a non-syncing Context then we have to wait for GPU work to finish before
36     // destroying the Context.
37     if (fContext && !fContext->priv().caps()->allowCpuSync() && fContext->hasUnfinishedGpuWork()) {
38         fTestContext->syncedSubmit(fContext.get());
39         SkASSERT(!fContext->hasUnfinishedGpuWork());
40     }
41 }
42 
43 ContextFactory::OwnedContextInfo::OwnedContextInfo(OwnedContextInfo&&) = default;
44 ContextFactory::OwnedContextInfo& ContextFactory::OwnedContextInfo::operator=(OwnedContextInfo&&) =
45         default;
46 
ContextFactory(const TestOptions & options)47 ContextFactory::ContextFactory(const TestOptions& options)
48         : fOptions(options) {}
49 
AsContextInfo(const OwnedContextInfo & owned)50 ContextInfo ContextFactory::AsContextInfo(const OwnedContextInfo& owned) {
51     return ContextInfo{owned.fTestContext.get(), owned.fContext.get()};
52 }
53 
getContextInfo(skgpu::ContextType type)54 ContextInfo ContextFactory::getContextInfo(skgpu::ContextType type) {
55     if (!skgpu::IsDawnBackend(type) && fOptions.hasDawnOptions()) {
56         return {};
57     }
58 
59     // Look for an existing ContextInfo that we can re-use.
60     for (const OwnedContextInfo& ctxInfo : fContexts) {
61         if (ctxInfo.fType == type) {
62             return AsContextInfo(ctxInfo);
63         }
64     }
65 
66     // Create a new ContextInfo from this context type.
67     std::unique_ptr<GraphiteTestContext> testCtx;
68 
69     switch (type) {
70         case skgpu::ContextType::kMetal: {
71 #ifdef SK_METAL
72             testCtx = graphite::MtlTestContext::Make();
73 #endif
74         } break;
75         case skgpu::ContextType::kVulkan: {
76 #ifdef SK_VULKAN
77             testCtx = graphite::VulkanTestContext::Make();
78 #endif
79         } break;
80 #ifdef SK_DAWN
81 
82 #define CASE(TYPE)                                                                               \
83     case skgpu::ContextType::kDawn_##TYPE:                                                       \
84         testCtx = graphite::DawnTestContext::Make(wgpu::BackendType::TYPE, fOptions.fUseTintIR); \
85         break;
86 #else
87 #define CASE(TYPE)                         \
88     case skgpu::ContextType::kDawn_##TYPE: \
89         break;
90 #endif // SK_DAWN
91         CASE(D3D11)
92         CASE(D3D12)
93         CASE(Metal)
94         CASE(Vulkan)
95         CASE(OpenGL)
96         CASE(OpenGLES)
97 #undef CASE
98 
99         default:
100             break;
101     }
102 
103     if (!testCtx) {
104         return ContextInfo{};
105     }
106 
107     std::unique_ptr<skgpu::graphite::Context> context = testCtx->makeContext(fOptions);
108     if (!context) {
109         return ContextInfo{};
110     }
111 
112     fContexts.push_back({type, std::move(testCtx), std::move(context)});
113     return AsContextInfo(fContexts.back());
114 }
115 
116 } // namespace skiatest::graphite
117