• 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 "include/core/SkTypes.h"
12 
13 #if GR_TEST_UTILS
14 
15 #include "include/private/SkTArray.h"
16 #include "src/gpu/GrTestUtils.h"
17 #include "src/gpu/GrTextureProxy.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 class GrProcessor;
77 class GrTexture;
78 
79 template <class ProcessorSmartPtr>
80 class GrProcessorTestFactory : private SkNoncopyable {
81 public:
82     using Processor = typename ProcessorSmartPtr::element_type;
83     using MakeProc = ProcessorSmartPtr (*)(GrProcessorTestData*);
84 
GrProcessorTestFactory(MakeProc makeProc)85     GrProcessorTestFactory(MakeProc makeProc) {
86         fMakeProc = makeProc;
87         GetFactories()->push_back(this);
88     }
89 
90     /** Pick a random factory function and create a processor.  */
Make(GrProcessorTestData * data)91     static ProcessorSmartPtr Make(GrProcessorTestData* data) {
92         VerifyFactoryCount();
93         if (GetFactories()->count() == 0) {
94             return nullptr;
95         }
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         SkASSERT(idx < GetFactories()->count());
106         GrProcessorTestFactory<ProcessorSmartPtr>* factory = (*GetFactories())[idx];
107         ProcessorSmartPtr processor = factory->fMakeProc(data);
108         SkASSERT(processor);
109         return processor;
110     }
111 
112 private:
113     /**
114      * A test function which verifies the count of factories.
115      */
116     static void VerifyFactoryCount();
117 
118     MakeProc fMakeProc;
119 
120     static SkTArray<GrProcessorTestFactory<ProcessorSmartPtr>*, true>* GetFactories();
121 };
122 
123 using GrFragmentProcessorTestFactory = GrProcessorTestFactory<std::unique_ptr<GrFragmentProcessor>>;
124 using GrGeometryProcessorTestFactory = GrProcessorTestFactory<sk_sp<GrGeometryProcessor>>;
125 
126 class GrXPFactoryTestFactory : private SkNoncopyable {
127 public:
128     using GetFn = const GrXPFactory*(GrProcessorTestData*);
129 
GrXPFactoryTestFactory(GetFn * getProc)130     GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) { GetFactories()->push_back(this); }
131 
Get(GrProcessorTestData * data)132     static const GrXPFactory* Get(GrProcessorTestData* data) {
133         VerifyFactoryCount();
134         if (GetFactories()->count() == 0) {
135             return nullptr;
136         }
137         uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
138         const GrXPFactory* xpf = (*GetFactories())[idx]->fGetProc(data);
139         SkASSERT(xpf);
140         return xpf;
141     }
142 
143 private:
144     static void VerifyFactoryCount();
145 
146     GetFn* fGetProc;
147     static SkTArray<GrXPFactoryTestFactory*, true>* GetFactories();
148 };
149 
150 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
151 
152 /** GrProcessor subclasses should insert this macro in their declaration to be included in the
153  *  program generation unit test.
154  */
155 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                        \
156     static GrGeometryProcessorTestFactory gTestFactory SK_UNUSED; \
157     static sk_sp<GrGeometryProcessor> TestCreate(GrProcessorTestData*);
158 
159 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                        \
160     static GrFragmentProcessorTestFactory gTestFactory SK_UNUSED; \
161     static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
162 
163 #define GR_DECLARE_XP_FACTORY_TEST                                                                 \
164     static GrXPFactoryTestFactory gTestFactory SK_UNUSED;                                          \
165     static const GrXPFactory* TestGet(GrProcessorTestData*);
166 
167 /** GrProcessor subclasses should insert this macro in their implementation file. They must then
168  *  also implement this static function:
169  *      GrProcessor* TestCreate(GrProcessorTestData*);
170  */
171 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect) \
172     GrFragmentProcessorTestFactory Effect::gTestFactory(Effect::TestCreate)
173 
174 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect) \
175     GrGeometryProcessorTestFactory Effect::gTestFactory(Effect::TestCreate)
176 
177 #define GR_DEFINE_XP_FACTORY_TEST(Factory)                                                         \
178     GrXPFactoryTestFactory Factory::gTestFactory(Factory::TestGet)
179 
180 #else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
181 
182 // The unit test relies on static initializers. Just declare the TestCreate function so that
183 // its definitions will compile.
184 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
185     static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
186 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
187 
188 // The unit test relies on static initializers. Just declare the TestCreate function so that
189 // its definitions will compile.
190 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
191     static sk_sp<GrGeometryProcessor> TestCreate(GrProcessorTestData*);
192 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
193 
194 // The unit test relies on static initializers. Just declare the TestGet function so that
195 // its definitions will compile.
196 #define GR_DECLARE_XP_FACTORY_TEST                                                                 \
197     const GrXPFactory* TestGet(GrProcessorTestData*);
198 #define GR_DEFINE_XP_FACTORY_TEST(X)
199 
200 #endif  // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
201 #else   // GR_TEST_UTILS
202     #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
203     #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
204     #define GR_DECLARE_XP_FACTORY_TEST
205     #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
206     #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
207     #define GR_DEFINE_XP_FACTORY_TEST(...)
208     #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
209     #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
210     #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
211     #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
212     #define GR_DECLARE_XP_FACTORY_TEST
213     #define GR_DEFINE_XP_FACTORY_TEST(...)
214 #endif  // GR_TEST_UTILS
215 #endif  // GrProcessorUnitTest_DEFINED
216