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 "GrTestUtils.h"
12 #include "SkTArray.h"
13 #include "SkTypes.h"
14 
15 class SkMatrix;
16 class GrDrawTargetCaps;
17 
18 namespace GrProcessorUnitTest {
19 // Used to access the dummy textures in TestCreate procs.
20 enum {
21     kSkiaPMTextureIdx = 0,
22     kAlphaTextureIdx = 1,
23 };
24 
25 }
26 
27 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
28 
29 class GrContext;
30 class GrProcessor;
31 class GrTexture;
32 
33 template <class Processor>
34 class GrProcessorTestFactory : SkNoncopyable {
35 public:
36 
37     typedef Processor* (*CreateProc)(SkRandom*,
38                                      GrContext*,
39                                      const GrDrawTargetCaps& caps,
40                                      GrTexture* dummyTextures[]);
41 
GrProcessorTestFactory(CreateProc createProc)42     GrProcessorTestFactory(CreateProc createProc) {
43         fCreateProc = createProc;
44         GetFactories()->push_back(this);
45     }
46 
CreateStage(SkRandom * random,GrContext * context,const GrDrawTargetCaps & caps,GrTexture * dummyTextures[])47     static Processor* CreateStage(SkRandom* random,
48                                   GrContext* context,
49                                   const GrDrawTargetCaps& caps,
50                                   GrTexture* dummyTextures[]) {
51         VerifyFactoryCount();
52         SkASSERT(GetFactories()->count());
53         uint32_t idx = random->nextRangeU(0, GetFactories()->count() - 1);
54         GrProcessorTestFactory<Processor>* factory = (*GetFactories())[idx];
55         return factory->fCreateProc(random, context, caps, dummyTextures);
56     }
57 
58     /*
59      * A test function which verifies the count of factories.
60      */
61     static void VerifyFactoryCount();
62 
63 private:
64     CreateProc fCreateProc;
65 
66     static SkTArray<GrProcessorTestFactory<Processor>*, true>* GetFactories();
67 };
68 
69 /** GrProcessor subclasses should insert this macro in their declaration to be included in the
70  *  program generation unit test.
71  */
72 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
73     static GrProcessorTestFactory<GrGeometryProcessor> gTestFactory SK_UNUSED;                     \
74     static GrGeometryProcessor* TestCreate(SkRandom*,                                              \
75                                            GrContext*,                                             \
76                                            const GrDrawTargetCaps&,                                \
77                                            GrTexture* dummyTextures[2])
78 
79 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
80     static GrProcessorTestFactory<GrFragmentProcessor> gTestFactory SK_UNUSED;                     \
81     static GrFragmentProcessor* TestCreate(SkRandom*,                                              \
82                                            GrContext*,                                             \
83                                            const GrDrawTargetCaps&,                                \
84                                            GrTexture* dummyTextures[2])
85 
86 #define GR_DECLARE_XP_FACTORY_TEST                                                                 \
87     static GrProcessorTestFactory<GrXPFactory> gTestFactory SK_UNUSED;                             \
88     static GrXPFactory* TestCreate(SkRandom*,                                                      \
89                                    GrContext*,                                                     \
90                                    const GrDrawTargetCaps&,                                        \
91                                    GrTexture* dummyTextures[2])
92 
93 
94 /** GrProcessor subclasses should insert this macro in their implementation file. They must then
95  *  also implement this static function:
96  *      GrProcessor* TestCreate(SkRandom*,
97  *                           GrContext*,
98  *                           const GrDrawTargetCaps&,
99  *                           GrTexture* dummyTextures[2]);
100  * dummyTextures[] are valid textures that can optionally be used to construct GrTextureAccesses.
101  * The first texture has config kSkia8888_GrPixelConfig and the second has
102  * kAlpha_8_GrPixelConfig. TestCreate functions are also free to create additional textures using
103  * the GrContext.
104  */
105 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect)                                                  \
106     GrProcessorTestFactory<GrFragmentProcessor> Effect :: gTestFactory(Effect :: TestCreate)
107 
108 #define GR_DEFINE_XP_FACTORY_TEST(Factory)                                                         \
109     GrProcessorTestFactory<GrXPFactory> Factory :: gTestFactory(Factory :: TestCreate)
110 
111 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect)                                                  \
112     GrProcessorTestFactory<GrGeometryProcessor> Effect :: gTestFactory(Effect :: TestCreate)
113 
114 #else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
115 
116 // The unit test relies on static initializers. Just declare the TestCreate function so that
117 // its definitions will compile.
118 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
119     static GrFragmentProcessor* TestCreate(SkRandom*,                                              \
120                                            GrContext*,                                             \
121                                            const GrDrawTargetCaps&,                                \
122                                            GrTexture* dummyTextures[2])
123 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
124 
125 // The unit test relies on static initializers. Just declare the TestCreate function so that
126 // its definitions will compile.
127 #define GR_DECLARE_XP_FACTORY_TEST                                                                 \
128     static GrXPFactory* TestCreate(SkRandom*,                                                      \
129                                    GrContext*,                                                     \
130                                    const GrDrawTargetCaps&,                                        \
131                                    GrTexture* dummyTextures[2])
132 #define GR_DEFINE_XP_FACTORY_TEST(X)
133 
134 // The unit test relies on static initializers. Just declare the TestCreate function so that
135 // its definitions will compile.
136 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
137     static GrGeometryProcessor* TestCreate(SkRandom*,                                              \
138                                            GrContext*,                                             \
139                                            const GrDrawTargetCaps&,                                \
140                                            GrTexture* dummyTextures[2])
141 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
142 
143 #endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
144 #endif
145