blob: 5086028049d424c7bc16df16d7b5f4df4896619c [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;
joshualitt0067ff52015-07-08 14:26:19 -070024class GrContext;
Robert Phillips1afd4cd2018-01-08 13:40:32 -050025class GrProxyProvider;
Brian Osman11052242016-10-27 14:47:55 -040026class GrRenderTargetContext;
Brian Salomon766098d2019-12-18 10:41:58 -050027class GrProcessorTestData;
Mike Reedd4706732016-11-15 16:44:34 -050028class GrTexture;
Brian Salomona1633922017-01-09 11:46:10 -050029class GrXPFactory;
Brian Salomon1c053642017-07-24 10:16:19 -040030class GrGeometryProcessor;
joshualittb0a8a372014-09-23 09:50:21 -070031
32namespace GrProcessorUnitTest {
bsalomon506c8022015-09-14 13:16:26 -070033
joshualittb0a8a372014-09-23 09:50:21 -070034// Used to access the dummy textures in TestCreate procs.
35enum {
36 kSkiaPMTextureIdx = 0,
37 kAlphaTextureIdx = 1,
38};
39
bsalomon506c8022015-09-14 13:16:26 -070040/** This allows parent FPs to implement a test create with known leaf children in order to avoid
41creating an unbounded FP tree which may overflow various shader limits. */
Brian Salomonaff329b2017-08-11 09:40:37 -040042std::unique_ptr<GrFragmentProcessor> MakeChildFP(GrProcessorTestData*);
bsalomon506c8022015-09-14 13:16:26 -070043
joshualitt2e3b3e32014-12-09 13:31:14 -080044}
45
joshualitt0067ff52015-07-08 14:26:19 -070046/*
47 * GrProcessorTestData is an argument struct to TestCreate functions
48 * fTextures are valid textures that can optionally be used to construct
Greg Danielb58a3c72020-01-23 10:05:14 -050049 * TextureSampler. The first texture has a RGBA8 format and the second has Alpha8 format for the
50 * specific backend API. TestCreate functions are also free to create additional textures using
joshualitt0067ff52015-07-08 14:26:19 -070051 * the GrContext.
52 */
Brian Salomon766098d2019-12-18 10:41:58 -050053class GrProcessorTestData {
54public:
Greg Daniel026a60c2020-02-12 10:53:51 -050055 using ViewInfo = std::tuple<GrSurfaceProxyView, GrColorType, SkAlphaType>;
56 GrProcessorTestData(SkRandom* random, GrContext* context, int numProxies, const ViewInfo[]);
Robert Phillips757914d2017-01-25 15:48:30 -050057
58 GrContext* context() { return fContext; }
Robert Phillips296b1cc2017-03-15 10:42:12 -040059 GrResourceProvider* resourceProvider();
Robert Phillips1afd4cd2018-01-08 13:40:32 -050060 GrProxyProvider* proxyProvider();
Robert Phillips296b1cc2017-03-15 10:42:12 -040061 const GrCaps* caps();
Robert Phillips7cd0bfe2019-11-20 16:08:10 -050062 SkArenaAlloc* allocator() { return fArena.get(); }
Robert Phillips757914d2017-01-25 15:48:30 -050063
Greg Daniel026a60c2020-02-12 10:53:51 -050064 ViewInfo randomView();
65 ViewInfo randomAlphaOnlyView();
Brian Salomon766098d2019-12-18 10:41:58 -050066
67 SkRandom* fRandom;
68
Robert Phillips757914d2017-01-25 15:48:30 -050069private:
Robert Phillipsdbc8eeb2017-02-21 10:04:31 -050070 GrContext* fContext;
Greg Daniel026a60c2020-02-12 10:53:51 -050071 SkTArray<ViewInfo> fViews;
Robert Phillips7cd0bfe2019-11-20 16:08:10 -050072 std::unique_ptr<SkArenaAlloc> fArena;
joshualitt0067ff52015-07-08 14:26:19 -070073};
74
joshualittb0a8a372014-09-23 09:50:21 -070075class GrProcessor;
76class GrTexture;
77
Brian Salomon1c053642017-07-24 10:16:19 -040078template <class ProcessorSmartPtr>
79class GrProcessorTestFactory : private SkNoncopyable {
joshualittb0a8a372014-09-23 09:50:21 -070080public:
Brian Salomon1c053642017-07-24 10:16:19 -040081 using MakeProc = ProcessorSmartPtr (*)(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -070082
bungeman06ca8ec2016-06-09 08:01:03 -070083 GrProcessorTestFactory(MakeProc makeProc) {
84 fMakeProc = makeProc;
joshualittb0a8a372014-09-23 09:50:21 -070085 GetFactories()->push_back(this);
86 }
87
bsalomonb5b60322015-09-14 12:26:33 -070088 /** Pick a random factory function and create a processor. */
Brian Salomon1c053642017-07-24 10:16:19 -040089 static ProcessorSmartPtr Make(GrProcessorTestData* data) {
joshualitt9e87fa72014-10-09 13:12:35 -070090 VerifyFactoryCount();
Ben Wagnerf1344ac2019-05-10 15:01:53 -040091 if (GetFactories()->count() == 0) {
92 return nullptr;
93 }
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) {
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400103 SkASSERT(idx < GetFactories()->count());
Brian Salomon1c053642017-07-24 10:16:19 -0400104 GrProcessorTestFactory<ProcessorSmartPtr>* factory = (*GetFactories())[idx];
105 ProcessorSmartPtr processor = factory->fMakeProc(data);
Brian Salomona1633922017-01-09 11:46:10 -0500106 SkASSERT(processor);
107 return processor;
joshualittb0a8a372014-09-23 09:50:21 -0700108 }
109
Brian Salomona1633922017-01-09 11:46:10 -0500110private:
111 /**
joshualitt9e87fa72014-10-09 13:12:35 -0700112 * A test function which verifies the count of factories.
113 */
114 static void VerifyFactoryCount();
115
bungeman06ca8ec2016-06-09 08:01:03 -0700116 MakeProc fMakeProc;
joshualittb0a8a372014-09-23 09:50:21 -0700117
Brian Salomon1c053642017-07-24 10:16:19 -0400118 static SkTArray<GrProcessorTestFactory<ProcessorSmartPtr>*, true>* GetFactories();
joshualittb0a8a372014-09-23 09:50:21 -0700119};
120
Brian Salomonaff329b2017-08-11 09:40:37 -0400121using GrFragmentProcessorTestFactory = GrProcessorTestFactory<std::unique_ptr<GrFragmentProcessor>>;
Robert Phillips7cd0bfe2019-11-20 16:08:10 -0500122using GrGeometryProcessorTestFactory = GrProcessorTestFactory<GrGeometryProcessor*>;
Brian Salomon1c053642017-07-24 10:16:19 -0400123
Brian Salomona1633922017-01-09 11:46:10 -0500124class GrXPFactoryTestFactory : private SkNoncopyable {
125public:
126 using GetFn = const GrXPFactory*(GrProcessorTestData*);
127
128 GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) { GetFactories()->push_back(this); }
129
130 static const GrXPFactory* Get(GrProcessorTestData* data) {
131 VerifyFactoryCount();
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400132 if (GetFactories()->count() == 0) {
133 return nullptr;
134 }
Brian Salomona1633922017-01-09 11:46:10 -0500135 uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->count() - 1);
136 const GrXPFactory* xpf = (*GetFactories())[idx]->fGetProc(data);
137 SkASSERT(xpf);
138 return xpf;
139 }
140
141private:
142 static void VerifyFactoryCount();
143
144 GetFn* fGetProc;
145 static SkTArray<GrXPFactoryTestFactory*, true>* GetFactories();
146};
147
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400148#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
149
joshualittb0a8a372014-09-23 09:50:21 -0700150/** GrProcessor subclasses should insert this macro in their declaration to be included in the
151 * program generation unit test.
152 */
Brian Salomon1c053642017-07-24 10:16:19 -0400153#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \
154 static GrGeometryProcessorTestFactory gTestFactory SK_UNUSED; \
Robert Phillips7cd0bfe2019-11-20 16:08:10 -0500155 static GrGeometryProcessor* TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700156
Brian Salomon1c053642017-07-24 10:16:19 -0400157#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \
158 static GrFragmentProcessorTestFactory gTestFactory SK_UNUSED; \
Brian Salomonaff329b2017-08-11 09:40:37 -0400159 static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700160
egdanielc2304142014-12-11 13:15:13 -0800161#define GR_DECLARE_XP_FACTORY_TEST \
Brian Salomona1633922017-01-09 11:46:10 -0500162 static GrXPFactoryTestFactory gTestFactory SK_UNUSED; \
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400163 static const GrXPFactory* TestGet(GrProcessorTestData*);
egdanielc2304142014-12-11 13:15:13 -0800164
joshualittb0a8a372014-09-23 09:50:21 -0700165/** GrProcessor subclasses should insert this macro in their implementation file. They must then
166 * also implement this static function:
joshualitt0067ff52015-07-08 14:26:19 -0700167 * GrProcessor* TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700168 */
Brian Salomon1c053642017-07-24 10:16:19 -0400169#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect) \
170 GrFragmentProcessorTestFactory Effect::gTestFactory(Effect::TestCreate)
Brian Salomon003312a2017-01-09 16:00:33 +0000171
Brian Salomon1c053642017-07-24 10:16:19 -0400172#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect) \
173 GrGeometryProcessorTestFactory Effect::gTestFactory(Effect::TestCreate)
Brian Salomona1633922017-01-09 11:46:10 -0500174
175#define GR_DEFINE_XP_FACTORY_TEST(Factory) \
176 GrXPFactoryTestFactory Factory::gTestFactory(Factory::TestGet)
joshualittb0a8a372014-09-23 09:50:21 -0700177
178#else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
179
180// The unit test relies on static initializers. Just declare the TestCreate function so that
181// its definitions will compile.
182#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \
Brian Salomonaff329b2017-08-11 09:40:37 -0400183 static std::unique_ptr<GrFragmentProcessor> TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700184#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
185
186// The unit test relies on static initializers. Just declare the TestCreate function so that
187// its definitions will compile.
188#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \
Robert Phillips7cd0bfe2019-11-20 16:08:10 -0500189 static GrGeometryProcessor* TestCreate(GrProcessorTestData*);
joshualittb0a8a372014-09-23 09:50:21 -0700190#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
191
Brian Salomona1633922017-01-09 11:46:10 -0500192// The unit test relies on static initializers. Just declare the TestGet function so that
193// its definitions will compile.
194#define GR_DECLARE_XP_FACTORY_TEST \
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400195 const GrXPFactory* TestGet(GrProcessorTestData*);
Brian Salomona1633922017-01-09 11:46:10 -0500196#define GR_DEFINE_XP_FACTORY_TEST(X)
197
Hal Canary6f6961e2017-01-31 13:50:44 -0500198#endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
199#else // GR_TEST_UTILS
200 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
201 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
202 #define GR_DECLARE_XP_FACTORY_TEST
203 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
204 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
205 #define GR_DEFINE_XP_FACTORY_TEST(...)
206 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST
207 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
208 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
209 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
210 #define GR_DECLARE_XP_FACTORY_TEST
211 #define GR_DEFINE_XP_FACTORY_TEST(...)
212#endif // GR_TEST_UTILS
213#endif // GrProcessorUnitTest_DEFINED