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 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 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 77 78 class GrProcessor; 79 class GrTexture; 80 81 template <class ProcessorSmartPtr> 82 class GrProcessorTestFactory : private SkNoncopyable { 83 public: 84 using Processor = typename ProcessorSmartPtr::element_type; 85 using MakeProc = ProcessorSmartPtr (*)(GrProcessorTestData*); 86 GrProcessorTestFactory(MakeProc makeProc)87 GrProcessorTestFactory(MakeProc makeProc) { 88 fMakeProc = makeProc; 89 GetFactories()->push_back(this); 90 } 91 92 /** Pick a random factory function and create a processor. */ Make(GrProcessorTestData * data)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 */ 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 GrProcessorTestFactory<ProcessorSmartPtr>* factory = (*GetFactories())[idx]; 106 ProcessorSmartPtr processor = factory->fMakeProc(data); 107 SkASSERT(processor); 108 return processor; 109 } 110 111 private: 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 122 using GrFragmentProcessorTestFactory = GrProcessorTestFactory<std::unique_ptr<GrFragmentProcessor>>; 123 using GrGeometryProcessorTestFactory = GrProcessorTestFactory<sk_sp<GrGeometryProcessor>>; 124 125 class GrXPFactoryTestFactory : private SkNoncopyable { 126 public: 127 using GetFn = const GrXPFactory*(GrProcessorTestData*); 128 GrXPFactoryTestFactory(GetFn * getProc)129 GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) { GetFactories()->push_back(this); } 130 Get(GrProcessorTestData * data)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 140 private: 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