xref: /aosp_15_r20/external/skia/tools/testrunners/common/surface_manager/GaneshGLSurfaceManager.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/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