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