blob: 654dce0afb94ea1721c1701bbd52d0e17d3e53cc [file] [log] [blame]
bsalomon@google.coma8e686e2011-08-16 15:45:58 +00001/*
2 * Copyright 2011 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
bsalomon@google.comd4726202012-08-03 14:34:46 +00008// This is a GPU-backend specific test. It relies on static intializers to work
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +00009
bsalomon@google.com2a48c3a2012-08-03 14:54:45 +000010#include "SkTypes.h"
11
Brian Osmanc7ad40f2018-05-31 14:27:17 -040012#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
bsalomon@google.com2a48c3a2012-08-03 14:54:45 +000013
bsalomon6f7f2012015-03-16 14:00:52 -070014#include "GrAutoLocaleSetter.h"
bsalomon@google.com67b915d2013-02-04 16:13:32 +000015#include "GrContextFactory.h"
csmartdaltonbde96c62016-08-31 12:54:46 -070016#include "GrContextPriv.h"
Brian Salomon5ec9def2016-12-20 15:34:05 -050017#include "GrDrawOpTest.h"
robertphillipsa13e2022015-11-11 12:01:09 -080018#include "GrDrawingManager.h"
egdaniel8dd688b2015-01-22 10:16:09 -080019#include "GrPipeline.h"
Brian Salomon5ec9def2016-12-20 15:34:05 -050020#include "GrRenderTargetContextPriv.h"
egdaniel95131432014-12-09 11:15:43 -080021#include "GrXferProcessor.h"
bsalomon@google.com2db3ded2013-05-22 14:34:04 +000022#include "SkChecksum.h"
tfarina@chromium.org223137f2012-11-21 22:38:36 +000023#include "SkRandom.h"
bsalomon@google.comc3841b92012-08-02 18:11:43 +000024#include "Test.h"
joshualitt74417822015-08-07 11:42:16 -070025
Brian Salomon89527432016-12-16 09:52:16 -050026#include "ops/GrDrawOp.h"
joshualitt74417822015-08-07 11:42:16 -070027
joshualitt2c93efe2014-11-06 12:57:13 -080028#include "effects/GrConfigConversionEffect.h"
egdaniel95131432014-12-09 11:15:43 -080029#include "effects/GrPorterDuffXferProcessor.h"
wangyix059dffa2015-09-10 06:57:05 -070030#include "effects/GrXfermodeFragmentProcessor.h"
joshualitt74417822015-08-07 11:42:16 -070031
jvanverth39edf762014-12-22 11:44:19 -080032#include "gl/GrGLGpu.h"
egdaniel64c47282015-11-13 06:54:19 -080033#include "glsl/GrGLSLFragmentProcessor.h"
egdaniel2d721d32015-11-11 13:06:05 -080034#include "glsl/GrGLSLFragmentShaderBuilder.h"
35#include "glsl/GrGLSLProgramBuilder.h"
bsalomon@google.comc3841b92012-08-02 18:11:43 +000036
joshualitt65171342014-10-09 07:25:36 -070037/*
bsalomon98b33eb2014-10-15 11:05:26 -070038 * A dummy processor which just tries to insert a massive key and verify that it can retrieve the
joshualitt65171342014-10-09 07:25:36 -070039 * whole thing correctly
40 */
41static const uint32_t kMaxKeySize = 1024;
42
egdaniel64c47282015-11-13 06:54:19 -080043class GLBigKeyProcessor : public GrGLSLFragmentProcessor {
joshualitt65171342014-10-09 07:25:36 -070044public:
robertphillips9cdb9922016-02-03 12:25:40 -080045 void emitCode(EmitArgs& args) override {
joshualitt6c891102015-05-13 08:51:49 -070046 // pass through
egdaniel4ca2e602015-11-18 08:01:26 -080047 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
bsalomonb5b60322015-09-14 12:26:33 -070048 if (args.fInputColor) {
egdaniel4ca2e602015-11-18 08:01:26 -080049 fragBuilder->codeAppendf("%s = %s;\n", args.fOutputColor, args.fInputColor);
bsalomonb5b60322015-09-14 12:26:33 -070050 } else {
egdaniel4ca2e602015-11-18 08:01:26 -080051 fragBuilder->codeAppendf("%s = vec4(1.0);\n", args.fOutputColor);
bsalomonb5b60322015-09-14 12:26:33 -070052 }
joshualitt6c891102015-05-13 08:51:49 -070053 }
joshualitt65171342014-10-09 07:25:36 -070054
Brian Salomon94efbf52016-11-29 13:43:05 -050055 static void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder* b) {
joshualitt65171342014-10-09 07:25:36 -070056 for (uint32_t i = 0; i < kMaxKeySize; i++) {
57 b->add32(i);
joshualittd9097592014-10-07 08:37:36 -070058 }
joshualittd9097592014-10-07 08:37:36 -070059 }
60
joshualitt65171342014-10-09 07:25:36 -070061private:
egdaniel64c47282015-11-13 06:54:19 -080062 typedef GrGLSLFragmentProcessor INHERITED;
joshualitt65171342014-10-09 07:25:36 -070063};
64
joshualitteb2a6762014-12-04 11:35:33 -080065class BigKeyProcessor : public GrFragmentProcessor {
66public:
Brian Salomonaff329b2017-08-11 09:40:37 -040067 static std::unique_ptr<GrFragmentProcessor> Make() {
68 return std::unique_ptr<GrFragmentProcessor>(new BigKeyProcessor);
joshualitteb2a6762014-12-04 11:35:33 -080069 }
70
mtklein36352bf2015-03-25 18:17:31 -070071 const char* name() const override { return "Big Ole Key"; }
joshualitteb2a6762014-12-04 11:35:33 -080072
egdaniel57d3b032015-11-13 11:57:27 -080073 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
robertphillips9cdb9922016-02-03 12:25:40 -080074 return new GLBigKeyProcessor;
joshualitteb2a6762014-12-04 11:35:33 -080075 }
76
Brian Salomonaff329b2017-08-11 09:40:37 -040077 std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(); }
Brian Salomonb17e6392017-07-28 13:41:51 -040078
joshualitteb2a6762014-12-04 11:35:33 -080079private:
Ethan Nicholasabff9562017-10-09 10:54:08 -040080 BigKeyProcessor() : INHERITED(kBigKeyProcessor_ClassID, kNone_OptimizationFlags) { }
Brian Salomon94efbf52016-11-29 13:43:05 -050081 virtual void onGetGLSLProcessorKey(const GrShaderCaps& caps,
egdaniel57d3b032015-11-13 11:57:27 -080082 GrProcessorKeyBuilder* b) const override {
wangyix4b3050b2015-08-04 07:59:37 -070083 GLBigKeyProcessor::GenKey(*this, caps, b);
84 }
mtklein36352bf2015-03-25 18:17:31 -070085 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
joshualitteb2a6762014-12-04 11:35:33 -080086
Brian Salomon0c26a9d2017-07-06 10:09:38 -040087 GR_DECLARE_FRAGMENT_PROCESSOR_TEST
joshualitteb2a6762014-12-04 11:35:33 -080088
89 typedef GrFragmentProcessor INHERITED;
90};
91
92GR_DEFINE_FRAGMENT_PROCESSOR_TEST(BigKeyProcessor);
93
Hal Canary6f6961e2017-01-31 13:50:44 -050094#if GR_TEST_UTILS
Brian Salomonaff329b2017-08-11 09:40:37 -040095std::unique_ptr<GrFragmentProcessor> BigKeyProcessor::TestCreate(GrProcessorTestData*) {
bungeman06ca8ec2016-06-09 08:01:03 -070096 return BigKeyProcessor::Make();
joshualitteb2a6762014-12-04 11:35:33 -080097}
Hal Canary6f6961e2017-01-31 13:50:44 -050098#endif
joshualitteb2a6762014-12-04 11:35:33 -080099
bsalomonb5b60322015-09-14 12:26:33 -0700100//////////////////////////////////////////////////////////////////////////////
101
102class BlockInputFragmentProcessor : public GrFragmentProcessor {
103public:
Brian Salomonaff329b2017-08-11 09:40:37 -0400104 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp) {
105 return std::unique_ptr<GrFragmentProcessor>(new BlockInputFragmentProcessor(std::move(fp)));
bsalomonb5b60322015-09-14 12:26:33 -0700106 }
107
108 const char* name() const override { return "Block Input"; }
109
egdaniel57d3b032015-11-13 11:57:27 -0800110 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLFP; }
bsalomonb5b60322015-09-14 12:26:33 -0700111
Brian Salomonaff329b2017-08-11 09:40:37 -0400112 std::unique_ptr<GrFragmentProcessor> clone() const override {
Brian Salomon96271cd2017-07-31 16:27:23 -0400113 return Make(this->childProcessor(0).clone());
Brian Salomonb17e6392017-07-28 13:41:51 -0400114 }
115
bsalomonb5b60322015-09-14 12:26:33 -0700116private:
egdaniel64c47282015-11-13 06:54:19 -0800117 class GLFP : public GrGLSLFragmentProcessor {
bsalomonb5b60322015-09-14 12:26:33 -0700118 public:
119 void emitCode(EmitArgs& args) override {
Ethan Nicholas2983f402017-05-08 09:36:08 -0400120 this->emitChild(0, args);
bsalomonb5b60322015-09-14 12:26:33 -0700121 }
122
123 private:
egdaniel64c47282015-11-13 06:54:19 -0800124 typedef GrGLSLFragmentProcessor INHERITED;
bsalomonb5b60322015-09-14 12:26:33 -0700125 };
126
Brian Salomonaff329b2017-08-11 09:40:37 -0400127 BlockInputFragmentProcessor(std::unique_ptr<GrFragmentProcessor> child)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400128 : INHERITED(kBlockInputFragmentProcessor_ClassID, kNone_OptimizationFlags) {
bungeman06ca8ec2016-06-09 08:01:03 -0700129 this->registerChildProcessor(std::move(child));
bsalomonb5b60322015-09-14 12:26:33 -0700130 }
131
Brian Salomon94efbf52016-11-29 13:43:05 -0500132 void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {}
bsalomonb5b60322015-09-14 12:26:33 -0700133
134 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
135
bsalomonb5b60322015-09-14 12:26:33 -0700136 typedef GrFragmentProcessor INHERITED;
137};
138
139//////////////////////////////////////////////////////////////////////////////
140
joshualitt65171342014-10-09 07:25:36 -0700141/*
142 * Begin test code
143 */
144static const int kRenderTargetHeight = 1;
145static const int kRenderTargetWidth = 1;
146
Brian Osman11052242016-10-27 14:47:55 -0400147static sk_sp<GrRenderTargetContext> random_render_target_context(GrContext* context,
148 SkRandom* random,
149 const GrCaps* caps) {
robertphillips82ec6e52016-05-19 14:01:05 -0700150 GrSurfaceOrigin origin = random->nextBool() ? kTopLeft_GrSurfaceOrigin
151 : kBottomLeft_GrSurfaceOrigin;
Brian Salomonbdecacf2018-02-02 20:32:49 -0500152 int sampleCnt =
153 random->nextBool() ? caps->getRenderTargetSampleCount(2, kRGBA_8888_GrPixelConfig) : 1;
154 // Above could be 0 if msaa isn't supported.
155 sampleCnt = SkTMax(1, sampleCnt);
joshualitt6c891102015-05-13 08:51:49 -0700156
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500157 sk_sp<GrRenderTargetContext> renderTargetContext(
158 context->contextPriv().makeDeferredRenderTargetContext(SkBackingFit::kExact,
159 kRenderTargetWidth,
160 kRenderTargetHeight,
161 kRGBA_8888_GrPixelConfig,
162 nullptr,
163 sampleCnt,
164 GrMipMapped::kNo,
165 origin));
Brian Osman11052242016-10-27 14:47:55 -0400166 return renderTargetContext;
bsalomon@google.com91207482013-02-12 21:45:24 +0000167}
168
Hal Canary6f6961e2017-01-31 13:50:44 -0500169#if GR_TEST_UTILS
robertphillips28a838e2016-06-23 14:07:00 -0700170static void set_random_xpf(GrPaint* paint, GrProcessorTestData* d) {
Brian Salomona1633922017-01-09 11:46:10 -0500171 paint->setXPFactory(GrXPFactoryTestFactory::Get(d));
egdanielc2304142014-12-11 13:15:13 -0800172}
173
Brian Salomonaff329b2017-08-11 09:40:37 -0400174static std::unique_ptr<GrFragmentProcessor> create_random_proc_tree(GrProcessorTestData* d,
175 int minLevels, int maxLevels) {
wangyix059dffa2015-09-10 06:57:05 -0700176 SkASSERT(1 <= minLevels);
177 SkASSERT(minLevels <= maxLevels);
178
179 // Return a leaf node if maxLevels is 1 or if we randomly chose to terminate.
180 // If returning a leaf node, make sure that it doesn't have children (e.g. another
181 // GrComposeEffect)
182 const float terminateProbability = 0.3f;
183 if (1 == minLevels) {
184 bool terminate = (1 == maxLevels) || (d->fRandom->nextF() < terminateProbability);
185 if (terminate) {
Brian Salomonaff329b2017-08-11 09:40:37 -0400186 std::unique_ptr<GrFragmentProcessor> fp;
wangyix059dffa2015-09-10 06:57:05 -0700187 while (true) {
Brian Salomon1c053642017-07-24 10:16:19 -0400188 fp = GrFragmentProcessorTestFactory::Make(d);
wangyix059dffa2015-09-10 06:57:05 -0700189 SkASSERT(fp);
190 if (0 == fp->numChildProcessors()) {
191 break;
192 }
wangyix059dffa2015-09-10 06:57:05 -0700193 }
194 return fp;
195 }
196 }
197 // If we didn't terminate, choose either the left or right subtree to fulfill
198 // the minLevels requirement of this tree; the other child can have as few levels as it wants.
Brian Salomona12c1532017-02-13 12:41:44 -0500199 // Also choose a random xfer mode.
wangyix059dffa2015-09-10 06:57:05 -0700200 if (minLevels > 1) {
201 --minLevels;
202 }
Brian Salomonaff329b2017-08-11 09:40:37 -0400203 auto minLevelsChild = create_random_proc_tree(d, minLevels, maxLevels - 1);
204 std::unique_ptr<GrFragmentProcessor> otherChild(create_random_proc_tree(d, 1, maxLevels - 1));
Mike Reed7d954ad2016-10-28 15:42:34 -0400205 SkBlendMode mode = static_cast<SkBlendMode>(d->fRandom->nextRangeU(0,
Brian Salomona12c1532017-02-13 12:41:44 -0500206 (int)SkBlendMode::kLastMode));
Brian Salomonaff329b2017-08-11 09:40:37 -0400207 std::unique_ptr<GrFragmentProcessor> fp;
wangyix059dffa2015-09-10 06:57:05 -0700208 if (d->fRandom->nextF() < 0.5f) {
bungeman06ca8ec2016-06-09 08:01:03 -0700209 fp = GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(minLevelsChild),
210 std::move(otherChild), mode);
wangyix059dffa2015-09-10 06:57:05 -0700211 SkASSERT(fp);
212 } else {
bungeman06ca8ec2016-06-09 08:01:03 -0700213 fp = GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(otherChild),
214 std::move(minLevelsChild), mode);
wangyix059dffa2015-09-10 06:57:05 -0700215 SkASSERT(fp);
216 }
217 return fp;
218}
219
robertphillips28a838e2016-06-23 14:07:00 -0700220static void set_random_color_coverage_stages(GrPaint* paint,
221 GrProcessorTestData* d,
Greg Daniel78325c12017-06-19 16:39:13 -0400222 int maxStages,
223 int maxTreeLevels) {
wangyix059dffa2015-09-10 06:57:05 -0700224 // Randomly choose to either create a linear pipeline of procs or create one proc tree
225 const float procTreeProbability = 0.5f;
226 if (d->fRandom->nextF() < procTreeProbability) {
Brian Salomonaff329b2017-08-11 09:40:37 -0400227 std::unique_ptr<GrFragmentProcessor> fp(create_random_proc_tree(d, 2, maxTreeLevels));
Robert Phillips1c9686b2017-06-30 08:40:28 -0400228 if (fp) {
229 paint->addColorFragmentProcessor(std::move(fp));
230 }
wangyix059dffa2015-09-10 06:57:05 -0700231 } else {
232 int numProcs = d->fRandom->nextULessThan(maxStages + 1);
233 int numColorProcs = d->fRandom->nextULessThan(numProcs + 1);
joshualitt65171342014-10-09 07:25:36 -0700234
wangyix059dffa2015-09-10 06:57:05 -0700235 for (int s = 0; s < numProcs;) {
Brian Salomonaff329b2017-08-11 09:40:37 -0400236 std::unique_ptr<GrFragmentProcessor> fp(GrFragmentProcessorTestFactory::Make(d));
wangyix059dffa2015-09-10 06:57:05 -0700237 SkASSERT(fp);
238
239 // finally add the stage to the correct pipeline in the drawstate
240 if (s < numColorProcs) {
robertphillips28a838e2016-06-23 14:07:00 -0700241 paint->addColorFragmentProcessor(std::move(fp));
wangyix059dffa2015-09-10 06:57:05 -0700242 } else {
robertphillips28a838e2016-06-23 14:07:00 -0700243 paint->addCoverageFragmentProcessor(std::move(fp));
wangyix059dffa2015-09-10 06:57:05 -0700244 }
245 ++s;
joshualitt65171342014-10-09 07:25:36 -0700246 }
joshualitt65171342014-10-09 07:25:36 -0700247 }
248}
249
Hal Canary6f6961e2017-01-31 13:50:44 -0500250#endif
joshualitt249af152014-09-15 11:41:13 -0700251
Hal Canary6f6961e2017-01-31 13:50:44 -0500252#if !GR_TEST_UTILS
253bool GrDrawingManager::ProgramUnitTest(GrContext*, int) { return true; }
254#else
Greg Daniel78325c12017-06-19 16:39:13 -0400255bool GrDrawingManager::ProgramUnitTest(GrContext* context, int maxStages, int maxLevels) {
csmartdaltonbde96c62016-08-31 12:54:46 -0700256 GrDrawingManager* drawingManager = context->contextPriv().drawingManager();
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500257 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
robertphillipsa13e2022015-11-11 12:01:09 -0800258
Robert Phillipse78b7252017-04-06 07:59:41 -0400259 sk_sp<GrTextureProxy> proxies[2];
260
joshualitt65171342014-10-09 07:25:36 -0700261 // setup dummy textures
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500262 {
263 GrSurfaceDesc dummyDesc;
264 dummyDesc.fFlags = kRenderTarget_GrSurfaceFlag;
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500265 dummyDesc.fWidth = 34;
266 dummyDesc.fHeight = 18;
267 dummyDesc.fConfig = kRGBA_8888_GrPixelConfig;
Brian Salomon2a4f9832018-03-03 22:43:43 -0500268 proxies[0] = proxyProvider->createProxy(dummyDesc, kBottomLeft_GrSurfaceOrigin,
Greg Daniel09c94002018-06-08 22:11:51 +0000269 GrMipMapped::kYes, SkBackingFit::kExact,
270 SkBudgeted::kNo, GrInternalSurfaceFlags::kNone);
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500271 }
272 {
273 GrSurfaceDesc dummyDesc;
274 dummyDesc.fFlags = kNone_GrSurfaceFlags;
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500275 dummyDesc.fWidth = 16;
276 dummyDesc.fHeight = 22;
277 dummyDesc.fConfig = kAlpha_8_GrPixelConfig;
Brian Salomon2a4f9832018-03-03 22:43:43 -0500278 proxies[1] = proxyProvider->createProxy(dummyDesc, kTopLeft_GrSurfaceOrigin,
Greg Daniel09c94002018-06-08 22:11:51 +0000279 GrMipMapped::kYes, SkBackingFit::kExact,
280 SkBudgeted::kNo, GrInternalSurfaceFlags::kNone);
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500281 }
bsalomon@google.comd4726202012-08-03 14:34:46 +0000282
Robert Phillipse78b7252017-04-06 07:59:41 -0400283 if (!proxies[0] || !proxies[1]) {
joshualitt65171342014-10-09 07:25:36 -0700284 SkDebugf("Could not allocate dummy textures");
bsalomone904c092014-07-17 10:50:59 -0700285 return false;
286 }
287
Brian Salomond818ebf2018-07-02 14:08:49 +0000288 // dummy scissor state
289 GrScissorState scissor;
290
Brian Osman9f772a42017-07-10 13:03:50 -0400291 SkRandom random;
bsalomonf3261af2016-04-05 10:57:13 -0700292 static const int NUM_TESTS = 1024;
joshualitt6c891102015-05-13 08:51:49 -0700293 for (int t = 0; t < NUM_TESTS; t++) {
joshualitt65171342014-10-09 07:25:36 -0700294 // setup random render target(can fail)
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400295 sk_sp<GrRenderTargetContext> renderTargetContext(
296 random_render_target_context(context, &random, context->contextPriv().caps()));
Brian Osman11052242016-10-27 14:47:55 -0400297 if (!renderTargetContext) {
298 SkDebugf("Could not allocate renderTargetContext");
joshualittf5883a62016-01-13 07:47:38 -0800299 return false;
300 }
robertphillips0dfa62c2015-11-16 06:23:31 -0800301
Brian Salomon17726632017-05-12 14:09:46 -0400302 GrPaint paint;
Robert Phillipse78b7252017-04-06 07:59:41 -0400303 GrProcessorTestData ptd(&random, context, renderTargetContext.get(), proxies);
Greg Daniel78325c12017-06-19 16:39:13 -0400304 set_random_color_coverage_stages(&paint, &ptd, maxStages, maxLevels);
Brian Salomon17726632017-05-12 14:09:46 -0400305 set_random_xpf(&paint, &ptd);
Brian Salomon17726632017-05-12 14:09:46 -0400306 GrDrawRandomOp(&random, renderTargetContext.get(), std::move(paint));
bsalomon@google.comc3841b92012-08-02 18:11:43 +0000307 }
joshualitt6c891102015-05-13 08:51:49 -0700308 // Flush everything, test passes if flush is successful(ie, no asserts are hit, no crashes)
Robert Phillips7ee385e2017-03-30 08:02:11 -0400309 drawingManager->flush(nullptr);
bsalomonb5b60322015-09-14 12:26:33 -0700310
311 // Validate that GrFPs work correctly without an input.
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500312 sk_sp<GrRenderTargetContext> renderTargetContext(
313 context->contextPriv().makeDeferredRenderTargetContext(SkBackingFit::kExact,
314 kRenderTargetWidth,
315 kRenderTargetHeight,
316 kRGBA_8888_GrPixelConfig,
317 nullptr));
Brian Osman11052242016-10-27 14:47:55 -0400318 if (!renderTargetContext) {
319 SkDebugf("Could not allocate a renderTargetContext");
robertphillips82ec6e52016-05-19 14:01:05 -0700320 return false;
321 }
322
Brian Salomon1c053642017-07-24 10:16:19 -0400323 int fpFactoryCnt = GrFragmentProcessorTestFactory::Count();
bsalomonb5b60322015-09-14 12:26:33 -0700324 for (int i = 0; i < fpFactoryCnt; ++i) {
325 // Since FP factories internally randomize, call each 10 times.
326 for (int j = 0; j < 10; ++j) {
Robert Phillipse78b7252017-04-06 07:59:41 -0400327 GrProcessorTestData ptd(&random, context, renderTargetContext.get(), proxies);
bsalomonb5b60322015-09-14 12:26:33 -0700328
Brian Salomon17726632017-05-12 14:09:46 -0400329 GrPaint paint;
330 paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
Brian Salomonaff329b2017-08-11 09:40:37 -0400331 auto fp = GrFragmentProcessorTestFactory::MakeIdx(i, &ptd);
332 auto blockFP = BlockInputFragmentProcessor::Make(std::move(fp));
Brian Salomon17726632017-05-12 14:09:46 -0400333 paint.addColorFragmentProcessor(std::move(blockFP));
334 GrDrawRandomOp(&random, renderTargetContext.get(), std::move(paint));
Robert Phillips7ee385e2017-03-30 08:02:11 -0400335 drawingManager->flush(nullptr);
bsalomonb5b60322015-09-14 12:26:33 -0700336 }
337 }
338
bsalomon@google.comc3841b92012-08-02 18:11:43 +0000339 return true;
340}
Hal Canary6f6961e2017-01-31 13:50:44 -0500341#endif
bsalomon@google.coma8e686e2011-08-16 15:45:58 +0000342
Greg Danield895ca62017-06-19 14:39:43 -0400343static int get_glprograms_max_stages(const sk_gpu_test::ContextInfo& ctxInfo) {
344 GrContext* context = ctxInfo.grContext();
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500345 GrGLGpu* gpu = static_cast<GrGLGpu*>(context->contextPriv().getGpu());
Brian Salomone334c592017-05-15 11:00:58 -0400346 int maxStages = 6;
347 if (kGLES_GrGLStandard == gpu->glStandard()) {
348 // We've had issues with driver crashes and HW limits being exceeded with many effects on
349 // Android devices. We have passes on ARM devices with the default number of stages.
350 // TODO When we run ES 3.00 GLSL in more places, test again
351#ifdef SK_BUILD_FOR_ANDROID
352 if (kARM_GrGLVendor != gpu->ctxInfo().vendor()) {
353 maxStages = 1;
354 }
kkinnunen3e980c32015-12-23 01:33:00 -0800355#endif
Brian Salomone334c592017-05-15 11:00:58 -0400356 // On iOS we can exceed the maximum number of varyings. http://skbug.com/6627.
Brian Osman4e1868c2017-05-26 15:56:32 -0400357#ifdef SK_BUILD_FOR_IOS
Brian Salomone334c592017-05-15 11:00:58 -0400358 maxStages = 3;
359#endif
360 }
Greg Danield895ca62017-06-19 14:39:43 -0400361 if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D9_ES2_ContextType ||
362 ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES2_ContextType) {
363 // On Angle D3D we will hit a limit of out variables if we use too many stages.
364 maxStages = 3;
365 }
Brian Salomone334c592017-05-15 11:00:58 -0400366 return maxStages;
367}
368
Greg Daniel78325c12017-06-19 16:39:13 -0400369static int get_glprograms_max_levels(const sk_gpu_test::ContextInfo& ctxInfo) {
370 // A full tree with 5 levels (31 nodes) may cause a program that exceeds shader limits
371 // (e.g. uniform or varying limits); maxTreeLevels should be a number from 1 to 4 inclusive.
372 int maxTreeLevels = 4;
373 // On iOS we can exceed the maximum number of varyings. http://skbug.com/6627.
374#ifdef SK_BUILD_FOR_IOS
375 maxTreeLevels = 2;
376#endif
377 if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D9_ES2_ContextType ||
378 ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES2_ContextType) {
379 // On Angle D3D we will hit a limit of out variables if we use too many stages.
380 maxTreeLevels = 2;
381 }
382 return maxTreeLevels;
383}
384
Brian Salomone334c592017-05-15 11:00:58 -0400385static void test_glprograms(skiatest::Reporter* reporter, const sk_gpu_test::ContextInfo& ctxInfo) {
Greg Danield895ca62017-06-19 14:39:43 -0400386 int maxStages = get_glprograms_max_stages(ctxInfo);
kkinnunen3e980c32015-12-23 01:33:00 -0800387 if (maxStages == 0) {
388 return;
389 }
Greg Daniel78325c12017-06-19 16:39:13 -0400390 int maxLevels = get_glprograms_max_levels(ctxInfo);
391 if (maxLevels == 0) {
392 return;
393 }
Brian Osman9f772a42017-07-10 13:03:50 -0400394
Greg Daniel78325c12017-06-19 16:39:13 -0400395 REPORTER_ASSERT(reporter, GrDrawingManager::ProgramUnitTest(ctxInfo.grContext(), maxStages,
396 maxLevels));
kkinnunen3e980c32015-12-23 01:33:00 -0800397}
398
Brian Salomondcfca432017-11-15 15:48:03 -0500399DEF_GPUTEST(GLPrograms, reporter, options) {
bsalomon3318ee72015-03-16 11:56:29 -0700400 // Set a locale that would cause shader compilation to fail because of , as decimal separator.
401 // skbug 3330
402#ifdef SK_BUILD_FOR_WIN
403 GrAutoLocaleSetter als("sv-SE");
404#else
405 GrAutoLocaleSetter als("sv_SE.UTF-8");
406#endif
407
joshualitt6c891102015-05-13 08:51:49 -0700408 // We suppress prints to avoid spew
Brian Salomondcfca432017-11-15 15:48:03 -0500409 GrContextOptions opts = options;
joshualitt6c891102015-05-13 08:51:49 -0700410 opts.fSuppressPrints = true;
bsalomon3724e572016-03-30 18:56:19 -0700411 sk_gpu_test::GrContextFactory debugFactory(opts);
Brian Salomone334c592017-05-15 11:00:58 -0400412 skiatest::RunWithGPUTestContexts(test_glprograms, &skiatest::IsRenderingGLContextType, reporter,
Brian Salomondcfca432017-11-15 15:48:03 -0500413 opts);
bsalomon@google.coma8e686e2011-08-16 15:45:58 +0000414}
415
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000416#endif