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 {
GrProcessorTestDataGrProcessorTestData49     GrProcessorTestData(SkRandom* random,
50                         GrContext* context,
51                         const GrRenderTargetContext* renderTargetContext,
52                         GrTexture* const textures[2])
53             : fRandom(random)
54             , fRenderTargetContext(renderTargetContext)
55             , fContext(context) {
56         fProxies[0] = GrSurfaceProxy::MakeWrapped(sk_ref_sp(textures[0]));
57         fProxies[1] = GrSurfaceProxy::MakeWrapped(sk_ref_sp(textures[1]));
58     }
59     SkRandom* fRandom;
60     const GrRenderTargetContext* fRenderTargetContext;
61 
contextGrProcessorTestData62     GrContext* context() { return fContext; }
63     GrResourceProvider* resourceProvider();
64     const GrCaps* caps();
textureProxyGrProcessorTestData65     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 
GrProcessorTestFactory(MakeProc makeProc)81     GrProcessorTestFactory(MakeProc makeProc) {
82         fMakeProc = makeProc;
83         GetFactories()->push_back(this);
84     }
85 
86     /** Pick a random factory function and create a processor.  */
Make(GrProcessorTestData * data)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 */
Count()95     static int Count() { return GetFactories()->count(); }
96 
97     /** Use factory function at Index idx to create a processor. */
MakeIdx(int idx,GrProcessorTestData * data)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 
GrXPFactoryTestFactory(GetFn * getProc)120     GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) { GetFactories()->push_back(this); }
121 
Get(GrProcessorTestData * data)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
202