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