GrProcessorUnitTest.h revision 9f5d4679e107ab83de635392798b3ddd62f48a12
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 19class SkMatrix; 20class GrCaps; 21class GrContext; 22class GrRenderTargetContext; 23struct GrProcessorTestData; 24class GrTexture; 25class GrXPFactory; 26 27namespace GrProcessorUnitTest { 28 29// Used to access the dummy textures in TestCreate procs. 30enum { 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 36creating an unbounded FP tree which may overflow various shader limits. */ 37sk_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 */ 48struct GrProcessorTestData { 49 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 fProxies[0] = proxies[0]; 57 fProxies[1] = proxies[1]; 58 } 59 SkRandom* fRandom; 60 const GrRenderTargetContext* fRenderTargetContext; 61 62 GrContext* context() { return fContext; } 63 GrResourceProvider* resourceProvider(); 64 const GrCaps* caps(); 65 sk_sp<GrTextureProxy> textureProxy(int index) { return fProxies[index]; } 66 67private: 68 GrContext* fContext; 69 sk_sp<GrTextureProxy> fProxies[2]; 70}; 71 72#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 73 74class GrProcessor; 75class GrTexture; 76 77template <class Processor> class GrProcessorTestFactory : private SkNoncopyable { 78public: 79 typedef sk_sp<Processor> (*MakeProc)(GrProcessorTestData*); 80 81 GrProcessorTestFactory(MakeProc makeProc) { 82 fMakeProc = makeProc; 83 GetFactories()->push_back(this); 84 } 85 86 /** Pick a random factory function and create a processor. */ 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 */ 95 static int Count() { return GetFactories()->count(); } 96 97 /** Use factory function at Index idx to create a processor. */ 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 105private: 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 116class GrXPFactoryTestFactory : private SkNoncopyable { 117public: 118 using GetFn = const GrXPFactory*(GrProcessorTestData*); 119 120 GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) { GetFactories()->push_back(this); } 121 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 131private: 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