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
19class SkMatrix;
20class GrCaps;
21class GrContext;
22class GrProxyProvider;
23class GrRenderTargetContext;
24struct GrProcessorTestData;
25class GrTexture;
26class GrXPFactory;
27class GrGeometryProcessor;
28
29namespace GrProcessorUnitTest {
30
31// Used to access the dummy textures in TestCreate procs.
32enum {
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
38creating an unbounded FP tree which may overflow various shader limits. */
39std::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 */
50struct GrProcessorTestData {
51    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
65    GrContext* context() { return fContext; }
66    GrResourceProvider* resourceProvider();
67    GrProxyProvider* proxyProvider();
68    const GrCaps* caps();
69    sk_sp<GrTextureProxy> textureProxy(int index) { return fProxies[index]; }
70
71private:
72    GrContext* fContext;
73    sk_sp<GrTextureProxy> fProxies[2];
74};
75
76#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
77
78class GrProcessor;
79class GrTexture;
80
81template <class ProcessorSmartPtr>
82class GrProcessorTestFactory : private SkNoncopyable {
83public:
84    using Processor = typename ProcessorSmartPtr::element_type;
85    using MakeProc = ProcessorSmartPtr (*)(GrProcessorTestData*);
86
87    GrProcessorTestFactory(MakeProc makeProc) {
88        fMakeProc = makeProc;
89        GetFactories()->push_back(this);
90    }
91
92    /** Pick a random factory function and create a processor.  */
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 */
101    static int Count() { return GetFactories()->count(); }
102
103    /** Use factory function at Index idx to create a processor. */
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
111private:
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
122using GrFragmentProcessorTestFactory = GrProcessorTestFactory<std::unique_ptr<GrFragmentProcessor>>;
123using GrGeometryProcessorTestFactory = GrProcessorTestFactory<sk_sp<GrGeometryProcessor>>;
124
125class GrXPFactoryTestFactory : private SkNoncopyable {
126public:
127    using GetFn = const GrXPFactory*(GrProcessorTestData*);
128
129    GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) { GetFactories()->push_back(this); }
130
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
140private:
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