blob: 51259781f25ba7af38cc6a3a0032ff7ca17ce98f [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
12#if SK_SUPPORT_GPU && SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
13
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"
bsalomon4061b122015-05-29 10:26:19 -070021#include "GrResourceProvider.h"
joshualitt2c93efe2014-11-06 12:57:13 -080022#include "GrTest.h"
egdaniel95131432014-12-09 11:15:43 -080023#include "GrXferProcessor.h"
bsalomon@google.com2db3ded2013-05-22 14:34:04 +000024#include "SkChecksum.h"
tfarina@chromium.org223137f2012-11-21 22:38:36 +000025#include "SkRandom.h"
bsalomon@google.comc3841b92012-08-02 18:11:43 +000026#include "Test.h"
joshualitt74417822015-08-07 11:42:16 -070027
Brian Salomon89527432016-12-16 09:52:16 -050028#include "ops/GrDrawOp.h"
joshualitt74417822015-08-07 11:42:16 -070029
joshualitt2c93efe2014-11-06 12:57:13 -080030#include "effects/GrConfigConversionEffect.h"
egdaniel95131432014-12-09 11:15:43 -080031#include "effects/GrPorterDuffXferProcessor.h"
wangyix059dffa2015-09-10 06:57:05 -070032#include "effects/GrXfermodeFragmentProcessor.h"
joshualitt74417822015-08-07 11:42:16 -070033
jvanverth39edf762014-12-22 11:44:19 -080034#include "gl/GrGLGpu.h"
egdaniel64c47282015-11-13 06:54:19 -080035#include "glsl/GrGLSLFragmentProcessor.h"
egdaniel2d721d32015-11-11 13:06:05 -080036#include "glsl/GrGLSLFragmentShaderBuilder.h"
37#include "glsl/GrGLSLProgramBuilder.h"
bsalomon@google.comc3841b92012-08-02 18:11:43 +000038
joshualitt65171342014-10-09 07:25:36 -070039/*
bsalomon98b33eb2014-10-15 11:05:26 -070040 * A dummy processor which just tries to insert a massive key and verify that it can retrieve the
joshualitt65171342014-10-09 07:25:36 -070041 * whole thing correctly
42 */
43static const uint32_t kMaxKeySize = 1024;
44
egdaniel64c47282015-11-13 06:54:19 -080045class GLBigKeyProcessor : public GrGLSLFragmentProcessor {
joshualitt65171342014-10-09 07:25:36 -070046public:
robertphillips9cdb9922016-02-03 12:25:40 -080047 void emitCode(EmitArgs& args) override {
joshualitt6c891102015-05-13 08:51:49 -070048 // pass through
egdaniel4ca2e602015-11-18 08:01:26 -080049 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
bsalomonb5b60322015-09-14 12:26:33 -070050 if (args.fInputColor) {
egdaniel4ca2e602015-11-18 08:01:26 -080051 fragBuilder->codeAppendf("%s = %s;\n", args.fOutputColor, args.fInputColor);
bsalomonb5b60322015-09-14 12:26:33 -070052 } else {
egdaniel4ca2e602015-11-18 08:01:26 -080053 fragBuilder->codeAppendf("%s = vec4(1.0);\n", args.fOutputColor);
bsalomonb5b60322015-09-14 12:26:33 -070054 }
joshualitt6c891102015-05-13 08:51:49 -070055 }
joshualitt65171342014-10-09 07:25:36 -070056
Brian Salomon94efbf52016-11-29 13:43:05 -050057 static void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder* b) {
joshualitt65171342014-10-09 07:25:36 -070058 for (uint32_t i = 0; i < kMaxKeySize; i++) {
59 b->add32(i);
joshualittd9097592014-10-07 08:37:36 -070060 }
joshualittd9097592014-10-07 08:37:36 -070061 }
62
joshualitt65171342014-10-09 07:25:36 -070063private:
egdaniel64c47282015-11-13 06:54:19 -080064 typedef GrGLSLFragmentProcessor INHERITED;
joshualitt65171342014-10-09 07:25:36 -070065};
66
joshualitteb2a6762014-12-04 11:35:33 -080067class BigKeyProcessor : public GrFragmentProcessor {
68public:
bungeman06ca8ec2016-06-09 08:01:03 -070069 static sk_sp<GrFragmentProcessor> Make() {
70 return sk_sp<GrFragmentProcessor>(new BigKeyProcessor);
joshualitteb2a6762014-12-04 11:35:33 -080071 }
72
mtklein36352bf2015-03-25 18:17:31 -070073 const char* name() const override { return "Big Ole Key"; }
joshualitteb2a6762014-12-04 11:35:33 -080074
egdaniel57d3b032015-11-13 11:57:27 -080075 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
robertphillips9cdb9922016-02-03 12:25:40 -080076 return new GLBigKeyProcessor;
joshualitteb2a6762014-12-04 11:35:33 -080077 }
78
79private:
Brian Salomon587e08f2017-01-27 10:59:27 -050080 BigKeyProcessor() : INHERITED(kNone_OptimizationFlags) { this->initClassID<BigKeyProcessor>(); }
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
87 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
88
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
bungeman06ca8ec2016-06-09 08:01:03 -070095sk_sp<GrFragmentProcessor> BigKeyProcessor::TestCreate(GrProcessorTestData*) {
96 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:
bungeman06ca8ec2016-06-09 08:01:03 -0700104 static sk_sp<GrFragmentProcessor> Make(sk_sp<GrFragmentProcessor> fp) {
105 return sk_sp<GrFragmentProcessor>(new BlockInputFragmentProcessor(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
112private:
egdaniel64c47282015-11-13 06:54:19 -0800113 class GLFP : public GrGLSLFragmentProcessor {
bsalomonb5b60322015-09-14 12:26:33 -0700114 public:
115 void emitCode(EmitArgs& args) override {
Ethan Nicholas2983f402017-05-08 09:36:08 -0400116 this->emitChild(0, args);
bsalomonb5b60322015-09-14 12:26:33 -0700117 }
118
119 private:
egdaniel64c47282015-11-13 06:54:19 -0800120 typedef GrGLSLFragmentProcessor INHERITED;
bsalomonb5b60322015-09-14 12:26:33 -0700121 };
122
Brian Salomon587e08f2017-01-27 10:59:27 -0500123 BlockInputFragmentProcessor(sk_sp<GrFragmentProcessor> child)
124 : INHERITED(kNone_OptimizationFlags) {
bsalomonb5b60322015-09-14 12:26:33 -0700125 this->initClassID<BlockInputFragmentProcessor>();
bungeman06ca8ec2016-06-09 08:01:03 -0700126 this->registerChildProcessor(std::move(child));
bsalomonb5b60322015-09-14 12:26:33 -0700127 }
128
Brian Salomon94efbf52016-11-29 13:43:05 -0500129 void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {}
bsalomonb5b60322015-09-14 12:26:33 -0700130
131 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
132
bsalomonb5b60322015-09-14 12:26:33 -0700133 typedef GrFragmentProcessor INHERITED;
134};
135
136//////////////////////////////////////////////////////////////////////////////
137
joshualitt65171342014-10-09 07:25:36 -0700138/*
139 * Begin test code
140 */
141static const int kRenderTargetHeight = 1;
142static const int kRenderTargetWidth = 1;
143
Brian Osman11052242016-10-27 14:47:55 -0400144static sk_sp<GrRenderTargetContext> random_render_target_context(GrContext* context,
145 SkRandom* random,
146 const GrCaps* caps) {
robertphillips82ec6e52016-05-19 14:01:05 -0700147 GrSurfaceOrigin origin = random->nextBool() ? kTopLeft_GrSurfaceOrigin
148 : kBottomLeft_GrSurfaceOrigin;
149 int sampleCnt = random->nextBool() ? SkTMin(4, caps->maxSampleCount()) : 0;
joshualitt6c891102015-05-13 08:51:49 -0700150
Robert Phillipsdd3b3f42017-04-24 10:57:28 -0400151 sk_sp<GrRenderTargetContext> renderTargetContext(context->makeDeferredRenderTargetContext(
Brian Osman11052242016-10-27 14:47:55 -0400152 SkBackingFit::kExact,
153 kRenderTargetWidth,
154 kRenderTargetHeight,
155 kRGBA_8888_GrPixelConfig,
156 nullptr,
157 sampleCnt,
158 origin));
159 return renderTargetContext;
bsalomon@google.com91207482013-02-12 21:45:24 +0000160}
161
Hal Canary6f6961e2017-01-31 13:50:44 -0500162#if GR_TEST_UTILS
robertphillips28a838e2016-06-23 14:07:00 -0700163static void set_random_xpf(GrPaint* paint, GrProcessorTestData* d) {
Brian Salomona1633922017-01-09 11:46:10 -0500164 paint->setXPFactory(GrXPFactoryTestFactory::Get(d));
egdanielc2304142014-12-11 13:15:13 -0800165}
166
bungeman06ca8ec2016-06-09 08:01:03 -0700167static sk_sp<GrFragmentProcessor> create_random_proc_tree(GrProcessorTestData* d,
168 int minLevels, int maxLevels) {
wangyix059dffa2015-09-10 06:57:05 -0700169 SkASSERT(1 <= minLevels);
170 SkASSERT(minLevels <= maxLevels);
171
172 // Return a leaf node if maxLevels is 1 or if we randomly chose to terminate.
173 // If returning a leaf node, make sure that it doesn't have children (e.g. another
174 // GrComposeEffect)
175 const float terminateProbability = 0.3f;
176 if (1 == minLevels) {
177 bool terminate = (1 == maxLevels) || (d->fRandom->nextF() < terminateProbability);
178 if (terminate) {
bungeman06ca8ec2016-06-09 08:01:03 -0700179 sk_sp<GrFragmentProcessor> fp;
wangyix059dffa2015-09-10 06:57:05 -0700180 while (true) {
bungeman06ca8ec2016-06-09 08:01:03 -0700181 fp = GrProcessorTestFactory<GrFragmentProcessor>::Make(d);
wangyix059dffa2015-09-10 06:57:05 -0700182 SkASSERT(fp);
183 if (0 == fp->numChildProcessors()) {
184 break;
185 }
wangyix059dffa2015-09-10 06:57:05 -0700186 }
187 return fp;
188 }
189 }
190 // If we didn't terminate, choose either the left or right subtree to fulfill
191 // the minLevels requirement of this tree; the other child can have as few levels as it wants.
Brian Salomona12c1532017-02-13 12:41:44 -0500192 // Also choose a random xfer mode.
wangyix059dffa2015-09-10 06:57:05 -0700193 if (minLevels > 1) {
194 --minLevels;
195 }
bungeman06ca8ec2016-06-09 08:01:03 -0700196 sk_sp<GrFragmentProcessor> minLevelsChild(create_random_proc_tree(d, minLevels, maxLevels - 1));
197 sk_sp<GrFragmentProcessor> otherChild(create_random_proc_tree(d, 1, maxLevels - 1));
Mike Reed7d954ad2016-10-28 15:42:34 -0400198 SkBlendMode mode = static_cast<SkBlendMode>(d->fRandom->nextRangeU(0,
Brian Salomona12c1532017-02-13 12:41:44 -0500199 (int)SkBlendMode::kLastMode));
bungeman06ca8ec2016-06-09 08:01:03 -0700200 sk_sp<GrFragmentProcessor> fp;
wangyix059dffa2015-09-10 06:57:05 -0700201 if (d->fRandom->nextF() < 0.5f) {
bungeman06ca8ec2016-06-09 08:01:03 -0700202 fp = GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(minLevelsChild),
203 std::move(otherChild), mode);
wangyix059dffa2015-09-10 06:57:05 -0700204 SkASSERT(fp);
205 } else {
bungeman06ca8ec2016-06-09 08:01:03 -0700206 fp = GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(otherChild),
207 std::move(minLevelsChild), mode);
wangyix059dffa2015-09-10 06:57:05 -0700208 SkASSERT(fp);
209 }
210 return fp;
211}
212
robertphillips28a838e2016-06-23 14:07:00 -0700213static void set_random_color_coverage_stages(GrPaint* paint,
214 GrProcessorTestData* d,
215 int maxStages) {
wangyix059dffa2015-09-10 06:57:05 -0700216 // Randomly choose to either create a linear pipeline of procs or create one proc tree
217 const float procTreeProbability = 0.5f;
218 if (d->fRandom->nextF() < procTreeProbability) {
Brian Salomona12c1532017-02-13 12:41:44 -0500219 // A full tree with 5 levels (31 nodes) may cause a program that exceeds shader limits
220 // (e.g. uniform or varying limits); maxTreeLevels should be a number from 1 to 4 inclusive.
Brian Osman988adb42017-05-26 16:30:19 -0400221 int maxTreeLevels = 4;
222 // On iOS we can exceed the maximum number of varyings. http://skbug.com/6627.
223#ifdef SK_BUILD_FOR_IOS
224 maxTreeLevels = 2;
225#endif
bungeman06ca8ec2016-06-09 08:01:03 -0700226 sk_sp<GrFragmentProcessor> fp(create_random_proc_tree(d, 2, maxTreeLevels));
robertphillips28a838e2016-06-23 14:07:00 -0700227 paint->addColorFragmentProcessor(std::move(fp));
wangyix059dffa2015-09-10 06:57:05 -0700228 } else {
229 int numProcs = d->fRandom->nextULessThan(maxStages + 1);
230 int numColorProcs = d->fRandom->nextULessThan(numProcs + 1);
joshualitt65171342014-10-09 07:25:36 -0700231
wangyix059dffa2015-09-10 06:57:05 -0700232 for (int s = 0; s < numProcs;) {
bungeman06ca8ec2016-06-09 08:01:03 -0700233 sk_sp<GrFragmentProcessor> fp(GrProcessorTestFactory<GrFragmentProcessor>::Make(d));
wangyix059dffa2015-09-10 06:57:05 -0700234 SkASSERT(fp);
235
236 // finally add the stage to the correct pipeline in the drawstate
237 if (s < numColorProcs) {
robertphillips28a838e2016-06-23 14:07:00 -0700238 paint->addColorFragmentProcessor(std::move(fp));
wangyix059dffa2015-09-10 06:57:05 -0700239 } else {
robertphillips28a838e2016-06-23 14:07:00 -0700240 paint->addCoverageFragmentProcessor(std::move(fp));
wangyix059dffa2015-09-10 06:57:05 -0700241 }
242 ++s;
joshualitt65171342014-10-09 07:25:36 -0700243 }
joshualitt65171342014-10-09 07:25:36 -0700244 }
245}
246
Brian Salomon17726632017-05-12 14:09:46 -0400247static void set_random_state(GrPaint* paint, SkRandom* random) {
robertphillips28a838e2016-06-23 14:07:00 -0700248 if (random->nextBool()) {
249 paint->setDisableOutputConversionToSRGB(true);
joshualitt65171342014-10-09 07:25:36 -0700250 }
robertphillips28a838e2016-06-23 14:07:00 -0700251 if (random->nextBool()) {
252 paint->setAllowSRGBInputs(true);
joshualitt6c891102015-05-13 08:51:49 -0700253 }
joshualitt65171342014-10-09 07:25:36 -0700254}
255
Hal Canary6f6961e2017-01-31 13:50:44 -0500256#endif
joshualitt249af152014-09-15 11:41:13 -0700257
Hal Canary6f6961e2017-01-31 13:50:44 -0500258#if !GR_TEST_UTILS
259bool GrDrawingManager::ProgramUnitTest(GrContext*, int) { return true; }
260#else
robertphillips0dfa62c2015-11-16 06:23:31 -0800261bool GrDrawingManager::ProgramUnitTest(GrContext* context, int maxStages) {
csmartdaltonbde96c62016-08-31 12:54:46 -0700262 GrDrawingManager* drawingManager = context->contextPriv().drawingManager();
robertphillipsa13e2022015-11-11 12:01:09 -0800263
Robert Phillipse78b7252017-04-06 07:59:41 -0400264 sk_sp<GrTextureProxy> proxies[2];
265
joshualitt65171342014-10-09 07:25:36 -0700266 // setup dummy textures
bsalomonf2703d82014-10-28 14:33:06 -0700267 GrSurfaceDesc dummyDesc;
bsalomonbea01502015-07-16 10:00:28 -0700268 dummyDesc.fFlags = kRenderTarget_GrSurfaceFlag;
Robert Phillipse78b7252017-04-06 07:59:41 -0400269 dummyDesc.fOrigin = kBottomLeft_GrSurfaceOrigin;
Brian Osman777b5632016-10-14 09:16:21 -0400270 dummyDesc.fConfig = kRGBA_8888_GrPixelConfig;
bsalomon@google.comd4726202012-08-03 14:34:46 +0000271 dummyDesc.fWidth = 34;
272 dummyDesc.fHeight = 18;
Robert Phillipse78b7252017-04-06 07:59:41 -0400273 proxies[0] = GrSurfaceProxy::MakeDeferred(context->resourceProvider(),
274 dummyDesc, SkBudgeted::kNo, nullptr, 0);
bsalomonf2703d82014-10-28 14:33:06 -0700275 dummyDesc.fFlags = kNone_GrSurfaceFlags;
Robert Phillipse78b7252017-04-06 07:59:41 -0400276 dummyDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
bsalomon@google.comd4726202012-08-03 14:34:46 +0000277 dummyDesc.fConfig = kAlpha_8_GrPixelConfig;
278 dummyDesc.fWidth = 16;
279 dummyDesc.fHeight = 22;
Robert Phillipse78b7252017-04-06 07:59:41 -0400280 proxies[1] = GrSurfaceProxy::MakeDeferred(context->resourceProvider(),
281 dummyDesc, SkBudgeted::kNo, nullptr, 0);
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
joshualitt54e0c122014-11-19 09:38:51 -0800288 // dummy scissor state
bsalomon3e791242014-12-17 13:43:13 -0800289 GrScissorState scissor;
joshualitt54e0c122014-11-19 09:38:51 -0800290
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000291 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 Osman11052242016-10-27 14:47:55 -0400295 sk_sp<GrRenderTargetContext> renderTargetContext(random_render_target_context(
296 context, &random, context->caps()));
297 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);
Brian Salomon17726632017-05-12 14:09:46 -0400304 set_random_color_coverage_stages(&paint, &ptd, maxStages);
305 set_random_xpf(&paint, &ptd);
306 set_random_state(&paint, &random);
307 GrDrawRandomOp(&random, renderTargetContext.get(), std::move(paint));
bsalomon@google.comc3841b92012-08-02 18:11:43 +0000308 }
joshualitt6c891102015-05-13 08:51:49 -0700309 // Flush everything, test passes if flush is successful(ie, no asserts are hit, no crashes)
Robert Phillips7ee385e2017-03-30 08:02:11 -0400310 drawingManager->flush(nullptr);
bsalomonb5b60322015-09-14 12:26:33 -0700311
312 // Validate that GrFPs work correctly without an input.
Robert Phillipsdd3b3f42017-04-24 10:57:28 -0400313 sk_sp<GrRenderTargetContext> renderTargetContext(context->makeDeferredRenderTargetContext(
Brian Osman11052242016-10-27 14:47:55 -0400314 SkBackingFit::kExact,
315 kRenderTargetWidth,
316 kRenderTargetHeight,
317 kRGBA_8888_GrPixelConfig,
318 nullptr));
319 if (!renderTargetContext) {
320 SkDebugf("Could not allocate a renderTargetContext");
robertphillips82ec6e52016-05-19 14:01:05 -0700321 return false;
322 }
323
bsalomonb5b60322015-09-14 12:26:33 -0700324 int fpFactoryCnt = GrProcessorTestFactory<GrFragmentProcessor>::Count();
325 for (int i = 0; i < fpFactoryCnt; ++i) {
326 // Since FP factories internally randomize, call each 10 times.
327 for (int j = 0; j < 10; ++j) {
Robert Phillipse78b7252017-04-06 07:59:41 -0400328 GrProcessorTestData ptd(&random, context, renderTargetContext.get(), proxies);
bsalomonb5b60322015-09-14 12:26:33 -0700329
Brian Salomon17726632017-05-12 14:09:46 -0400330 GrPaint paint;
331 paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
bungeman06ca8ec2016-06-09 08:01:03 -0700332 sk_sp<GrFragmentProcessor> fp(
333 GrProcessorTestFactory<GrFragmentProcessor>::MakeIdx(i, &ptd));
334 sk_sp<GrFragmentProcessor> blockFP(
335 BlockInputFragmentProcessor::Make(std::move(fp)));
Brian Salomon17726632017-05-12 14:09:46 -0400336 paint.addColorFragmentProcessor(std::move(blockFP));
337 GrDrawRandomOp(&random, renderTargetContext.get(), std::move(paint));
Robert Phillips7ee385e2017-03-30 08:02:11 -0400338 drawingManager->flush(nullptr);
bsalomonb5b60322015-09-14 12:26:33 -0700339 }
340 }
341
bsalomon@google.comc3841b92012-08-02 18:11:43 +0000342 return true;
343}
Hal Canary6f6961e2017-01-31 13:50:44 -0500344#endif
bsalomon@google.coma8e686e2011-08-16 15:45:58 +0000345
kkinnunen3e980c32015-12-23 01:33:00 -0800346static int get_glprograms_max_stages(GrContext* context) {
347 GrGLGpu* gpu = static_cast<GrGLGpu*>(context->getGpu());
Brian Salomone334c592017-05-15 11:00:58 -0400348 int maxStages = 6;
349 if (kGLES_GrGLStandard == gpu->glStandard()) {
350 // We've had issues with driver crashes and HW limits being exceeded with many effects on
351 // Android devices. We have passes on ARM devices with the default number of stages.
352 // TODO When we run ES 3.00 GLSL in more places, test again
353#ifdef SK_BUILD_FOR_ANDROID
354 if (kARM_GrGLVendor != gpu->ctxInfo().vendor()) {
355 maxStages = 1;
356 }
kkinnunen3e980c32015-12-23 01:33:00 -0800357#endif
Brian Salomone334c592017-05-15 11:00:58 -0400358 // On iOS we can exceed the maximum number of varyings. http://skbug.com/6627.
Brian Osman4e1868c2017-05-26 15:56:32 -0400359#ifdef SK_BUILD_FOR_IOS
Brian Salomone334c592017-05-15 11:00:58 -0400360 maxStages = 3;
361#endif
362 }
363 return maxStages;
364}
365
366static void test_glprograms(skiatest::Reporter* reporter, const sk_gpu_test::ContextInfo& ctxInfo) {
367 int maxStages = get_glprograms_max_stages(ctxInfo.grContext());
kkinnunen3e980c32015-12-23 01:33:00 -0800368 if (maxStages == 0) {
369 return;
370 }
bsalomon8b7451a2016-05-11 06:33:06 -0700371 REPORTER_ASSERT(reporter, GrDrawingManager::ProgramUnitTest(ctxInfo.grContext(), maxStages));
kkinnunen3e980c32015-12-23 01:33:00 -0800372}
373
374DEF_GPUTEST(GLPrograms, reporter, /*factory*/) {
bsalomon3318ee72015-03-16 11:56:29 -0700375 // Set a locale that would cause shader compilation to fail because of , as decimal separator.
376 // skbug 3330
377#ifdef SK_BUILD_FOR_WIN
378 GrAutoLocaleSetter als("sv-SE");
379#else
380 GrAutoLocaleSetter als("sv_SE.UTF-8");
381#endif
382
joshualitt6c891102015-05-13 08:51:49 -0700383 // We suppress prints to avoid spew
bsalomon682c2692015-05-22 14:01:46 -0700384 GrContextOptions opts;
joshualitt6c891102015-05-13 08:51:49 -0700385 opts.fSuppressPrints = true;
bsalomon3724e572016-03-30 18:56:19 -0700386 sk_gpu_test::GrContextFactory debugFactory(opts);
Brian Salomone334c592017-05-15 11:00:58 -0400387 skiatest::RunWithGPUTestContexts(test_glprograms, &skiatest::IsRenderingGLContextType, reporter,
388 &debugFactory);
bsalomon@google.coma8e686e2011-08-16 15:45:58 +0000389}
390
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000391#endif