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 "include/core/SkTypes.h" 12 13 #if GR_TEST_UTILS 14 15 #include "include/private/SkTArray.h" 16 #include "src/gpu/GrTestUtils.h" 17 #include "src/gpu/GrTextureProxy.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 class GrProcessor; 77 class GrTexture; 78 79 template <class ProcessorSmartPtr> 80 class GrProcessorTestFactory : private SkNoncopyable { 81 public: 82 using Processor = typename ProcessorSmartPtr::element_type; 83 using MakeProc = ProcessorSmartPtr (*)(GrProcessorTestData*); 84 GrProcessorTestFactory(MakeProc makeProc)85 GrProcessorTestFactory(MakeProc makeProc) { 86 fMakeProc = makeProc; 87 GetFactories()->push_back(this); 88 } 89 90 /** Pick a random factory function and create a processor. */ Make(GrProcessorTestData * data)91 static ProcessorSmartPtr Make(GrProcessorTestData* data) { 92 VerifyFactoryCount(); 93 if (GetFactories()->count() == 0) { 94 return nullptr; 95 } 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 SkASSERT(idx < GetFactories()->count()); 106 GrProcessorTestFactory<ProcessorSmartPtr>* factory = (*GetFactories())[idx]; 107 ProcessorSmartPtr processor = factory->fMakeProc(data); 108 SkASSERT(processor); 109 return processor; 110 } 111 112 private: 113 /** 114 * A test function which verifies the count of factories. 115 */ 116 static void VerifyFactoryCount(); 117 118 MakeProc fMakeProc; 119 120 static SkTArray<GrProcessorTestFactory<ProcessorSmartPtr>*, true>* GetFactories(); 121 }; 122 123 using GrFragmentProcessorTestFactory = GrProcessorTestFactory<std::unique_ptr<GrFragmentProcessor>>; 124 using GrGeometryProcessorTestFactory = GrProcessorTestFactory<sk_sp<GrGeometryProcessor>>; 125 126 class GrXPFactoryTestFactory : private SkNoncopyable { 127 public: 128 using GetFn = const GrXPFactory*(GrProcessorTestData*); 129 GrXPFactoryTestFactory(GetFn * getProc)130 GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) { GetFactories()->push_back(this); } 131 Get(GrProcessorTestData * data)132 static const GrXPFactory* Get(GrProcessorTestData* data) { 133 VerifyFactoryCount(); 134 if (GetFactories()->count() == 0) { 135 return nullptr; 136 } 137 uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1); 138 const GrXPFactory* xpf = (*GetFactories())[idx]->fGetProc(data); 139 SkASSERT(xpf); 140 return xpf; 141 } 142 143 private: 144 static void VerifyFactoryCount(); 145 146 GetFn* fGetProc; 147 static SkTArray<GrXPFactoryTestFactory*, true>* GetFactories(); 148 }; 149 150 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 151 152 /** GrProcessor subclasses should insert this macro in their declaration to be included in the 153 * program generation unit test. 154 */ 155 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \ 156 static GrGeometryProcessorTestFactory gTestFactory SK_UNUSED; \ 157 static sk_sp<GrGeometryProcessor> TestCreate(GrProcessorTestData*); 158 159 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \ 160 static GrFragmentProcessorTestFactory gTestFactory SK_UNUSED; \ 161 static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*); 162 163 #define GR_DECLARE_XP_FACTORY_TEST \ 164 static GrXPFactoryTestFactory gTestFactory SK_UNUSED; \ 165 static const GrXPFactory* TestGet(GrProcessorTestData*); 166 167 /** GrProcessor subclasses should insert this macro in their implementation file. They must then 168 * also implement this static function: 169 * GrProcessor* TestCreate(GrProcessorTestData*); 170 */ 171 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect) \ 172 GrFragmentProcessorTestFactory Effect::gTestFactory(Effect::TestCreate) 173 174 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect) \ 175 GrGeometryProcessorTestFactory Effect::gTestFactory(Effect::TestCreate) 176 177 #define GR_DEFINE_XP_FACTORY_TEST(Factory) \ 178 GrXPFactoryTestFactory Factory::gTestFactory(Factory::TestGet) 179 180 #else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 181 182 // The unit test relies on static initializers. Just declare the TestCreate function so that 183 // its definitions will compile. 184 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \ 185 static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*); 186 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X) 187 188 // The unit test relies on static initializers. Just declare the TestCreate function so that 189 // its definitions will compile. 190 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \ 191 static sk_sp<GrGeometryProcessor> TestCreate(GrProcessorTestData*); 192 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X) 193 194 // The unit test relies on static initializers. Just declare the TestGet function so that 195 // its definitions will compile. 196 #define GR_DECLARE_XP_FACTORY_TEST \ 197 const GrXPFactory* TestGet(GrProcessorTestData*); 198 #define GR_DEFINE_XP_FACTORY_TEST(X) 199 200 #endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 201 #else // GR_TEST_UTILS 202 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST 203 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST 204 #define GR_DECLARE_XP_FACTORY_TEST 205 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...) 206 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...) 207 #define GR_DEFINE_XP_FACTORY_TEST(...) 208 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST 209 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...) 210 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST 211 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...) 212 #define GR_DECLARE_XP_FACTORY_TEST 213 #define GR_DEFINE_XP_FACTORY_TEST(...) 214 #endif // GR_TEST_UTILS 215 #endif // GrProcessorUnitTest_DEFINED 216