• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                         sk_sp<GrTextureProxy> proxies[2])
53             : fRandom(random)
54             , fRenderTargetContext(renderTargetContext)
55             , fContext(context) {
56         SkASSERT(proxies[0] && proxies[1]);
57         fProxies[0] = proxies[0];
58         fProxies[1] = proxies[1];
59     }
60     SkRandom* fRandom;
61     const GrRenderTargetContext* fRenderTargetContext;
62 
contextGrProcessorTestData63     GrContext* context() { return fContext; }
64     GrResourceProvider* resourceProvider();
65     const GrCaps* caps();
textureProxyGrProcessorTestData66     sk_sp<GrTextureProxy> textureProxy(int index) { return fProxies[index]; }
67 
68 private:
69     GrContext* fContext;
70     sk_sp<GrTextureProxy> fProxies[2];
71 };
72 
73 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
74 
75 class GrProcessor;
76 class GrTexture;
77 
78 template <class Processor> class GrProcessorTestFactory : private SkNoncopyable {
79 public:
80     typedef sk_sp<Processor> (*MakeProc)(GrProcessorTestData*);
81 
GrProcessorTestFactory(MakeProc makeProc)82     GrProcessorTestFactory(MakeProc makeProc) {
83         fMakeProc = makeProc;
84         GetFactories()->push_back(this);
85     }
86 
87     /** Pick a random factory function and create a processor.  */
Make(GrProcessorTestData * data)88     static sk_sp<Processor> Make(GrProcessorTestData* data) {
89         VerifyFactoryCount();
90         SkASSERT(GetFactories()->count());
91         uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
92         return MakeIdx(idx, data);
93     }
94 
95     /** Number of registered factory functions */
Count()96     static int Count() { return GetFactories()->count(); }
97 
98     /** Use factory function at Index idx to create a processor. */
MakeIdx(int idx,GrProcessorTestData * data)99     static sk_sp<Processor> MakeIdx(int idx, GrProcessorTestData* data) {
100         GrProcessorTestFactory<Processor>* factory = (*GetFactories())[idx];
101         sk_sp<Processor> processor = factory->fMakeProc(data);
102         SkASSERT(processor);
103         return processor;
104     }
105 
106 private:
107     /**
108      * A test function which verifies the count of factories.
109      */
110     static void VerifyFactoryCount();
111 
112     MakeProc fMakeProc;
113 
114     static SkTArray<GrProcessorTestFactory<Processor>*, true>* GetFactories();
115 };
116 
117 class GrXPFactoryTestFactory : private SkNoncopyable {
118 public:
119     using GetFn = const GrXPFactory*(GrProcessorTestData*);
120 
GrXPFactoryTestFactory(GetFn * getProc)121     GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) { GetFactories()->push_back(this); }
122 
Get(GrProcessorTestData * data)123     static const GrXPFactory* Get(GrProcessorTestData* data) {
124         VerifyFactoryCount();
125         SkASSERT(GetFactories()->count());
126         uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
127         const GrXPFactory* xpf = (*GetFactories())[idx]->fGetProc(data);
128         SkASSERT(xpf);
129         return xpf;
130     }
131 
132 private:
133     static void VerifyFactoryCount();
134 
135     GetFn* fGetProc;
136     static SkTArray<GrXPFactoryTestFactory*, true>* GetFactories();
137 };
138 
139 /** GrProcessor subclasses should insert this macro in their declaration to be included in the
140  *  program generation unit test.
141  */
142 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
143     static GrProcessorTestFactory<GrGeometryProcessor> gTestFactory SK_UNUSED;                     \
144     static sk_sp<GrGeometryProcessor> TestCreate(GrProcessorTestData*);
145 
146 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
147     static GrProcessorTestFactory<GrFragmentProcessor> gTestFactory SK_UNUSED;                     \
148     static sk_sp<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
149 
150 #define GR_DECLARE_XP_FACTORY_TEST                                                                 \
151     static GrXPFactoryTestFactory gTestFactory SK_UNUSED;                                          \
152     static const GrXPFactory* TestGet(GrProcessorTestData*);
153 
154 /** GrProcessor subclasses should insert this macro in their implementation file. They must then
155  *  also implement this static function:
156  *      GrProcessor* TestCreate(GrProcessorTestData*);
157  */
158 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect)                                                  \
159     GrProcessorTestFactory<GrFragmentProcessor> Effect::gTestFactory(Effect::TestCreate)
160 
161 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect)                                                  \
162     GrProcessorTestFactory<GrGeometryProcessor> Effect::gTestFactory(Effect::TestCreate)
163 
164 #define GR_DEFINE_XP_FACTORY_TEST(Factory)                                                         \
165     GrXPFactoryTestFactory Factory::gTestFactory(Factory::TestGet)
166 
167 #else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
168 
169 // The unit test relies on static initializers. Just declare the TestCreate function so that
170 // its definitions will compile.
171 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
172     static sk_sp<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
173 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
174 
175 // The unit test relies on static initializers. Just declare the TestCreate function so that
176 // its definitions will compile.
177 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
178     static sk_sp<GrGeometryProcessor> TestCreate(GrProcessorTestData*);
179 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
180 
181 // The unit test relies on static initializers. Just declare the TestGet function so that
182 // its definitions will compile.
183 #define GR_DECLARE_XP_FACTORY_TEST                                                                 \
184     const GrXPFactory* TestGet(GrProcessorTestData*);
185 #define GR_DEFINE_XP_FACTORY_TEST(X)
186 
187 #endif  // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
188 #else   // GR_TEST_UTILS
189     #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
190     #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
191     #define GR_DECLARE_XP_FACTORY_TEST
192     #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
193     #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
194     #define GR_DEFINE_XP_FACTORY_TEST(...)
195     #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
196     #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
197     #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
198     #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
199     #define GR_DECLARE_XP_FACTORY_TEST
200     #define GR_DEFINE_XP_FACTORY_TEST(...)
201 #endif  // GR_TEST_UTILS
202 #endif  // GrProcessorUnitTest_DEFINED
203