1/*
2 * Copyright 2012 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
8#ifndef GrProcessorUnitTest_DEFINED
9#define GrProcessorUnitTest_DEFINED
10
11#include "include/core/SkTypes.h"
12
13#if GR_TEST_UTILS
14
15#include "include/private/SkTArray.h"
16#include "src/core/SkArenaAlloc.h"
17#include "src/gpu/GrTestUtils.h"
18#include "src/gpu/GrTextureProxy.h"
19
20#include <tuple>
21
22class SkMatrix;
23class GrCaps;
24class GrProxyProvider;
25class GrRenderTargetContext;
26class GrProcessorTestData;
27class GrTexture;
28class GrXPFactory;
29class GrGeometryProcessor;
30
31namespace GrProcessorUnitTest {
32
33// Used to access the dummy textures in TestCreate procs.
34enum {
35 kSkiaPMTextureIdx = 0,
36 kAlphaTextureIdx = 1,
37};
38
39/** This allows parent FPs to implement a test create with known leaf children in order to avoid
40 * creating an unbounded FP tree which may overflow various shader limits.
41 * MakeOptionalChildFP is the same as MakeChildFP, but can return null.
42 */
43std::unique_ptr<GrFragmentProcessor> MakeChildFP(GrProcessorTestData*);
44std::unique_ptr<GrFragmentProcessor> MakeOptionalChildFP(GrProcessorTestData*);
45
46} // namespace GrProcessorUnitTest
47
48/** GrProcessorTestData is an argument struct to TestCreate functions
49 * fTextures are valid textures that can optionally be used to construct
50 * TextureSampler. The first texture has a RGBA8 format and the second has Alpha8 format for the
51 * specific backend API. TestCreate functions are also free to create additional textures using
52 * the GrContext.
53 */
54class GrProcessorTestData {
55public:
56 using ViewInfo = std::tuple<GrSurfaceProxyView, GrColorType, SkAlphaType>;
57
58 GrProcessorTestData(SkRandom* random, GrRecordingContext* context, int maxTreeDepth,
59 int numViews, const ViewInfo views[]);
60 GrProcessorTestData(SkRandom* random, GrRecordingContext* context, int maxTreeDepth,
61 int numViews, const ViewInfo views[],
62 std::unique_ptr<GrFragmentProcessor> inputFP);
63 GrProcessorTestData(const GrProcessorTestData&) = delete;
64 ~GrProcessorTestData();
65
66 GrRecordingContext* context() { return fContext; }
67 GrProxyProvider* proxyProvider();
68 const GrCaps* caps();
69 SkArenaAlloc* allocator() { return fArena.get(); }
70 std::unique_ptr<GrFragmentProcessor> inputFP();
71
72 ViewInfo randomView();
73 ViewInfo randomAlphaOnlyView();
74
75 SkRandom* fRandom;
76 int fCurrentTreeDepth = 0;
77 int fMaxTreeDepth = 1;
78
79private:
80 GrRecordingContext* fContext;
81 SkTArray<ViewInfo> fViews;
82 std::unique_ptr<SkArenaAlloc> fArena;
83 std::unique_ptr<GrFragmentProcessor> fInputFP;
84};
85
86class GrProcessor;
87class GrTexture;
88
89template <class ProcessorSmartPtr>
90class GrProcessorTestFactory : private SkNoncopyable {
91public:
92 using MakeProc = ProcessorSmartPtr (*)(GrProcessorTestData*);
93
94 GrProcessorTestFactory(MakeProc makeProc, const char* name);
95
96 /** Pick a random factory function and create a processor. */
97 static ProcessorSmartPtr Make(GrProcessorTestData* data);
98
99 /** Use factory function at Index idx to create a processor. */
100 static ProcessorSmartPtr MakeIdx(int idx, GrProcessorTestData* data);
101
102 /** Number of registered factory functions */
103 static int Count();
104
105private:
106 /** A test function which verifies the count of factories. */
107 static void VerifyFactoryCount();
108 static SkTArray<GrProcessorTestFactory<ProcessorSmartPtr>*, true>* GetFactories();
109
110 MakeProc fMakeProc;
111 SkString fName;
112};
113
114using GrFragmentProcessorTestFactory = GrProcessorTestFactory<std::unique_ptr<GrFragmentProcessor>>;
115using GrGeometryProcessorTestFactory = GrProcessorTestFactory<GrGeometryProcessor*>;
116
117class GrXPFactoryTestFactory : private SkNoncopyable {
118public:
119 using GetFn = const GrXPFactory*(GrProcessorTestData*);
120
121 GrXPFactoryTestFactory(GetFn* getProc);
122
123 static const GrXPFactory* Get(GrProcessorTestData* data);
124
125private:
126 /** A test function which verifies the count of factories. */
127 static void VerifyFactoryCount();
128 static SkTArray<GrXPFactoryTestFactory*, true>* GetFactories();
129
130 GetFn* fGetProc;
131};
132
133#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
134
135/** GrProcessor subclasses should insert this macro in their declaration to be included in the
136 * program generation unit test.
137 */
138#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \
139 static GrGeometryProcessorTestFactory gTestFactory SK_UNUSED; \
140 static GrGeometryProcessor* TestCreate(GrProcessorTestData*);
141
142#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \
143 static GrFragmentProcessorTestFactory gTestFactory SK_UNUSED; \
144 static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
145
146#define GR_DECLARE_XP_FACTORY_TEST \
147 static GrXPFactoryTestFactory gTestFactory SK_UNUSED; \
148 static const GrXPFactory* TestGet(GrProcessorTestData*);
149
150/** GrProcessor subclasses should insert this macro in their implementation file. They must then
151 * also implement this static function:
152 * GrProcessor* TestCreate(GrProcessorTestData*);
153 */
154#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect) \
155 GrFragmentProcessorTestFactory Effect::gTestFactory(Effect::TestCreate, #Effect)
156
157#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect) \
158 GrGeometryProcessorTestFactory Effect::gTestFactory(Effect::TestCreate, #Effect)
159
160#define GR_DEFINE_XP_FACTORY_TEST(Factory) \
161 GrXPFactoryTestFactory Factory::gTestFactory(Factory::TestGet)
162
163#else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
164
165// The unit test relies on static initializers. Just declare the TestCreate function so that
166// its definitions will compile.
167#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \
168 static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
169#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
170
171// The unit test relies on static initializers. Just declare the TestCreate function so that
172// its definitions will compile.
173#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \
174 static GrGeometryProcessor* TestCreate(GrProcessorTestData*);
175#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
176
177// The unit test relies on static initializers. Just declare the TestGet function so that
178// its definitions will compile.
179#define GR_DECLARE_XP_FACTORY_TEST \
180 const GrXPFactory* TestGet(GrProcessorTestData*);
181#define GR_DEFINE_XP_FACTORY_TEST(X)
182
183#endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
184#else // GR_TEST_UTILS
185 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
186 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
187 #define GR_DECLARE_XP_FACTORY_TEST
188 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
189 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
190 #define GR_DEFINE_XP_FACTORY_TEST(...)
191 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
192 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
193 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
194 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
195 #define GR_DECLARE_XP_FACTORY_TEST
196 #define GR_DEFINE_XP_FACTORY_TEST(...)
197#endif // GR_TEST_UTILS
198#endif // GrProcessorUnitTest_DEFINED
199