1 /*
2 * Copyright 2017 Google Inc.
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 * This file implements many functions defined in Test.h that are required to be implemented by
8 * test runners (such as DM) to support GPU backends.
9 */
10
11 #include "tests/Test.h"
12
13 #include "include/gpu/ganesh/GrDirectContext.h"
14
15 #if defined(SK_GRAPHITE)
16 #include "include/gpu/graphite/Context.h"
17 #include "tools/graphite/ContextFactory.h"
18 #endif
19
20 using sk_gpu_test::GrContextFactory;
21 using sk_gpu_test::ContextInfo;
22
23 #ifdef SK_GL
24 using sk_gpu_test::GLTestContext;
25 #endif
26
27 namespace skiatest {
28
IsGLContextType(skgpu::ContextType type)29 bool IsGLContextType(skgpu::ContextType type) {
30 #if defined(SK_GANESH)
31 return skgpu::ganesh::ContextTypeBackend(type) == GrBackendApi::kOpenGL;
32 #else
33 return false;
34 #endif
35 }
36
IsVulkanContextType(skgpu::ContextType type)37 bool IsVulkanContextType(skgpu::ContextType type) {
38 #if defined(SK_GANESH)
39 return skgpu::ganesh::ContextTypeBackend(type) == GrBackendApi::kVulkan;
40 #elif defined(SK_GRAPHITE)
41 return skgpu::graphite::ContextTypeBackend(type) == BackendApi::kVulkan;
42 #else
43 return false;
44 #endif
45 }
46
IsMetalContextType(skgpu::ContextType type)47 bool IsMetalContextType(skgpu::ContextType type) {
48 #if defined(SK_GANESH)
49 return skgpu::ganesh::ContextTypeBackend(type) == GrBackendApi::kMetal;
50 #elif defined(SK_GRAPHITE)
51 return skgpu::graphite::ContextTypeBackend(type) == BackendApi::kMetal;
52 #else
53 return false;
54 #endif
55 }
56
IsDirect3DContextType(skgpu::ContextType type)57 bool IsDirect3DContextType(skgpu::ContextType type) {
58 #if defined(SK_GANESH)
59 return skgpu::ganesh::ContextTypeBackend(type) == GrBackendApi::kDirect3D;
60 #else
61 return false;
62 #endif
63 }
64
IsDawnContextType(skgpu::ContextType type)65 bool IsDawnContextType(skgpu::ContextType type) {
66 #if defined(SK_GRAPHITE)
67 return skgpu::graphite::ContextTypeBackend(type) == skgpu::BackendApi::kDawn;
68 #else
69 return false;
70 #endif
71 }
72
IsMockContextType(skgpu::ContextType type)73 bool IsMockContextType(skgpu::ContextType type) {
74 return type == skgpu::ContextType::kMock;
75 }
76
RunWithGaneshTestContexts(GrContextTestFn * testFn,ContextTypeFilterFn * filter,Reporter * reporter,const GrContextOptions & options)77 void RunWithGaneshTestContexts(GrContextTestFn* testFn, ContextTypeFilterFn* filter,
78 Reporter* reporter, const GrContextOptions& options) {
79 #if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC)
80 static constexpr auto kNativeGLType = skgpu::ContextType::kGL;
81 #else
82 static constexpr auto kNativeGLType = skgpu::ContextType::kGLES;
83 #endif
84
85 for (int typeInt = 0; typeInt < skgpu::kContextTypeCount; ++typeInt) {
86 skgpu::ContextType contextType = static_cast<skgpu::ContextType>(typeInt);
87 // Use "native" instead of explicitly trying OpenGL and OpenGL ES. Do not use GLES on
88 // desktop since tests do not account for not fixing http://skbug.com/2809
89 if (contextType == skgpu::ContextType::kGL ||
90 contextType == skgpu::ContextType::kGLES) {
91 if (contextType != kNativeGLType) {
92 continue;
93 }
94 }
95 // We destroy the factory and its associated contexts after each test. This is due to the
96 // fact that the command buffer sits on top of the native GL windowing (cgl, wgl, ...) but
97 // also tracks which of its contexts is current above that API and gets tripped up if the
98 // native windowing API is used directly outside of the command buffer code.
99 GrContextFactory factory(options);
100 ContextInfo ctxInfo = factory.getContextInfo(contextType);
101 if (filter && !(*filter)(contextType)) {
102 continue;
103 }
104
105 ReporterContext ctx(reporter, SkString(skgpu::ContextTypeName(contextType)));
106 if (ctxInfo.directContext()) {
107 (*testFn)(reporter, ctxInfo);
108 // In case the test changed the current context make sure we move it back before
109 // calling flush.
110 ctxInfo.testContext()->makeCurrent();
111 // Sync so any release/finished procs get called.
112 ctxInfo.directContext()->flushAndSubmit(GrSyncCpu::kYes);
113 }
114 }
115 }
116
117 #if defined(SK_GRAPHITE)
118
119 namespace graphite {
120
RunWithGraphiteTestContexts(GraphiteTestFn * test,ContextTypeFilterFn * filter,Reporter * reporter,const skiatest::graphite::TestOptions & options)121 void RunWithGraphiteTestContexts(GraphiteTestFn* test,
122 ContextTypeFilterFn* filter,
123 Reporter* reporter,
124 const skiatest::graphite::TestOptions& options) {
125 ContextFactory factory(options);
126 for (int typeInt = 0; typeInt < skgpu::kContextTypeCount; ++typeInt) {
127 skgpu::ContextType contextType = static_cast<skgpu::ContextType>(typeInt);
128 if (filter && !(*filter)(contextType)) {
129 continue;
130 }
131
132 skiatest::graphite::ContextInfo ctxInfo = factory.getContextInfo(contextType);
133 if (!ctxInfo.fContext) {
134 continue;
135 }
136
137 ReporterContext ctx(reporter, SkString(skgpu::ContextTypeName(contextType)));
138 (*test)(reporter, ctxInfo.fContext, ctxInfo.fTestContext);
139 }
140 }
141
142 } // namespace graphite
143
144 #endif // SK_GRAPHITE
145
146 } // namespace skiatest
147