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