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