| /* | |
| * Copyright 2021 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "tools/graphite/ContextFactory.h" | |
| #include "include/gpu/graphite/Context.h" | |
| #include "src/gpu/graphite/Caps.h" | |
| #include "src/gpu/graphite/ContextPriv.h" | |
| #ifdef SK_DAWN | |
| #include "tools/graphite/dawn/GraphiteDawnTestContext.h" | |
| #endif | |
| #ifdef SK_METAL | |
| #include "tools/graphite/mtl/GraphiteMtlTestContext.h" | |
| #endif | |
| #ifdef SK_VULKAN | |
| #include "tools/graphite/vk/GraphiteVulkanTestContext.h" | |
| #endif | |
| bool gGraphiteAvoidDepth = false; | |
| namespace skiatest::graphite { | |
| ContextFactory::OwnedContextInfo::OwnedContextInfo() = default; | |
| ContextFactory::OwnedContextInfo::OwnedContextInfo( | |
| 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::OwnedContextInfo::~OwnedContextInfo() { | |
| // If we created a non-syncing Context then we have to wait for GPU work to finish before | |
| // destroying the Context. | |
| if (fContext && !fContext->priv().caps()->allowCpuSync() && fContext->hasUnfinishedGpuWork()) { | |
| fTestContext->syncedSubmit(fContext.get()); | |
| SkASSERT(!fContext->hasUnfinishedGpuWork()); | |
| } | |
| } | |
| ContextFactory::OwnedContextInfo::OwnedContextInfo(OwnedContextInfo&&) = default; | |
| ContextFactory::OwnedContextInfo& ContextFactory::OwnedContextInfo::operator=(OwnedContextInfo&&) = | |
| default; | |
| ContextFactory::ContextFactory(const TestOptions& options) | |
| : fOptions(options) {} | |
| ContextInfo ContextFactory::AsContextInfo(const OwnedContextInfo& owned) { | |
| return ContextInfo{owned.fTestContext.get(), owned.fContext.get()}; | |
| } | |
| ContextInfo ContextFactory::getContextInfo(skgpu::ContextType type) { | |
| if (!skgpu::IsDawnBackend(type) && fOptions.hasDawnOptions()) { | |
| return {}; | |
| } | |
| // 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) { | |
| case skgpu::ContextType::kMetal: { | |
| #ifdef SK_METAL | |
| testCtx = graphite::MtlTestContext::Make(); | |
| #endif | |
| } break; | |
| case skgpu::ContextType::kVulkan: { | |
| #ifdef SK_VULKAN | |
| testCtx = graphite::VulkanTestContext::Make(); | |
| #endif | |
| } break; | |
| #ifdef SK_DAWN | |
| #define CASE(TYPE) \ | |
| case skgpu::ContextType::kDawn_##TYPE: \ | |
| testCtx = graphite::DawnTestContext::Make(wgpu::BackendType::TYPE); \ | |
| break; | |
| #else | |
| #define CASE(TYPE) \ | |
| case skgpu::ContextType::kDawn_##TYPE: \ | |
| break; | |
| #endif // SK_DAWN | |
| CASE(D3D11) | |
| CASE(D3D12) | |
| CASE(Metal) | |
| CASE(Vulkan) | |
| CASE(OpenGL) | |
| CASE(OpenGLES) | |
| #undef CASE | |
| default: | |
| break; | |
| } | |
| if (!testCtx) { | |
| return ContextInfo{}; | |
| } | |
| std::unique_ptr<skgpu::graphite::Context> context = testCtx->makeContext(fOptions); | |
| if (!context) { | |
| return ContextInfo{}; | |
| } | |
| fContexts.push_back({type, std::move(testCtx), std::move(context)}); | |
| return AsContextInfo(fContexts.back()); | |
| } | |
| } // namespace skiatest::graphite |