| /* |
| * Copyright 2023 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "include/core/SkColorSpace.h" |
| #include "include/gpu/GrContextOptions.h" |
| #include "include/gpu/ganesh/SkSurfaceGanesh.h" |
| #include "tools/gpu/BackendSurfaceFactory.h" |
| #include "tools/gpu/GrContextFactory.h" |
| #include "tools/testrunners/common/surface_manager/SurfaceManager.h" |
| |
| #include <string> |
| |
| class GaneshVulkanSurfaceManager : public SurfaceManager { |
| public: |
| GaneshVulkanSurfaceManager(std::unique_ptr<sk_gpu_test::GrContextFactory> contextFactory, |
| sk_gpu_test::ContextInfo contextInfo, |
| GrDirectContext* context, |
| sk_sp<SkSurface> surface, |
| std::string config, |
| SkColorInfo colorInfo) |
| : SurfaceManager(config, colorInfo, CpuOrGpu::kGPU) |
| , fContextFactory(std::move(contextFactory)) |
| , fContextInfo(contextInfo) |
| , fContext(context) |
| , fSurface(surface) {} |
| |
| sk_sp<SkSurface> getSurface() override { return fSurface; } |
| |
| void flush() override { fContext->flushAndSubmit(fSurface.get(), GrSyncCpu::kYes); } |
| |
| sk_gpu_test::ContextInfo* getGaneshContextInfo() override { return &fContextInfo; } |
| |
| private: |
| // The Vulkan context is destroyed when the context factory is destroyed. We prevent early |
| // destruction of the context by grabbing a reference to the context factory. See the |
| // GrContextFactory class documentation for details. |
| std::unique_ptr<sk_gpu_test::GrContextFactory> fContextFactory; |
| sk_gpu_test::ContextInfo fContextInfo; |
| GrDirectContext* fContext; |
| sk_sp<SkSurface> fSurface; |
| }; |
| |
| enum class SurfaceType { kDefault, kBackendTexture, kBackendRenderTarget }; |
| |
| std::unique_ptr<SurfaceManager> makeVulkanSurfaceManager( |
| std::string config, |
| SurfaceOptions surfaceOptions, |
| GrContextOptions grContextOptions, |
| sk_gpu_test::GrContextFactory::ContextOverrides contextOverrides, |
| SkColorInfo colorInfo, |
| SurfaceType surfaceType, |
| uint32_t surfaceFlags, |
| int sampleCount) { |
| if (surfaceOptions.modifyGrContextOptions) { |
| surfaceOptions.modifyGrContextOptions(&grContextOptions); |
| } |
| |
| // Based on |
| // https://skia.googlesource.com/skia/+/8da85ea79d1ba2b3f32d25178eb21f2ebda83437/dm/DMSrcSink.cpp#1579. |
| auto contextFactory = std::make_unique<sk_gpu_test::GrContextFactory>(grContextOptions); |
| sk_gpu_test::ContextInfo contextInfo = |
| contextFactory.get()->getContextInfo(skgpu::ContextType::kVulkan, contextOverrides); |
| GrDirectContext* context = contextInfo.directContext(); |
| SkASSERT_RELEASE(context); |
| |
| // Based on |
| // https://skia.googlesource.com/skia/+/8da85ea79d1ba2b3f32d25178eb21f2ebda83437/dm/DMSrcSink.cpp#1524. |
| SkImageInfo imageInfo = |
| SkImageInfo::Make({surfaceOptions.width, surfaceOptions.height}, colorInfo); |
| SkSurfaceProps surfaceProps(surfaceFlags, kRGB_H_SkPixelGeometry); |
| sk_sp<SkSurface> surface; |
| switch (surfaceType) { |
| default: |
| case SurfaceType::kDefault: |
| surface = SkSurfaces::RenderTarget( |
| context, skgpu::Budgeted::kNo, imageInfo, sampleCount, &surfaceProps); |
| break; |
| |
| case SurfaceType::kBackendTexture: |
| surface = sk_gpu_test::MakeBackendTextureSurface(context, |
| imageInfo, |
| kTopLeft_GrSurfaceOrigin, |
| sampleCount, |
| skgpu::Mipmapped::kNo, |
| skgpu::Protected::kNo, |
| &surfaceProps); |
| break; |
| |
| case SurfaceType::kBackendRenderTarget: |
| surface = sk_gpu_test::MakeBackendRenderTargetSurface(context, |
| imageInfo, |
| kBottomLeft_GrSurfaceOrigin, |
| sampleCount, |
| skgpu::Protected::kNo, |
| &surfaceProps); |
| break; |
| } |
| SkASSERT_RELEASE(surface); |
| |
| return std::make_unique<GaneshVulkanSurfaceManager>( |
| std::move(contextFactory), contextInfo, context, surface, config, colorInfo); |
| } |
| |
| // Based on the configurations defined here[1], the configuration parsing logic here[2], and the |
| // sink selection logic here[3]. |
| // |
| // [1] |
| // https://skia.googlesource.com/skia/+/8da85ea79d1ba2b3f32d25178eb21f2ebda83437/tools/flags/CommonFlagsConfig.cpp#40 |
| // [2] |
| // https://skia.googlesource.com/skia/+/8da85ea79d1ba2b3f32d25178eb21f2ebda83437/tools/flags/CommonFlagsConfig.cpp#610 |
| // [3] |
| // https://skia.googlesource.com/skia/+/8da85ea79d1ba2b3f32d25178eb21f2ebda83437/dm/DM.cpp#1017 |
| std::unique_ptr<SurfaceManager> SurfaceManager::FromConfig(std::string config, |
| SurfaceOptions surfaceOptions) { |
| if (config == "vk") { |
| return makeVulkanSurfaceManager( |
| config, |
| surfaceOptions, |
| GrContextOptions(), |
| sk_gpu_test::GrContextFactory::ContextOverrides::kNone, |
| SkColorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()), |
| SurfaceType::kDefault, |
| SkSurfaceProps::kDefault_Flag, |
| /* sampleCount= */ 1); |
| } |
| if (config == "vk_1010102") { |
| return makeVulkanSurfaceManager( |
| config, |
| surfaceOptions, |
| GrContextOptions(), |
| sk_gpu_test::GrContextFactory::ContextOverrides::kNone, |
| SkColorInfo( |
| kRGBA_1010102_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()), |
| SurfaceType::kDefault, |
| SkSurfaceProps::kDefault_Flag, |
| /* sampleCount= */ 1); |
| } |
| if (config == "vk_msaa4") { |
| return makeVulkanSurfaceManager( |
| config, |
| surfaceOptions, |
| GrContextOptions(), |
| sk_gpu_test::GrContextFactory::ContextOverrides::kNone, |
| SkColorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()), |
| SurfaceType::kDefault, |
| SkSurfaceProps::kDefault_Flag, |
| /* sampleCount= */ 4); |
| } |
| if (config == "vk_msaa8") { |
| return makeVulkanSurfaceManager( |
| config, |
| surfaceOptions, |
| GrContextOptions(), |
| sk_gpu_test::GrContextFactory::ContextOverrides::kNone, |
| SkColorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()), |
| SurfaceType::kDefault, |
| SkSurfaceProps::kDefault_Flag, |
| /* sampleCount= */ 8); |
| } |
| if (config == "vk_dmsaa") { |
| return makeVulkanSurfaceManager( |
| config, |
| surfaceOptions, |
| GrContextOptions(), |
| sk_gpu_test::GrContextFactory::ContextOverrides::kNone, |
| SkColorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()), |
| SurfaceType::kDefault, |
| SkSurfaceProps::kDynamicMSAA_Flag, |
| /* sampleCount= */ 1); |
| } |
| if (config == "vk_betex") { |
| return makeVulkanSurfaceManager( |
| config, |
| surfaceOptions, |
| GrContextOptions(), |
| sk_gpu_test::GrContextFactory::ContextOverrides::kNone, |
| SkColorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()), |
| SurfaceType::kBackendTexture, |
| SkSurfaceProps::kDefault_Flag, |
| /* sampleCount= */ 1); |
| } |
| if (config == "vk_bert") { |
| return makeVulkanSurfaceManager( |
| config, |
| surfaceOptions, |
| GrContextOptions(), |
| sk_gpu_test::GrContextFactory::ContextOverrides::kNone, |
| SkColorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()), |
| SurfaceType::kBackendRenderTarget, |
| SkSurfaceProps::kDefault_Flag, |
| /* sampleCount= */ 1); |
| } |
| |
| return nullptr; |
| } |