blob: 56afcc546ce6c2dc24da708e8ae63f0a3cd6e1ef [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
20class SkMatrix;
bsalomon4b91f762015-05-19 09:29:46 -070021class GrCaps;
joshualitt0067ff52015-07-08 14:26:19 -070022class GrContext;
Robert Phillips1afd4cd2018-01-08 13:40:32 -050023class GrProxyProvider;
Brian Osman11052242016-10-27 14:47:55 -040024class GrRenderTargetContext;
bsalomon506c8022015-09-14 13:16:26 -070025struct GrProcessorTestData;
Mike Reedd4706732016-11-15 16:44:34 -050026class GrTexture;
Brian Salomona1633922017-01-09 11:46:10 -050027class GrXPFactory;
Brian Salomon1c053642017-07-24 10:16:19 -040028class GrGeometryProcessor;
joshualittb0a8a372014-09-23 09:50:21 -070029
30namespace GrProcessorUnitTest {
bsalomon506c8022015-09-14 13:16:26 -070031
joshualittb0a8a372014-09-23 09:50:21 -070032// Used to access the dummy textures in TestCreate procs.
33enum {
34 kSkiaPMTextureIdx = 0,
35 kAlphaTextureIdx = 1,
36};
37
bsalomon506c8022015-09-14 13:16:26 -070038/** This allows parent FPs to implement a test create with known leaf children in order to avoid
39creating an unbounded FP tree which may overflow various shader limits. */
Brian Salomonaff329b2017-08-11 09:40:37 -040040std::unique_ptr<GrFragmentProcessor> MakeChildFP(GrProcessorTestData*);
bsalomon506c8022015-09-14 13:16:26 -070041
joshualitt2e3b3e32014-12-09 13:31:14 -080042}
43
joshualitt0067ff52015-07-08 14:26:19 -070044/*
45 * GrProcessorTestData is an argument struct to TestCreate functions
46 * fTextures are valid textures that can optionally be used to construct
Brian Salomon0bbecb22016-11-17 11:38:22 -050047 * TextureSampler. The first texture has config kSkia8888_GrPixelConfig and the second has
joshualitt0067ff52015-07-08 14:26:19 -070048 * kAlpha_8_GrPixelConfig. TestCreate functions are also free to create additional textures using
49 * the GrContext.
50 */
51struct GrProcessorTestData {
52 GrProcessorTestData(SkRandom* random,
53 GrContext* context,
Brian Osman11052242016-10-27 14:47:55 -040054 const GrRenderTargetContext* renderTargetContext,
Greg Danielc594e622019-10-15 14:01:49 -040055 sk_sp<GrTextureProxy> proxies[2],
56 GrColorType proxyColorTypes[2])
Robert Phillipsdbc8eeb2017-02-21 10:04:31 -050057 : fRandom(random)
58 , fRenderTargetContext(renderTargetContext)
59 , fContext(context) {
Robert Phillipsbb581ce2017-05-29 15:05:15 -040060 SkASSERT(proxies[0] && proxies[1]);
Robert Phillipse78b7252017-04-06 07:59:41 -040061 fProxies[0] = proxies[0];
62 fProxies[1] = proxies[1];
Greg Danielc594e622019-10-15 14:01:49 -040063 fProxyColorTypes[0] = proxyColorTypes[0];
64 fProxyColorTypes[1] = proxyColorTypes[1];
Robert Phillips7cd0bfe2019-11-20 16:08:10 -050065
66 fArena = std::unique_ptr<SkArenaAlloc>(new SkArenaAlloc(1000));
joshualitt0067ff52015-07-08 14:26:19 -070067 }
Robert Phillips7cd0bfe2019-11-20 16:08:10 -050068
joshualitt0067ff52015-07-08 14:26:19 -070069 SkRandom* fRandom;
Brian Osman11052242016-10-27 14:47:55 -040070 const GrRenderTargetContext* fRenderTargetContext;
Robert Phillips757914d2017-01-25 15:48:30 -050071
72 GrContext* context() { return fContext; }
Robert Phillips296b1cc2017-03-15 10:42:12 -040073 GrResourceProvider* resourceProvider();
Robert Phillips1afd4cd2018-01-08 13:40:32 -050074 GrProxyProvider* proxyProvider();
Robert Phillips296b1cc2017-03-15 10:42:12 -040075 const GrCaps* caps();
Robert Phillips63c67462017-02-15 14:19:01 -050076 sk_sp<GrTextureProxy> textureProxy(int index) { return fProxies[index]; }
Greg Danielc594e622019-10-15 14:01:49 -040077 GrColorType textureProxyColorType(int index) { return fProxyColorTypes[index]; }
Robert Phillips7cd0bfe2019-11-20 16:08:10 -050078 SkArenaAlloc* allocator() { return fArena.get(); }
Robert Phillips757914d2017-01-25 15:48:30 -050079
80private:
Robert Phillipsdbc8eeb2017-02-21 10:04:31 -050081 GrContext* fContext;
Robert Phillips63c67462017-02-15 14:19:01 -050082 sk_sp<GrTextureProxy> fProxies[2];
Greg Danielc594e622019-10-15 14:01:49 -040083 GrColorType fProxyColorTypes[2];
Robert Phillips7cd0bfe2019-11-20 16:08:10 -050084
85 std::unique_ptr<SkArenaAlloc> fArena;
joshualitt0067ff52015-07-08 14:26:19 -070086};
87
joshualittb0a8a372014-09-23 09:50:21 -070088class GrProcessor;
89class GrTexture;
90
Brian Salomon1c053642017-07-24 10:16:19 -040091template <class ProcessorSmartPtr>
92class GrProcessorTestFactory : private SkNoncopyable {
joshualittb0a8a372014-09-23 09:50:21 -070093public:
Brian Salomon1c053642017-07-24 10:16:19 -040094 using MakeProc = ProcessorSmartPtr (*)(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -070095
bungeman06ca8ec2016-06-09 08:01:03 -070096 GrProcessorTestFactory(MakeProc makeProc) {
97 fMakeProc = makeProc;
joshualittb0a8a372014-09-23 09:50:21 -070098 GetFactories()->push_back(this);
99 }
100
bsalomonb5b60322015-09-14 12:26:33 -0700101 /** Pick a random factory function and create a processor. */
Brian Salomon1c053642017-07-24 10:16:19 -0400102 static ProcessorSmartPtr Make(GrProcessorTestData* data) {
joshualitt9e87fa72014-10-09 13:12:35 -0700103 VerifyFactoryCount();
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400104 if (GetFactories()->count() == 0) {
105 return nullptr;
106 }
joshualitt0067ff52015-07-08 14:26:19 -0700107 uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
bungeman06ca8ec2016-06-09 08:01:03 -0700108 return MakeIdx(idx, data);
bsalomonb5b60322015-09-14 12:26:33 -0700109 }
110
111 /** Number of registered factory functions */
112 static int Count() { return GetFactories()->count(); }
113
114 /** Use factory function at Index idx to create a processor. */
Brian Salomon94e0b112017-07-28 16:02:46 -0400115 static ProcessorSmartPtr MakeIdx(int idx, GrProcessorTestData* data) {
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400116 SkASSERT(idx < GetFactories()->count());
Brian Salomon1c053642017-07-24 10:16:19 -0400117 GrProcessorTestFactory<ProcessorSmartPtr>* factory = (*GetFactories())[idx];
118 ProcessorSmartPtr processor = factory->fMakeProc(data);
Brian Salomona1633922017-01-09 11:46:10 -0500119 SkASSERT(processor);
120 return processor;
joshualittb0a8a372014-09-23 09:50:21 -0700121 }
122
Brian Salomona1633922017-01-09 11:46:10 -0500123private:
124 /**
joshualitt9e87fa72014-10-09 13:12:35 -0700125 * A test function which verifies the count of factories.
126 */
127 static void VerifyFactoryCount();
128
bungeman06ca8ec2016-06-09 08:01:03 -0700129 MakeProc fMakeProc;
joshualittb0a8a372014-09-23 09:50:21 -0700130
Brian Salomon1c053642017-07-24 10:16:19 -0400131 static SkTArray<GrProcessorTestFactory<ProcessorSmartPtr>*, true>* GetFactories();
joshualittb0a8a372014-09-23 09:50:21 -0700132};
133
Brian Salomonaff329b2017-08-11 09:40:37 -0400134using GrFragmentProcessorTestFactory = GrProcessorTestFactory<std::unique_ptr<GrFragmentProcessor>>;
Robert Phillips7cd0bfe2019-11-20 16:08:10 -0500135using GrGeometryProcessorTestFactory = GrProcessorTestFactory<GrGeometryProcessor*>;
Brian Salomon1c053642017-07-24 10:16:19 -0400136
Brian Salomona1633922017-01-09 11:46:10 -0500137class GrXPFactoryTestFactory : private SkNoncopyable {
138public:
139 using GetFn = const GrXPFactory*(GrProcessorTestData*);
140
141 GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) { GetFactories()->push_back(this); }
142
143 static const GrXPFactory* Get(GrProcessorTestData* data) {
144 VerifyFactoryCount();
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400145 if (GetFactories()->count() == 0) {
146 return nullptr;
147 }
Brian Salomona1633922017-01-09 11:46:10 -0500148 uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
149 const GrXPFactory* xpf = (*GetFactories())[idx]->fGetProc(data);
150 SkASSERT(xpf);
151 return xpf;
152 }
153
154private:
155 static void VerifyFactoryCount();
156
157 GetFn* fGetProc;
158 static SkTArray<GrXPFactoryTestFactory*, true>* GetFactories();
159};
160
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400161#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
162
joshualittb0a8a372014-09-23 09:50:21 -0700163/** GrProcessor subclasses should insert this macro in their declaration to be included in the
164 * program generation unit test.
165 */
Brian Salomon1c053642017-07-24 10:16:19 -0400166#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \
167 static GrGeometryProcessorTestFactory gTestFactory SK_UNUSED; \
Robert Phillips7cd0bfe2019-11-20 16:08:10 -0500168 static GrGeometryProcessor* TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700169
Brian Salomon1c053642017-07-24 10:16:19 -0400170#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \
171 static GrFragmentProcessorTestFactory gTestFactory SK_UNUSED; \
Brian Salomonaff329b2017-08-11 09:40:37 -0400172 static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700173
egdanielc2304142014-12-11 13:15:13 -0800174#define GR_DECLARE_XP_FACTORY_TEST \
Brian Salomona1633922017-01-09 11:46:10 -0500175 static GrXPFactoryTestFactory gTestFactory SK_UNUSED; \
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400176 static const GrXPFactory* TestGet(GrProcessorTestData*);
egdanielc2304142014-12-11 13:15:13 -0800177
joshualittb0a8a372014-09-23 09:50:21 -0700178/** GrProcessor subclasses should insert this macro in their implementation file. They must then
179 * also implement this static function:
joshualitt0067ff52015-07-08 14:26:19 -0700180 * GrProcessor* TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700181 */
Brian Salomon1c053642017-07-24 10:16:19 -0400182#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect) \
183 GrFragmentProcessorTestFactory Effect::gTestFactory(Effect::TestCreate)
Brian Salomon003312a2017-01-09 16:00:33 +0000184
Brian Salomon1c053642017-07-24 10:16:19 -0400185#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect) \
186 GrGeometryProcessorTestFactory Effect::gTestFactory(Effect::TestCreate)
Brian Salomona1633922017-01-09 11:46:10 -0500187
188#define GR_DEFINE_XP_FACTORY_TEST(Factory) \
189 GrXPFactoryTestFactory Factory::gTestFactory(Factory::TestGet)
joshualittb0a8a372014-09-23 09:50:21 -0700190
191#else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
192
193// The unit test relies on static initializers. Just declare the TestCreate function so that
194// its definitions will compile.
195#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \
Brian Salomonaff329b2017-08-11 09:40:37 -0400196 static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700197#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
198
199// The unit test relies on static initializers. Just declare the TestCreate function so that
200// its definitions will compile.
201#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \
Robert Phillips7cd0bfe2019-11-20 16:08:10 -0500202 static GrGeometryProcessor* TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700203#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
204
Brian Salomona1633922017-01-09 11:46:10 -0500205// The unit test relies on static initializers. Just declare the TestGet function so that
206// its definitions will compile.
207#define GR_DECLARE_XP_FACTORY_TEST \
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400208 const GrXPFactory* TestGet(GrProcessorTestData*);
Brian Salomona1633922017-01-09 11:46:10 -0500209#define GR_DEFINE_XP_FACTORY_TEST(X)
210
Hal Canary6f6961e2017-01-31 13:50:44 -0500211#endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
212#else // GR_TEST_UTILS
213 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
214 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
215 #define GR_DECLARE_XP_FACTORY_TEST
216 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
217 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
218 #define GR_DEFINE_XP_FACTORY_TEST(...)
219 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
220 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
221 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
222 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
223 #define GR_DECLARE_XP_FACTORY_TEST
224 #define GR_DEFINE_XP_FACTORY_TEST(...)
225#endif // GR_TEST_UTILS
226#endif // GrProcessorUnitTest_DEFINED