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