blob: 731e1edda00d5b5b5b9d2c89ccb3b94e3ee0b8d7 [file] [log] [blame]
joshualittb0a8a372014-09-23 09:50:21 -07001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkTypes.h"
Hal Canary6f6961e2017-01-31 13:50:44 -050012
13#if GR_TEST_UTILS
14
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "include/private/SkTArray.h"
Robert Phillips7cd0bfe2019-11-20 16:08:10 -050016#include "src/core/SkArenaAlloc.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "src/gpu/GrTestUtils.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040018#include "src/gpu/GrTextureProxy.h"
joshualittb0a8a372014-09-23 09:50:21 -070019
Brian Salomon766098d2019-12-18 10:41:58 -050020#include <tuple>
21
joshualittb0a8a372014-09-23 09:50:21 -070022class SkMatrix;
bsalomon4b91f762015-05-19 09:29:46 -070023class GrCaps;
Robert Phillips1afd4cd2018-01-08 13:40:32 -050024class GrProxyProvider;
Brian Osman11052242016-10-27 14:47:55 -040025class GrRenderTargetContext;
Brian Salomon766098d2019-12-18 10:41:58 -050026class GrProcessorTestData;
Mike Reedd4706732016-11-15 16:44:34 -050027class GrTexture;
Brian Salomona1633922017-01-09 11:46:10 -050028class GrXPFactory;
Brian Salomon1c053642017-07-24 10:16:19 -040029class GrGeometryProcessor;
joshualittb0a8a372014-09-23 09:50:21 -070030
31namespace GrProcessorUnitTest {
bsalomon506c8022015-09-14 13:16:26 -070032
joshualittb0a8a372014-09-23 09:50:21 -070033// Used to access the dummy textures in TestCreate procs.
34enum {
35 kSkiaPMTextureIdx = 0,
36 kAlphaTextureIdx = 1,
37};
38
bsalomon506c8022015-09-14 13:16:26 -070039/** This allows parent FPs to implement a test create with known leaf children in order to avoid
40creating an unbounded FP tree which may overflow various shader limits. */
Brian Salomonaff329b2017-08-11 09:40:37 -040041std::unique_ptr<GrFragmentProcessor> MakeChildFP(GrProcessorTestData*);
bsalomon506c8022015-09-14 13:16:26 -070042
joshualitt2e3b3e32014-12-09 13:31:14 -080043}
44
joshualitt0067ff52015-07-08 14:26:19 -070045/*
46 * GrProcessorTestData is an argument struct to TestCreate functions
47 * fTextures are valid textures that can optionally be used to construct
Greg Danielb58a3c72020-01-23 10:05:14 -050048 * TextureSampler. The first texture has a RGBA8 format and the second has Alpha8 format for the
49 * specific backend API. TestCreate functions are also free to create additional textures using
joshualitt0067ff52015-07-08 14:26:19 -070050 * the GrContext.
51 */
Brian Salomon766098d2019-12-18 10:41:58 -050052class GrProcessorTestData {
53public:
Greg Daniel026a60c2020-02-12 10:53:51 -050054 using ViewInfo = std::tuple<GrSurfaceProxyView, GrColorType, SkAlphaType>;
John Stilese911ce52020-07-17 13:32:27 -040055
John Stiles6609cb62020-07-17 14:52:12 -040056 GrProcessorTestData(SkRandom* random, GrRecordingContext* context,
57 int numViews, const ViewInfo views[],
58 std::unique_ptr<GrFragmentProcessor> inputFP = nullptr);
John Stilese911ce52020-07-17 13:32:27 -040059 GrProcessorTestData(const GrProcessorTestData&) = delete;
60 ~GrProcessorTestData();
Robert Phillips757914d2017-01-25 15:48:30 -050061
Robert Phillips4e105e22020-07-16 09:18:50 -040062 GrRecordingContext* context() { return fContext; }
Robert Phillips1afd4cd2018-01-08 13:40:32 -050063 GrProxyProvider* proxyProvider();
Robert Phillips296b1cc2017-03-15 10:42:12 -040064 const GrCaps* caps();
Robert Phillips7cd0bfe2019-11-20 16:08:10 -050065 SkArenaAlloc* allocator() { return fArena.get(); }
John Stiles6609cb62020-07-17 14:52:12 -040066 std::unique_ptr<GrFragmentProcessor> inputFP();
Robert Phillips757914d2017-01-25 15:48:30 -050067
Greg Daniel026a60c2020-02-12 10:53:51 -050068 ViewInfo randomView();
69 ViewInfo randomAlphaOnlyView();
Brian Salomon766098d2019-12-18 10:41:58 -050070
71 SkRandom* fRandom;
72
Robert Phillips757914d2017-01-25 15:48:30 -050073private:
Robert Phillips4e105e22020-07-16 09:18:50 -040074 GrRecordingContext* fContext;
Greg Daniel026a60c2020-02-12 10:53:51 -050075 SkTArray<ViewInfo> fViews;
Robert Phillips7cd0bfe2019-11-20 16:08:10 -050076 std::unique_ptr<SkArenaAlloc> fArena;
John Stilese911ce52020-07-17 13:32:27 -040077 std::unique_ptr<GrFragmentProcessor> fInputFP;
joshualitt0067ff52015-07-08 14:26:19 -070078};
79
joshualittb0a8a372014-09-23 09:50:21 -070080class GrProcessor;
81class GrTexture;
82
Brian Salomon1c053642017-07-24 10:16:19 -040083template <class ProcessorSmartPtr>
84class GrProcessorTestFactory : private SkNoncopyable {
joshualittb0a8a372014-09-23 09:50:21 -070085public:
Brian Salomon1c053642017-07-24 10:16:19 -040086 using MakeProc = ProcessorSmartPtr (*)(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -070087
bungeman06ca8ec2016-06-09 08:01:03 -070088 GrProcessorTestFactory(MakeProc makeProc) {
89 fMakeProc = makeProc;
joshualittb0a8a372014-09-23 09:50:21 -070090 GetFactories()->push_back(this);
91 }
92
bsalomonb5b60322015-09-14 12:26:33 -070093 /** Pick a random factory function and create a processor. */
Brian Salomon1c053642017-07-24 10:16:19 -040094 static ProcessorSmartPtr Make(GrProcessorTestData* data) {
joshualitt9e87fa72014-10-09 13:12:35 -070095 VerifyFactoryCount();
Ben Wagnerf1344ac2019-05-10 15:01:53 -040096 if (GetFactories()->count() == 0) {
97 return nullptr;
98 }
joshualitt0067ff52015-07-08 14:26:19 -070099 uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
bungeman06ca8ec2016-06-09 08:01:03 -0700100 return MakeIdx(idx, data);
bsalomonb5b60322015-09-14 12:26:33 -0700101 }
102
103 /** Number of registered factory functions */
104 static int Count() { return GetFactories()->count(); }
105
106 /** Use factory function at Index idx to create a processor. */
Brian Salomon94e0b112017-07-28 16:02:46 -0400107 static ProcessorSmartPtr MakeIdx(int idx, GrProcessorTestData* data) {
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400108 SkASSERT(idx < GetFactories()->count());
Brian Salomon1c053642017-07-24 10:16:19 -0400109 GrProcessorTestFactory<ProcessorSmartPtr>* factory = (*GetFactories())[idx];
110 ProcessorSmartPtr processor = factory->fMakeProc(data);
Brian Salomona1633922017-01-09 11:46:10 -0500111 SkASSERT(processor);
112 return processor;
joshualittb0a8a372014-09-23 09:50:21 -0700113 }
114
Brian Salomona1633922017-01-09 11:46:10 -0500115private:
116 /**
joshualitt9e87fa72014-10-09 13:12:35 -0700117 * A test function which verifies the count of factories.
118 */
119 static void VerifyFactoryCount();
120
bungeman06ca8ec2016-06-09 08:01:03 -0700121 MakeProc fMakeProc;
joshualittb0a8a372014-09-23 09:50:21 -0700122
Brian Salomon1c053642017-07-24 10:16:19 -0400123 static SkTArray<GrProcessorTestFactory<ProcessorSmartPtr>*, true>* GetFactories();
joshualittb0a8a372014-09-23 09:50:21 -0700124};
125
Brian Salomonaff329b2017-08-11 09:40:37 -0400126using GrFragmentProcessorTestFactory = GrProcessorTestFactory<std::unique_ptr<GrFragmentProcessor>>;
Robert Phillips7cd0bfe2019-11-20 16:08:10 -0500127using GrGeometryProcessorTestFactory = GrProcessorTestFactory<GrGeometryProcessor*>;
Brian Salomon1c053642017-07-24 10:16:19 -0400128
Brian Salomona1633922017-01-09 11:46:10 -0500129class GrXPFactoryTestFactory : private SkNoncopyable {
130public:
131 using GetFn = const GrXPFactory*(GrProcessorTestData*);
132
133 GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) { GetFactories()->push_back(this); }
134
135 static const GrXPFactory* Get(GrProcessorTestData* data) {
136 VerifyFactoryCount();
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400137 if (GetFactories()->count() == 0) {
138 return nullptr;
139 }
Brian Salomona1633922017-01-09 11:46:10 -0500140 uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
141 const GrXPFactory* xpf = (*GetFactories())[idx]->fGetProc(data);
142 SkASSERT(xpf);
143 return xpf;
144 }
145
146private:
147 static void VerifyFactoryCount();
148
149 GetFn* fGetProc;
150 static SkTArray<GrXPFactoryTestFactory*, true>* GetFactories();
151};
152
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400153#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
154
joshualittb0a8a372014-09-23 09:50:21 -0700155/** GrProcessor subclasses should insert this macro in their declaration to be included in the
156 * program generation unit test.
157 */
Brian Salomon1c053642017-07-24 10:16:19 -0400158#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \
159 static GrGeometryProcessorTestFactory gTestFactory SK_UNUSED; \
Robert Phillips7cd0bfe2019-11-20 16:08:10 -0500160 static GrGeometryProcessor* TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700161
Brian Salomon1c053642017-07-24 10:16:19 -0400162#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \
163 static GrFragmentProcessorTestFactory gTestFactory SK_UNUSED; \
Brian Salomonaff329b2017-08-11 09:40:37 -0400164 static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700165
egdanielc2304142014-12-11 13:15:13 -0800166#define GR_DECLARE_XP_FACTORY_TEST \
Brian Salomona1633922017-01-09 11:46:10 -0500167 static GrXPFactoryTestFactory gTestFactory SK_UNUSED; \
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400168 static const GrXPFactory* TestGet(GrProcessorTestData*);
egdanielc2304142014-12-11 13:15:13 -0800169
joshualittb0a8a372014-09-23 09:50:21 -0700170/** GrProcessor subclasses should insert this macro in their implementation file. They must then
171 * also implement this static function:
joshualitt0067ff52015-07-08 14:26:19 -0700172 * GrProcessor* TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700173 */
Brian Salomon1c053642017-07-24 10:16:19 -0400174#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect) \
175 GrFragmentProcessorTestFactory Effect::gTestFactory(Effect::TestCreate)
Brian Salomon003312a2017-01-09 16:00:33 +0000176
Brian Salomon1c053642017-07-24 10:16:19 -0400177#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect) \
178 GrGeometryProcessorTestFactory Effect::gTestFactory(Effect::TestCreate)
Brian Salomona1633922017-01-09 11:46:10 -0500179
180#define GR_DEFINE_XP_FACTORY_TEST(Factory) \
181 GrXPFactoryTestFactory Factory::gTestFactory(Factory::TestGet)
joshualittb0a8a372014-09-23 09:50:21 -0700182
183#else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
184
185// The unit test relies on static initializers. Just declare the TestCreate function so that
186// its definitions will compile.
187#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \
Brian Salomonaff329b2017-08-11 09:40:37 -0400188 static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700189#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
190
191// The unit test relies on static initializers. Just declare the TestCreate function so that
192// its definitions will compile.
193#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \
Robert Phillips7cd0bfe2019-11-20 16:08:10 -0500194 static GrGeometryProcessor* TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700195#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
196
Brian Salomona1633922017-01-09 11:46:10 -0500197// The unit test relies on static initializers. Just declare the TestGet function so that
198// its definitions will compile.
199#define GR_DECLARE_XP_FACTORY_TEST \
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400200 const GrXPFactory* TestGet(GrProcessorTestData*);
Brian Salomona1633922017-01-09 11:46:10 -0500201#define GR_DEFINE_XP_FACTORY_TEST(X)
202
Hal Canary6f6961e2017-01-31 13:50:44 -0500203#endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
204#else // GR_TEST_UTILS
205 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
206 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
207 #define GR_DECLARE_XP_FACTORY_TEST
208 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
209 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
210 #define GR_DEFINE_XP_FACTORY_TEST(...)
211 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
212 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
213 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
214 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
215 #define GR_DECLARE_XP_FACTORY_TEST
216 #define GR_DEFINE_XP_FACTORY_TEST(...)
217#endif // GR_TEST_UTILS
218#endif // GrProcessorUnitTest_DEFINED