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/core/SkArenaAlloc.h" 17 #include "src/gpu/GrTestUtils.h" 18 #include "src/gpu/GrTextureProxy.h" 19 20 #include <tuple> 21 22 class SkMatrix; 23 class GrCaps; 24 class GrProxyProvider; 25 class GrProcessorTestData; 26 class GrTexture; 27 class GrXPFactory; 28 class GrGeometryProcessor; 29 30 namespace GrProcessorUnitTest { 31 32 /** This allows parent FPs to implement a test create with known leaf children in order to avoid 33 * creating an unbounded FP tree which may overflow various shader limits. 34 * MakeOptionalChildFP is the same as MakeChildFP, but can return null. 35 */ 36 std::unique_ptr<GrFragmentProcessor> MakeChildFP(GrProcessorTestData*); 37 std::unique_ptr<GrFragmentProcessor> MakeOptionalChildFP(GrProcessorTestData*); 38 39 } // namespace GrProcessorUnitTest 40 41 /** GrProcessorTestData is an argument struct to TestCreate functions 42 * fTextures are valid textures that can optionally be used to construct 43 * TextureSampler. The first texture has a RGBA8 format and the second has Alpha8 format for the 44 * specific backend API. TestCreate functions are also free to create additional textures using 45 * the GrContext. 46 */ 47 class GrProcessorTestData { 48 public: 49 using ViewInfo = std::tuple<GrSurfaceProxyView, GrColorType, SkAlphaType>; 50 51 GrProcessorTestData(SkRandom* random, GrRecordingContext* context, int maxTreeDepth, 52 int numViews, const ViewInfo views[]); 53 GrProcessorTestData(SkRandom* random, GrRecordingContext* context, int maxTreeDepth, 54 int numViews, const ViewInfo views[], 55 std::unique_ptr<GrFragmentProcessor> inputFP); 56 GrProcessorTestData(const GrProcessorTestData&) = delete; 57 ~GrProcessorTestData(); 58 context()59 GrRecordingContext* context() { return fContext; } 60 GrProxyProvider* proxyProvider(); 61 const GrCaps* caps(); allocator()62 SkArenaAlloc* allocator() { return fArena.get(); } 63 std::unique_ptr<GrFragmentProcessor> inputFP(); 64 65 ViewInfo randomView(); 66 ViewInfo randomAlphaOnlyView(); 67 68 SkRandom* fRandom; 69 int fCurrentTreeDepth = 0; 70 int fMaxTreeDepth = 1; 71 72 private: 73 GrRecordingContext* fContext; 74 SkTArray<ViewInfo> fViews; 75 std::unique_ptr<SkArenaAlloc> fArena; 76 std::unique_ptr<GrFragmentProcessor> fInputFP; 77 }; 78 79 class GrProcessor; 80 class GrTexture; 81 82 template <class ProcessorSmartPtr> 83 class GrProcessorTestFactory : private SkNoncopyable { 84 public: 85 using MakeProc = ProcessorSmartPtr (*)(GrProcessorTestData*); 86 87 GrProcessorTestFactory(MakeProc makeProc, const char* name); 88 89 /** Pick a random factory function and create a processor. */ 90 static ProcessorSmartPtr Make(GrProcessorTestData* data); 91 92 /** Use factory function at Index idx to create a processor. */ 93 static ProcessorSmartPtr MakeIdx(int idx, GrProcessorTestData* data); 94 95 /** Number of registered factory functions */ 96 static int Count(); 97 98 private: 99 /** A test function which verifies the count of factories. */ 100 static void VerifyFactoryCount(); 101 static SkTArray<GrProcessorTestFactory<ProcessorSmartPtr>*, true>* GetFactories(); 102 103 MakeProc fMakeProc; 104 SkString fName; 105 }; 106 107 using GrFragmentProcessorTestFactory = GrProcessorTestFactory<std::unique_ptr<GrFragmentProcessor>>; 108 using GrGeometryProcessorTestFactory = GrProcessorTestFactory<GrGeometryProcessor*>; 109 110 class GrXPFactoryTestFactory : private SkNoncopyable { 111 public: 112 using GetFn = const GrXPFactory*(GrProcessorTestData*); 113 114 GrXPFactoryTestFactory(GetFn* getProc); 115 116 static const GrXPFactory* Get(GrProcessorTestData* data); 117 118 private: 119 /** A test function which verifies the count of factories. */ 120 static void VerifyFactoryCount(); 121 static SkTArray<GrXPFactoryTestFactory*, true>* GetFactories(); 122 123 GetFn* fGetProc; 124 }; 125 126 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 127 128 /** GrProcessor subclasses should insert this macro in their declaration to be included in the 129 * program generation unit test. 130 */ 131 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \ 132 static GrGeometryProcessorTestFactory gTestFactory SK_UNUSED; \ 133 static GrGeometryProcessor* TestCreate(GrProcessorTestData*); 134 135 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \ 136 static GrFragmentProcessorTestFactory gTestFactory SK_UNUSED; \ 137 static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*); 138 139 #define GR_DECLARE_XP_FACTORY_TEST \ 140 static GrXPFactoryTestFactory gTestFactory SK_UNUSED; \ 141 static const GrXPFactory* TestGet(GrProcessorTestData*); 142 143 /** GrProcessor subclasses should insert this macro in their implementation file. They must then 144 * also implement this static function: 145 * GrProcessor* TestCreate(GrProcessorTestData*); 146 */ 147 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect) \ 148 GrFragmentProcessorTestFactory Effect::gTestFactory(Effect::TestCreate, #Effect) 149 150 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect) \ 151 GrGeometryProcessorTestFactory Effect::gTestFactory(Effect::TestCreate, #Effect) 152 153 #define GR_DEFINE_XP_FACTORY_TEST(Factory) \ 154 GrXPFactoryTestFactory Factory::gTestFactory(Factory::TestGet) 155 156 #else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 157 158 // The unit test relies on static initializers. Just declare the TestCreate function so that 159 // its definitions will compile. 160 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \ 161 static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*); 162 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X) 163 164 // The unit test relies on static initializers. Just declare the TestCreate function so that 165 // its definitions will compile. 166 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \ 167 static GrGeometryProcessor* TestCreate(GrProcessorTestData*); 168 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X) 169 170 // The unit test relies on static initializers. Just declare the TestGet function so that 171 // its definitions will compile. 172 #define GR_DECLARE_XP_FACTORY_TEST \ 173 const GrXPFactory* TestGet(GrProcessorTestData*); 174 #define GR_DEFINE_XP_FACTORY_TEST(X) 175 176 #endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 177 #else // GR_TEST_UTILS 178 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST 179 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST 180 #define GR_DECLARE_XP_FACTORY_TEST 181 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...) 182 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...) 183 #define GR_DEFINE_XP_FACTORY_TEST(...) 184 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST 185 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...) 186 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST 187 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...) 188 #define GR_DECLARE_XP_FACTORY_TEST 189 #define GR_DEFINE_XP_FACTORY_TEST(...) 190 #endif // GR_TEST_UTILS 191 #endif // GrProcessorUnitTest_DEFINED 192