xref: /aosp_15_r20/external/skia/tools/testrunners/common/surface_manager/GaneshVulkanSurfaceManager.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2023 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 "include/core/SkColorSpace.h"
9 #include "include/gpu/ganesh/GrContextOptions.h"
10 #include "include/gpu/ganesh/SkSurfaceGanesh.h"
11 #include "tools/gpu/BackendSurfaceFactory.h"
12 #include "tools/gpu/GrContextFactory.h"
13 #include "tools/testrunners/common/surface_manager/SurfaceManager.h"
14 
15 #include <string>
16 
17 class GaneshVulkanSurfaceManager : public SurfaceManager {
18 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)19     GaneshVulkanSurfaceManager(std::unique_ptr<sk_gpu_test::GrContextFactory> contextFactory,
20                                sk_gpu_test::ContextInfo contextInfo,
21                                GrDirectContext* context,
22                                sk_sp<SkSurface> surface,
23                                std::string config,
24                                SkColorInfo colorInfo)
25             : SurfaceManager(config, colorInfo, CpuOrGpu::kGPU)
26             , fContextFactory(std::move(contextFactory))
27             , fContextInfo(contextInfo)
28             , fContext(context)
29             , fSurface(surface) {}
30 
getSurface()31     sk_sp<SkSurface> getSurface() override { return fSurface; }
32 
flush()33     void flush() override { fContext->flushAndSubmit(fSurface.get(), GrSyncCpu::kYes); }
34 
getGaneshContextInfo()35     sk_gpu_test::ContextInfo* getGaneshContextInfo() override { return &fContextInfo; }
36 
37 private:
38     // The Vulkan context is destroyed when the context factory is destroyed. We prevent early
39     // destruction of the context by grabbing a reference to the context factory. See the
40     // GrContextFactory class documentation for details.
41     std::unique_ptr<sk_gpu_test::GrContextFactory> fContextFactory;
42     sk_gpu_test::ContextInfo fContextInfo;
43     GrDirectContext* fContext;
44     sk_sp<SkSurface> fSurface;
45 };
46 
47 enum class SurfaceType { kDefault, kBackendTexture, kBackendRenderTarget };
48 
makeVulkanSurfaceManager(std::string config,SurfaceOptions surfaceOptions,GrContextOptions grContextOptions,sk_gpu_test::GrContextFactory::ContextOverrides contextOverrides,SkColorInfo colorInfo,SurfaceType surfaceType,uint32_t surfaceFlags,int sampleCount)49 std::unique_ptr<SurfaceManager> makeVulkanSurfaceManager(
50         std::string config,
51         SurfaceOptions surfaceOptions,
52         GrContextOptions grContextOptions,
53         sk_gpu_test::GrContextFactory::ContextOverrides contextOverrides,
54         SkColorInfo colorInfo,
55         SurfaceType surfaceType,
56         uint32_t surfaceFlags,
57         int sampleCount) {
58     if (surfaceOptions.modifyGrContextOptions) {
59         surfaceOptions.modifyGrContextOptions(&grContextOptions);
60     }
61 
62     // Based on
63     // https://skia.googlesource.com/skia/+/8da85ea79d1ba2b3f32d25178eb21f2ebda83437/dm/DMSrcSink.cpp#1579.
64     auto contextFactory = std::make_unique<sk_gpu_test::GrContextFactory>(grContextOptions);
65     sk_gpu_test::ContextInfo contextInfo =
66             contextFactory.get()->getContextInfo(skgpu::ContextType::kVulkan, contextOverrides);
67     GrDirectContext* context = contextInfo.directContext();
68     SkASSERT_RELEASE(context);
69 
70     // Based on
71     // https://skia.googlesource.com/skia/+/8da85ea79d1ba2b3f32d25178eb21f2ebda83437/dm/DMSrcSink.cpp#1524.
72     SkImageInfo imageInfo =
73             SkImageInfo::Make({surfaceOptions.width, surfaceOptions.height}, colorInfo);
74     SkSurfaceProps surfaceProps(surfaceFlags, kRGB_H_SkPixelGeometry);
75     sk_sp<SkSurface> surface;
76     switch (surfaceType) {
77         default:
78         case SurfaceType::kDefault:
79             surface = SkSurfaces::RenderTarget(
80                     context, skgpu::Budgeted::kNo, imageInfo, sampleCount, &surfaceProps);
81             break;
82 
83         case SurfaceType::kBackendTexture:
84             surface = sk_gpu_test::MakeBackendTextureSurface(context,
85                                                              imageInfo,
86                                                              kTopLeft_GrSurfaceOrigin,
87                                                              sampleCount,
88                                                              skgpu::Mipmapped::kNo,
89                                                              skgpu::Protected::kNo,
90                                                              &surfaceProps);
91             break;
92 
93         case SurfaceType::kBackendRenderTarget:
94             surface = sk_gpu_test::MakeBackendRenderTargetSurface(context,
95                                                                   imageInfo,
96                                                                   kBottomLeft_GrSurfaceOrigin,
97                                                                   sampleCount,
98                                                                   skgpu::Protected::kNo,
99                                                                   &surfaceProps);
100             break;
101     }
102     SkASSERT_RELEASE(surface);
103 
104     return std::make_unique<GaneshVulkanSurfaceManager>(
105             std::move(contextFactory), contextInfo, context, surface, config, colorInfo);
106 }
107 
108 // Based on the configurations defined here[1], the configuration parsing logic here[2], and the
109 // sink selection logic here[3].
110 //
111 // [1]
112 // https://skia.googlesource.com/skia/+/8da85ea79d1ba2b3f32d25178eb21f2ebda83437/tools/flags/CommonFlagsConfig.cpp#40
113 // [2]
114 // https://skia.googlesource.com/skia/+/8da85ea79d1ba2b3f32d25178eb21f2ebda83437/tools/flags/CommonFlagsConfig.cpp#610
115 // [3]
116 // https://skia.googlesource.com/skia/+/8da85ea79d1ba2b3f32d25178eb21f2ebda83437/dm/DM.cpp#1017
FromConfig(std::string config,SurfaceOptions surfaceOptions)117 std::unique_ptr<SurfaceManager> SurfaceManager::FromConfig(std::string config,
118                                                            SurfaceOptions surfaceOptions) {
119     if (config == "vk") {
120         return makeVulkanSurfaceManager(
121                 config,
122                 surfaceOptions,
123                 GrContextOptions(),
124                 sk_gpu_test::GrContextFactory::ContextOverrides::kNone,
125                 SkColorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()),
126                 SurfaceType::kDefault,
127                 SkSurfaceProps::kDefault_Flag,
128                 /* sampleCount= */ 1);
129     }
130     if (config == "vk_1010102") {
131         return makeVulkanSurfaceManager(
132                 config,
133                 surfaceOptions,
134                 GrContextOptions(),
135                 sk_gpu_test::GrContextFactory::ContextOverrides::kNone,
136                 SkColorInfo(
137                         kRGBA_1010102_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()),
138                 SurfaceType::kDefault,
139                 SkSurfaceProps::kDefault_Flag,
140                 /* sampleCount= */ 1);
141     }
142     if (config == "vk_msaa4") {
143         return makeVulkanSurfaceManager(
144                 config,
145                 surfaceOptions,
146                 GrContextOptions(),
147                 sk_gpu_test::GrContextFactory::ContextOverrides::kNone,
148                 SkColorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()),
149                 SurfaceType::kDefault,
150                 SkSurfaceProps::kDefault_Flag,
151                 /* sampleCount= */ 4);
152     }
153     if (config == "vk_msaa8") {
154         return makeVulkanSurfaceManager(
155                 config,
156                 surfaceOptions,
157                 GrContextOptions(),
158                 sk_gpu_test::GrContextFactory::ContextOverrides::kNone,
159                 SkColorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()),
160                 SurfaceType::kDefault,
161                 SkSurfaceProps::kDefault_Flag,
162                 /* sampleCount= */ 8);
163     }
164     if (config == "vk_dmsaa") {
165         return makeVulkanSurfaceManager(
166                 config,
167                 surfaceOptions,
168                 GrContextOptions(),
169                 sk_gpu_test::GrContextFactory::ContextOverrides::kNone,
170                 SkColorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()),
171                 SurfaceType::kDefault,
172                 SkSurfaceProps::kDynamicMSAA_Flag,
173                 /* sampleCount= */ 1);
174     }
175     if (config == "vk_betex") {
176         return makeVulkanSurfaceManager(
177                 config,
178                 surfaceOptions,
179                 GrContextOptions(),
180                 sk_gpu_test::GrContextFactory::ContextOverrides::kNone,
181                 SkColorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()),
182                 SurfaceType::kBackendTexture,
183                 SkSurfaceProps::kDefault_Flag,
184                 /* sampleCount= */ 1);
185     }
186     if (config == "vk_bert") {
187         return makeVulkanSurfaceManager(
188                 config,
189                 surfaceOptions,
190                 GrContextOptions(),
191                 sk_gpu_test::GrContextFactory::ContextOverrides::kNone,
192                 SkColorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()),
193                 SurfaceType::kBackendRenderTarget,
194                 SkSurfaceProps::kDefault_Flag,
195                 /* sampleCount= */ 1);
196     }
197 
198     return nullptr;
199 }
200