Flutter Engine
The Flutter Engine
GrProcessorUnitTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 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
9
10#include <memory>
11
16
17using namespace skia_private;
18
19#if defined(GR_TEST_UTILS)
20
22
23GrProcessorTestData::GrProcessorTestData(SkRandom* random, GrRecordingContext* context,
24 int maxTreeDepth, int numViews, const ViewInfo views[])
25 : GrProcessorTestData(random, context, maxTreeDepth, numViews, views,
26 /*inputFP=*/nullptr) {}
27
28GrProcessorTestData::GrProcessorTestData(SkRandom* random, GrRecordingContext* context,
29 int maxTreeDepth, int numViews, const ViewInfo views[],
30 std::unique_ptr<GrFragmentProcessor> inputFP)
31 : fRandom(random)
32 , fMaxTreeDepth(maxTreeDepth)
33 , fContext(context)
34 , fInputFP(std::move(inputFP)) {
35 fViews.reset(views, numViews);
36 fArena = std::make_unique<SkArenaAlloc>(1000);
37}
38
39GrProcessorTestData::~GrProcessorTestData() {}
40
41GrProxyProvider* GrProcessorTestData::proxyProvider() { return fContext->priv().proxyProvider(); }
42
43const GrCaps* GrProcessorTestData::caps() { return fContext->priv().caps(); }
44
45std::unique_ptr<GrFragmentProcessor> GrProcessorTestData::inputFP() {
46 if (fCurrentTreeDepth == 0) {
47 // At the top level of the tree, provide the input FP from the test data.
48 return fInputFP ? fInputFP->clone() : nullptr;
49 } else {
50 // At deeper levels of recursion, synthesize a random input.
52 }
53}
54
55GrProcessorTestData::ViewInfo GrProcessorTestData::randomView() {
56 SkASSERT(!fViews.empty());
57 return fViews[fRandom->nextULessThan(fViews.size())];
58}
59
60GrProcessorTestData::ViewInfo GrProcessorTestData::randomAlphaOnlyView() {
61 int numAlphaOnly = 0;
62 for (const auto& [v, ct, at] : fViews) {
63 if (GrColorTypeIsAlphaOnly(ct)) {
64 ++numAlphaOnly;
65 }
66 }
67 SkASSERT(numAlphaOnly);
68 int idx = fRandom->nextULessThan(numAlphaOnly);
69 for (const auto& [v, ct, at] : fViews) {
70 if (GrColorTypeIsAlphaOnly(ct) && !idx--) {
71 return {v, ct, at};
72 }
73 }
75}
76
77template <class ProcessorSmartPtr>
78GrProcessorTestFactory<ProcessorSmartPtr>::GrProcessorTestFactory(MakeProc makeProc,
79 const char* name)
80 : fMakeProc(makeProc), fName(name) {
81 GetFactories()->push_back(this);
82}
83
84template <class ProcessorSmartPtr>
85ProcessorSmartPtr GrProcessorTestFactory<ProcessorSmartPtr>::Make(GrProcessorTestData* data) {
86 VerifyFactoryCount();
87 if (GetFactories()->size() == 0) {
88 return nullptr;
89 }
90 uint32_t idx = data->fRandom->nextULessThan(GetFactories()->size());
91 return MakeIdx(idx, data);
92}
93
94template <class ProcessorSmartPtr>
95ProcessorSmartPtr GrProcessorTestFactory<ProcessorSmartPtr>::MakeIdx(int idx,
96 GrProcessorTestData* data) {
97 SkASSERT(idx < GetFactories()->size());
98 GrProcessorTestFactory<ProcessorSmartPtr>* factory = (*GetFactories())[idx];
99 ProcessorSmartPtr processor = factory->fMakeProc(data);
100 if (processor == nullptr) {
101 SK_ABORT("%s: TestCreate returned null", factory->fName.c_str());
102 }
103 return processor;
104}
105
106template <class ProcessorSmartPtr>
107int GrProcessorTestFactory<ProcessorSmartPtr>::Count() {
108 return GetFactories()->size();
109}
110
111GrXPFactoryTestFactory::GrXPFactoryTestFactory(GetFn* getProc) : fGetProc(getProc) {
112 GetFactories()->push_back(this);
113}
114
115const GrXPFactory* GrXPFactoryTestFactory::Get(GrProcessorTestData* data) {
116 VerifyFactoryCount();
117 if (GetFactories()->size() == 0) {
118 return nullptr;
119 }
120 uint32_t idx = data->fRandom->nextRangeU(0, GetFactories()->size() - 1);
121 const GrXPFactory* xpf = (*GetFactories())[idx]->fGetProc(data);
122 SkASSERT(xpf);
123 return xpf;
124}
125
126/*
127 * Originally these were both in the processor unit test header, but then it seemed to cause linker
128 * problems on android.
129 */
130template <>
131TArray<GrFragmentProcessorTestFactory*, true>* GrFragmentProcessorTestFactory::GetFactories() {
133 return &gFactories;
134}
135
136template <>
137TArray<GrGeometryProcessorTestFactory*, true>* GrGeometryProcessorTestFactory::GetFactories() {
139 return &gFactories;
140}
141
142TArray<GrXPFactoryTestFactory*, true>* GrXPFactoryTestFactory::GetFactories() {
144 return &gFactories;
145}
146
147/*
148 * To ensure we always have successful static initialization, before creating from the factories
149 * we verify the count is as expected. If a new factory is added, then these numbers must be
150 * manually adjusted.
151 */
152static constexpr int kFPFactoryCount = 10;
153static constexpr int kGPFactoryCount = 14;
154static constexpr int kXPFactoryCount = 4;
155
156template <> void GrFragmentProcessorTestFactory::VerifyFactoryCount() {
157 if (kFPFactoryCount != GetFactories()->size()) {
158 SkDebugf("\nExpected %d fragment processor factories, found %d.\n", kFPFactoryCount,
159 GetFactories()->size());
160 SK_ABORT("Wrong number of fragment processor factories!");
161 }
162}
163
164template <> void GrGeometryProcessorTestFactory::VerifyFactoryCount() {
165 if (kGPFactoryCount != GetFactories()->size()) {
166 SkDebugf("\nExpected %d geometry processor factories, found %d.\n", kGPFactoryCount,
167 GetFactories()->size());
168 SK_ABORT("Wrong number of geometry processor factories!");
169 }
170}
171
172void GrXPFactoryTestFactory::VerifyFactoryCount() {
173 if (kXPFactoryCount != GetFactories()->size()) {
174 SkDebugf("\nExpected %d xp factory factories, found %d.\n", kXPFactoryCount,
175 GetFactories()->size());
176 SK_ABORT("Wrong number of xp factory factories!");
177 }
178}
179
180std::unique_ptr<GrFragmentProcessor> GrProcessorUnitTest::MakeChildFP(GrProcessorTestData* data) {
181 std::unique_ptr<GrFragmentProcessor> fp;
182
183 ++data->fCurrentTreeDepth;
184 if (data->fCurrentTreeDepth > data->fMaxTreeDepth) {
185 // We've gone too deep, but we can't necessarily return null without risking an assertion.
186 // Instead, return a known-simple zero-child FP. This limits the recursion, and the
187 // generated FP will be rejected by the numNonNullChildProcessors check below.
189 } else {
190 for (;;) {
192 SkASSERT(fp);
193 // If our tree has already reached its max depth, we must reject FPs that have children.
194 if (data->fCurrentTreeDepth < data->fMaxTreeDepth ||
195 fp->numNonNullChildProcessors() == 0) {
196 break;
197 }
198 }
199 }
200
201 --data->fCurrentTreeDepth;
202 return fp;
203}
204
205std::unique_ptr<GrFragmentProcessor> GrProcessorUnitTest::MakeOptionalChildFP(
206 GrProcessorTestData* data) {
207 return data->fRandom->nextBool() ? MakeChildFP(data) : nullptr;
208}
209
210template class GrProcessorTestFactory<GrGeometryProcessor*>;
211template class GrProcessorTestFactory<std::unique_ptr<GrFragmentProcessor>>;
212
213#endif
const char * fName
static constexpr bool GrColorTypeIsAlphaOnly(GrColorType ct)
Definition: GrTypesPriv.h:888
#define SkUNREACHABLE
Definition: SkAssert.h:135
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkASSERT(cond)
Definition: SkAssert.h:116
constexpr SkPMColor4f SK_PMColor4fTRANSPARENT
Definition: SkColorData.h:378
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
const Context & fContext
Definition: GrCaps.h:57
static std::unique_ptr< GrFragmentProcessor > MakeColor(SkPMColor4f color)
const GrXPFactory * Get(SkBlendMode mode)
GrFPResult MakeChildFP(const SkRuntimeEffect::ChildPtr &child, const GrFPArgs &childArgs)
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
const uint32_t fp
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
Definition: ref_ptr.h:256
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63