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