blob: 739b2f0c263cc09ff5792e336c557e5ca12e8f97 [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
Hal Canary6f6961e2017-01-31 13:50:44 -050011#include "SkTypes.h"
12
13#if GR_TEST_UTILS
14
Robert Phillips757914d2017-01-25 15:48:30 -050015#include "../private/GrTextureProxy.h"
bungemanbf521ff2016-02-17 13:13:44 -080016#include "../private/SkTArray.h"
joshualitt4eaf9ce2015-04-28 13:31:18 -070017#include "GrTestUtils.h"
joshualittb0a8a372014-09-23 09:50:21 -070018
19class SkMatrix;
bsalomon4b91f762015-05-19 09:29:46 -070020class GrCaps;
joshualitt0067ff52015-07-08 14:26:19 -070021class GrContext;
Brian Osman11052242016-10-27 14:47:55 -040022class GrRenderTargetContext;
bsalomon506c8022015-09-14 13:16:26 -070023struct GrProcessorTestData;
Mike Reedd4706732016-11-15 16:44:34 -050024class GrTexture;
Brian Salomona1633922017-01-09 11:46:10 -050025class GrXPFactory;
Brian Salomon1c053642017-07-24 10:16:19 -040026class GrGeometryProcessor;
joshualittb0a8a372014-09-23 09:50:21 -070027
28namespace GrProcessorUnitTest {
bsalomon506c8022015-09-14 13:16:26 -070029
joshualittb0a8a372014-09-23 09:50:21 -070030// Used to access the dummy textures in TestCreate procs.
31enum {
32 kSkiaPMTextureIdx = 0,
33 kAlphaTextureIdx = 1,
34};
35
bsalomon506c8022015-09-14 13:16:26 -070036/** This allows parent FPs to implement a test create with known leaf children in order to avoid
37creating an unbounded FP tree which may overflow various shader limits. */
Brian Salomonaff329b2017-08-11 09:40:37 -040038std::unique_ptr<GrFragmentProcessor> MakeChildFP(GrProcessorTestData*);
bsalomon506c8022015-09-14 13:16:26 -070039
joshualitt2e3b3e32014-12-09 13:31:14 -080040}
41
joshualitt0067ff52015-07-08 14:26:19 -070042/*
43 * GrProcessorTestData is an argument struct to TestCreate functions
44 * fTextures are valid textures that can optionally be used to construct
Brian Salomon0bbecb22016-11-17 11:38:22 -050045 * TextureSampler. The first texture has config kSkia8888_GrPixelConfig and the second has
joshualitt0067ff52015-07-08 14:26:19 -070046 * kAlpha_8_GrPixelConfig. TestCreate functions are also free to create additional textures using
47 * the GrContext.
48 */
49struct GrProcessorTestData {
50 GrProcessorTestData(SkRandom* random,
51 GrContext* context,
Brian Osman11052242016-10-27 14:47:55 -040052 const GrRenderTargetContext* renderTargetContext,
Robert Phillipse78b7252017-04-06 07:59:41 -040053 sk_sp<GrTextureProxy> proxies[2])
Robert Phillipsdbc8eeb2017-02-21 10:04:31 -050054 : fRandom(random)
55 , fRenderTargetContext(renderTargetContext)
56 , fContext(context) {
Robert Phillipsbb581ce2017-05-29 15:05:15 -040057 SkASSERT(proxies[0] && proxies[1]);
Robert Phillipse78b7252017-04-06 07:59:41 -040058 fProxies[0] = proxies[0];
59 fProxies[1] = proxies[1];
joshualitt0067ff52015-07-08 14:26:19 -070060 }
61 SkRandom* fRandom;
Brian Osman11052242016-10-27 14:47:55 -040062 const GrRenderTargetContext* fRenderTargetContext;
Robert Phillips757914d2017-01-25 15:48:30 -050063
64 GrContext* context() { return fContext; }
Robert Phillips296b1cc2017-03-15 10:42:12 -040065 GrResourceProvider* resourceProvider();
66 const GrCaps* caps();
Robert Phillips63c67462017-02-15 14:19:01 -050067 sk_sp<GrTextureProxy> textureProxy(int index) { return fProxies[index]; }
Robert Phillips757914d2017-01-25 15:48:30 -050068
69private:
Robert Phillipsdbc8eeb2017-02-21 10:04:31 -050070 GrContext* fContext;
Robert Phillips63c67462017-02-15 14:19:01 -050071 sk_sp<GrTextureProxy> fProxies[2];
joshualitt0067ff52015-07-08 14:26:19 -070072};
73
joshualittb0a8a372014-09-23 09:50:21 -070074#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
75
joshualittb0a8a372014-09-23 09:50:21 -070076class GrProcessor;
77class GrTexture;
78
Brian Salomon1c053642017-07-24 10:16:19 -040079template <class ProcessorSmartPtr>
80class GrProcessorTestFactory : private SkNoncopyable {
joshualittb0a8a372014-09-23 09:50:21 -070081public:
Brian Salomon1c053642017-07-24 10:16:19 -040082 using Processor = typename ProcessorSmartPtr::element_type;
83 using MakeProc = ProcessorSmartPtr (*)(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -070084
bungeman06ca8ec2016-06-09 08:01:03 -070085 GrProcessorTestFactory(MakeProc makeProc) {
86 fMakeProc = makeProc;
joshualittb0a8a372014-09-23 09:50:21 -070087 GetFactories()->push_back(this);
88 }
89
bsalomonb5b60322015-09-14 12:26:33 -070090 /** Pick a random factory function and create a processor. */
Brian Salomon1c053642017-07-24 10:16:19 -040091 static ProcessorSmartPtr Make(GrProcessorTestData* data) {
joshualitt9e87fa72014-10-09 13:12:35 -070092 VerifyFactoryCount();
93 SkASSERT(GetFactories()->count());
joshualitt0067ff52015-07-08 14:26:19 -070094 uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
bungeman06ca8ec2016-06-09 08:01:03 -070095 return MakeIdx(idx, data);
bsalomonb5b60322015-09-14 12:26:33 -070096 }
97
98 /** Number of registered factory functions */
99 static int Count() { return GetFactories()->count(); }
100
101 /** Use factory function at Index idx to create a processor. */
Brian Salomon94e0b112017-07-28 16:02:46 -0400102 static ProcessorSmartPtr MakeIdx(int idx, GrProcessorTestData* data) {
Brian Salomon1c053642017-07-24 10:16:19 -0400103 GrProcessorTestFactory<ProcessorSmartPtr>* factory = (*GetFactories())[idx];
104 ProcessorSmartPtr processor = factory->fMakeProc(data);
Brian Salomona1633922017-01-09 11:46:10 -0500105 SkASSERT(processor);
106 return processor;
joshualittb0a8a372014-09-23 09:50:21 -0700107 }
108
Brian Salomona1633922017-01-09 11:46:10 -0500109private:
110 /**
joshualitt9e87fa72014-10-09 13:12:35 -0700111 * A test function which verifies the count of factories.
112 */
113 static void VerifyFactoryCount();
114
bungeman06ca8ec2016-06-09 08:01:03 -0700115 MakeProc fMakeProc;
joshualittb0a8a372014-09-23 09:50:21 -0700116
Brian Salomon1c053642017-07-24 10:16:19 -0400117 static SkTArray<GrProcessorTestFactory<ProcessorSmartPtr>*, true>* GetFactories();
joshualittb0a8a372014-09-23 09:50:21 -0700118};
119
Brian Salomonaff329b2017-08-11 09:40:37 -0400120using GrFragmentProcessorTestFactory = GrProcessorTestFactory<std::unique_ptr<GrFragmentProcessor>>;
Brian Salomon1c053642017-07-24 10:16:19 -0400121using GrGeometryProcessorTestFactory = GrProcessorTestFactory<sk_sp<GrGeometryProcessor>>;
122
Brian Salomona1633922017-01-09 11:46:10 -0500123class GrXPFactoryTestFactory : private SkNoncopyable {
124public:
125 using GetFn = const GrXPFactory*(GrProcessorTestData*);
126
127 GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) { GetFactories()->push_back(this); }
128
129 static const GrXPFactory* Get(GrProcessorTestData* data) {
130 VerifyFactoryCount();
131 SkASSERT(GetFactories()->count());
132 uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
133 const GrXPFactory* xpf = (*GetFactories())[idx]->fGetProc(data);
134 SkASSERT(xpf);
135 return xpf;
136 }
137
138private:
139 static void VerifyFactoryCount();
140
141 GetFn* fGetProc;
142 static SkTArray<GrXPFactoryTestFactory*, true>* GetFactories();
143};
144
joshualittb0a8a372014-09-23 09:50:21 -0700145/** GrProcessor subclasses should insert this macro in their declaration to be included in the
146 * program generation unit test.
147 */
Brian Salomon1c053642017-07-24 10:16:19 -0400148#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \
149 static GrGeometryProcessorTestFactory gTestFactory SK_UNUSED; \
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400150 static sk_sp<GrGeometryProcessor> TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700151
Brian Salomon1c053642017-07-24 10:16:19 -0400152#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \
153 static GrFragmentProcessorTestFactory gTestFactory SK_UNUSED; \
Brian Salomonaff329b2017-08-11 09:40:37 -0400154 static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700155
egdanielc2304142014-12-11 13:15:13 -0800156#define GR_DECLARE_XP_FACTORY_TEST \
Brian Salomona1633922017-01-09 11:46:10 -0500157 static GrXPFactoryTestFactory gTestFactory SK_UNUSED; \
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400158 static const GrXPFactory* TestGet(GrProcessorTestData*);
egdanielc2304142014-12-11 13:15:13 -0800159
joshualittb0a8a372014-09-23 09:50:21 -0700160/** GrProcessor subclasses should insert this macro in their implementation file. They must then
161 * also implement this static function:
joshualitt0067ff52015-07-08 14:26:19 -0700162 * GrProcessor* TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700163 */
Brian Salomon1c053642017-07-24 10:16:19 -0400164#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect) \
165 GrFragmentProcessorTestFactory Effect::gTestFactory(Effect::TestCreate)
Brian Salomon003312a2017-01-09 16:00:33 +0000166
Brian Salomon1c053642017-07-24 10:16:19 -0400167#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect) \
168 GrGeometryProcessorTestFactory Effect::gTestFactory(Effect::TestCreate)
Brian Salomona1633922017-01-09 11:46:10 -0500169
170#define GR_DEFINE_XP_FACTORY_TEST(Factory) \
171 GrXPFactoryTestFactory Factory::gTestFactory(Factory::TestGet)
joshualittb0a8a372014-09-23 09:50:21 -0700172
173#else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
174
175// The unit test relies on static initializers. Just declare the TestCreate function so that
176// its definitions will compile.
177#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \
Brian Salomonaff329b2017-08-11 09:40:37 -0400178 static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700179#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
180
181// The unit test relies on static initializers. Just declare the TestCreate function so that
182// its definitions will compile.
183#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400184 static sk_sp<GrGeometryProcessor> TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700185#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
186
Brian Salomona1633922017-01-09 11:46:10 -0500187// The unit test relies on static initializers. Just declare the TestGet function so that
188// its definitions will compile.
189#define GR_DECLARE_XP_FACTORY_TEST \
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400190 const GrXPFactory* TestGet(GrProcessorTestData*);
Brian Salomona1633922017-01-09 11:46:10 -0500191#define GR_DEFINE_XP_FACTORY_TEST(X)
192
Hal Canary6f6961e2017-01-31 13:50:44 -0500193#endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
194#else // GR_TEST_UTILS
195 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
196 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
197 #define GR_DECLARE_XP_FACTORY_TEST
198 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
199 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
200 #define GR_DEFINE_XP_FACTORY_TEST(...)
201 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
202 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
203 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
204 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
205 #define GR_DECLARE_XP_FACTORY_TEST
206 #define GR_DEFINE_XP_FACTORY_TEST(...)
207#endif // GR_TEST_UTILS
208#endif // GrProcessorUnitTest_DEFINED