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 "../private/SkTArray.h" 12 #include "GrTestUtils.h" 13 #include "SkTypes.h" 14 15 class SkMatrix; 16 class GrCaps; 17 class GrContext; 18 class GrRenderTarget; 19 struct GrProcessorTestData; 20 21 namespace GrProcessorUnitTest { 22 23 // Used to access the dummy textures in TestCreate procs. 24 enum { 25 kSkiaPMTextureIdx = 0, 26 kAlphaTextureIdx = 1, 27 }; 28 29 /** This allows parent FPs to implement a test create with known leaf children in order to avoid 30 creating an unbounded FP tree which may overflow various shader limits. */ 31 const GrFragmentProcessor* CreateChildFP(GrProcessorTestData*); 32 33 } 34 35 /* 36 * GrProcessorTestData is an argument struct to TestCreate functions 37 * fTextures are valid textures that can optionally be used to construct 38 * GrTextureAccesses. The first texture has config kSkia8888_GrPixelConfig and the second has 39 * kAlpha_8_GrPixelConfig. TestCreate functions are also free to create additional textures using 40 * the GrContext. 41 */ 42 struct GrProcessorTestData { GrProcessorTestDataGrProcessorTestData43 GrProcessorTestData(SkRandom* random, 44 GrContext* context, 45 const GrCaps* caps, 46 const GrRenderTarget* rt, 47 GrTexture* textures[2]) 48 : fRandom(random) 49 , fContext(context) 50 , fCaps(caps) 51 , fRenderTarget(rt) { 52 fTextures[0] = textures[0]; 53 fTextures[1] = textures[1]; 54 } 55 SkRandom* fRandom; 56 GrContext* fContext; 57 const GrCaps* fCaps; 58 const GrRenderTarget* fRenderTarget; 59 GrTexture* fTextures[2]; 60 }; 61 62 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 63 64 class GrProcessor; 65 class GrTexture; 66 67 template <class Processor> class GrProcessorTestFactory : SkNoncopyable { 68 public: 69 typedef const Processor* (*CreateProc)(GrProcessorTestData*); 70 GrProcessorTestFactory(CreateProc createProc)71 GrProcessorTestFactory(CreateProc createProc) { 72 fCreateProc = createProc; 73 GetFactories()->push_back(this); 74 } 75 76 /** Pick a random factory function and create a processor. */ Create(GrProcessorTestData * data)77 static const Processor* Create(GrProcessorTestData* data) { 78 VerifyFactoryCount(); 79 SkASSERT(GetFactories()->count()); 80 uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1); 81 return CreateIdx(idx, data); 82 } 83 84 /** Number of registered factory functions */ Count()85 static int Count() { return GetFactories()->count(); } 86 87 /** Use factory function at Index idx to create a processor. */ CreateIdx(int idx,GrProcessorTestData * data)88 static const Processor* CreateIdx(int idx, GrProcessorTestData* data) { 89 GrProcessorTestFactory<Processor>* factory = (*GetFactories())[idx]; 90 return factory->fCreateProc(data); 91 } 92 93 /* 94 * A test function which verifies the count of factories. 95 */ 96 static void VerifyFactoryCount(); 97 98 private: 99 CreateProc fCreateProc; 100 101 static SkTArray<GrProcessorTestFactory<Processor>*, true>* GetFactories(); 102 }; 103 104 /** GrProcessor subclasses should insert this macro in their declaration to be included in the 105 * program generation unit test. 106 */ 107 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \ 108 static GrProcessorTestFactory<GrGeometryProcessor> gTestFactory SK_UNUSED; \ 109 static const GrGeometryProcessor* TestCreate(GrProcessorTestData*) 110 111 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \ 112 static GrProcessorTestFactory<GrFragmentProcessor> gTestFactory SK_UNUSED; \ 113 static const GrFragmentProcessor* TestCreate(GrProcessorTestData*) 114 115 #define GR_DECLARE_XP_FACTORY_TEST \ 116 static GrProcessorTestFactory<GrXPFactory> gTestFactory SK_UNUSED; \ 117 static const GrXPFactory* TestCreate(GrProcessorTestData*) 118 119 /** GrProcessor subclasses should insert this macro in their implementation file. They must then 120 * also implement this static function: 121 * GrProcessor* TestCreate(GrProcessorTestData*); 122 */ 123 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect) \ 124 GrProcessorTestFactory<GrFragmentProcessor> Effect :: gTestFactory(Effect :: TestCreate) 125 126 #define GR_DEFINE_XP_FACTORY_TEST(Factory) \ 127 GrProcessorTestFactory<GrXPFactory> Factory :: gTestFactory(Factory :: TestCreate) 128 129 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect) \ 130 GrProcessorTestFactory<GrGeometryProcessor> Effect :: gTestFactory(Effect :: TestCreate) 131 132 #else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 133 134 // The unit test relies on static initializers. Just declare the TestCreate function so that 135 // its definitions will compile. 136 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \ 137 static const GrFragmentProcessor* TestCreate(GrProcessorTestData*) 138 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X) 139 140 // The unit test relies on static initializers. Just declare the TestCreate function so that 141 // its definitions will compile. 142 #define GR_DECLARE_XP_FACTORY_TEST \ 143 static const GrXPFactory* TestCreate(GrProcessorTestData*) 144 #define GR_DEFINE_XP_FACTORY_TEST(X) 145 146 // The unit test relies on static initializers. Just declare the TestCreate function so that 147 // its definitions will compile. 148 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \ 149 static const GrGeometryProcessor* TestCreate(GrProcessorTestData*) 150 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X) 151 152 #endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 153 #endif 154