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