blob: 98c41974aa2c04c2e99386f3107405df250a253a [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
Ben Wagnerf1344ac2019-05-10 15:01:53 -04008// This is a GPU-backend specific test.
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +00009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkTypes.h"
bsalomon@google.com2a48c3a2012-08-03 14:54:45 +000011
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/private/SkChecksum.h"
13#include "include/utils/SkRandom.h"
14#include "src/gpu/GrAutoLocaleSetter.h"
15#include "src/gpu/GrContextPriv.h"
16#include "src/gpu/GrDrawOpTest.h"
17#include "src/gpu/GrDrawingManager.h"
18#include "src/gpu/GrPipeline.h"
19#include "src/gpu/GrRenderTargetContextPriv.h"
20#include "src/gpu/GrXferProcessor.h"
21#include "tests/Test.h"
22#include "tools/gpu/GrContextFactory.h"
joshualitt74417822015-08-07 11:42:16 -070023
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#include "src/gpu/ops/GrDrawOp.h"
joshualitt74417822015-08-07 11:42:16 -070025
Mike Kleinc0bd9f92019-04-23 12:05:21 -050026#include "src/gpu/effects/GrPorterDuffXferProcessor.h"
27#include "src/gpu/effects/GrXfermodeFragmentProcessor.h"
28#include "src/gpu/effects/generated/GrConfigConversionEffect.h"
joshualitt74417822015-08-07 11:42:16 -070029
Mike Kleinc0bd9f92019-04-23 12:05:21 -050030#include "src/gpu/gl/GrGLGpu.h"
31#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
32#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
33#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
bsalomon@google.comc3841b92012-08-02 18:11:43 +000034
joshualitt65171342014-10-09 07:25:36 -070035/*
bsalomon98b33eb2014-10-15 11:05:26 -070036 * A dummy processor which just tries to insert a massive key and verify that it can retrieve the
joshualitt65171342014-10-09 07:25:36 -070037 * whole thing correctly
38 */
39static const uint32_t kMaxKeySize = 1024;
40
egdaniel64c47282015-11-13 06:54:19 -080041class GLBigKeyProcessor : public GrGLSLFragmentProcessor {
joshualitt65171342014-10-09 07:25:36 -070042public:
robertphillips9cdb9922016-02-03 12:25:40 -080043 void emitCode(EmitArgs& args) override {
joshualitt6c891102015-05-13 08:51:49 -070044 // pass through
egdaniel4ca2e602015-11-18 08:01:26 -080045 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
bsalomonb5b60322015-09-14 12:26:33 -070046 if (args.fInputColor) {
egdaniel4ca2e602015-11-18 08:01:26 -080047 fragBuilder->codeAppendf("%s = %s;\n", args.fOutputColor, args.fInputColor);
bsalomonb5b60322015-09-14 12:26:33 -070048 } else {
egdaniel4ca2e602015-11-18 08:01:26 -080049 fragBuilder->codeAppendf("%s = vec4(1.0);\n", args.fOutputColor);
bsalomonb5b60322015-09-14 12:26:33 -070050 }
joshualitt6c891102015-05-13 08:51:49 -070051 }
joshualitt65171342014-10-09 07:25:36 -070052
Brian Salomon94efbf52016-11-29 13:43:05 -050053 static void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder* b) {
joshualitt65171342014-10-09 07:25:36 -070054 for (uint32_t i = 0; i < kMaxKeySize; i++) {
55 b->add32(i);
joshualittd9097592014-10-07 08:37:36 -070056 }
joshualittd9097592014-10-07 08:37:36 -070057 }
58
joshualitt65171342014-10-09 07:25:36 -070059private:
egdaniel64c47282015-11-13 06:54:19 -080060 typedef GrGLSLFragmentProcessor INHERITED;
joshualitt65171342014-10-09 07:25:36 -070061};
62
joshualitteb2a6762014-12-04 11:35:33 -080063class BigKeyProcessor : public GrFragmentProcessor {
64public:
Brian Salomonaff329b2017-08-11 09:40:37 -040065 static std::unique_ptr<GrFragmentProcessor> Make() {
66 return std::unique_ptr<GrFragmentProcessor>(new BigKeyProcessor);
joshualitteb2a6762014-12-04 11:35:33 -080067 }
68
mtklein36352bf2015-03-25 18:17:31 -070069 const char* name() const override { return "Big Ole Key"; }
joshualitteb2a6762014-12-04 11:35:33 -080070
egdaniel57d3b032015-11-13 11:57:27 -080071 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
robertphillips9cdb9922016-02-03 12:25:40 -080072 return new GLBigKeyProcessor;
joshualitteb2a6762014-12-04 11:35:33 -080073 }
74
Brian Salomonaff329b2017-08-11 09:40:37 -040075 std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(); }
Brian Salomonb17e6392017-07-28 13:41:51 -040076
joshualitteb2a6762014-12-04 11:35:33 -080077private:
Ethan Nicholasabff9562017-10-09 10:54:08 -040078 BigKeyProcessor() : INHERITED(kBigKeyProcessor_ClassID, kNone_OptimizationFlags) { }
Brian Salomon94efbf52016-11-29 13:43:05 -050079 virtual void onGetGLSLProcessorKey(const GrShaderCaps& caps,
egdaniel57d3b032015-11-13 11:57:27 -080080 GrProcessorKeyBuilder* b) const override {
wangyix4b3050b2015-08-04 07:59:37 -070081 GLBigKeyProcessor::GenKey(*this, caps, b);
82 }
mtklein36352bf2015-03-25 18:17:31 -070083 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
joshualitteb2a6762014-12-04 11:35:33 -080084
Brian Salomon0c26a9d2017-07-06 10:09:38 -040085 GR_DECLARE_FRAGMENT_PROCESSOR_TEST
joshualitteb2a6762014-12-04 11:35:33 -080086
87 typedef GrFragmentProcessor INHERITED;
88};
89
90GR_DEFINE_FRAGMENT_PROCESSOR_TEST(BigKeyProcessor);
91
Hal Canary6f6961e2017-01-31 13:50:44 -050092#if GR_TEST_UTILS
Brian Salomonaff329b2017-08-11 09:40:37 -040093std::unique_ptr<GrFragmentProcessor> BigKeyProcessor::TestCreate(GrProcessorTestData*) {
bungeman06ca8ec2016-06-09 08:01:03 -070094 return BigKeyProcessor::Make();
joshualitteb2a6762014-12-04 11:35:33 -080095}
Hal Canary6f6961e2017-01-31 13:50:44 -050096#endif
joshualitteb2a6762014-12-04 11:35:33 -080097
bsalomonb5b60322015-09-14 12:26:33 -070098//////////////////////////////////////////////////////////////////////////////
99
100class BlockInputFragmentProcessor : public GrFragmentProcessor {
101public:
Brian Salomonaff329b2017-08-11 09:40:37 -0400102 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp) {
103 return std::unique_ptr<GrFragmentProcessor>(new BlockInputFragmentProcessor(std::move(fp)));
bsalomonb5b60322015-09-14 12:26:33 -0700104 }
105
106 const char* name() const override { return "Block Input"; }
107
egdaniel57d3b032015-11-13 11:57:27 -0800108 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLFP; }
bsalomonb5b60322015-09-14 12:26:33 -0700109
Brian Salomonaff329b2017-08-11 09:40:37 -0400110 std::unique_ptr<GrFragmentProcessor> clone() const override {
Brian Salomon96271cd2017-07-31 16:27:23 -0400111 return Make(this->childProcessor(0).clone());
Brian Salomonb17e6392017-07-28 13:41:51 -0400112 }
113
bsalomonb5b60322015-09-14 12:26:33 -0700114private:
egdaniel64c47282015-11-13 06:54:19 -0800115 class GLFP : public GrGLSLFragmentProcessor {
bsalomonb5b60322015-09-14 12:26:33 -0700116 public:
117 void emitCode(EmitArgs& args) override {
Ethan Nicholasc6dce5a2019-07-24 16:51:36 -0400118 this->invokeChild(0, args);
bsalomonb5b60322015-09-14 12:26:33 -0700119 }
120
121 private:
egdaniel64c47282015-11-13 06:54:19 -0800122 typedef GrGLSLFragmentProcessor INHERITED;
bsalomonb5b60322015-09-14 12:26:33 -0700123 };
124
Brian Salomonaff329b2017-08-11 09:40:37 -0400125 BlockInputFragmentProcessor(std::unique_ptr<GrFragmentProcessor> child)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400126 : INHERITED(kBlockInputFragmentProcessor_ClassID, kNone_OptimizationFlags) {
bungeman06ca8ec2016-06-09 08:01:03 -0700127 this->registerChildProcessor(std::move(child));
bsalomonb5b60322015-09-14 12:26:33 -0700128 }
129
Brian Salomon94efbf52016-11-29 13:43:05 -0500130 void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {}
bsalomonb5b60322015-09-14 12:26:33 -0700131
132 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
133
bsalomonb5b60322015-09-14 12:26:33 -0700134 typedef GrFragmentProcessor INHERITED;
135};
136
137//////////////////////////////////////////////////////////////////////////////
138
joshualitt65171342014-10-09 07:25:36 -0700139/*
140 * Begin test code
141 */
142static const int kRenderTargetHeight = 1;
143static const int kRenderTargetWidth = 1;
144
Brian Salomonbf6b9792019-08-21 09:38:10 -0400145static std::unique_ptr<GrRenderTargetContext> random_render_target_context(GrContext* context,
146 SkRandom* random,
147 const GrCaps* caps) {
robertphillips82ec6e52016-05-19 14:01:05 -0700148 GrSurfaceOrigin origin = random->nextBool() ? kTopLeft_GrSurfaceOrigin
149 : kBottomLeft_GrSurfaceOrigin;
joshualitt6c891102015-05-13 08:51:49 -0700150
Greg Daniel5c96db82019-07-09 14:06:58 -0400151 GrColorType ct = GrColorType::kRGBA_8888;
Robert Phillips0a15cc62019-07-30 12:49:10 -0400152 const GrBackendFormat format = caps->getDefaultBackendFormat(ct, GrRenderable::kYes);
Greg Daniel4065d452018-11-16 15:43:41 -0500153
Greg Daniel6fa62e22019-08-07 15:52:37 -0400154 int sampleCnt = random->nextBool() ? caps->getRenderTargetSampleCount(2, format) : 1;
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400155 // Above could be 0 if msaa isn't supported.
156 sampleCnt = SkTMax(1, sampleCnt);
157
Brian Salomonbf6b9792019-08-21 09:38:10 -0400158 return context->priv().makeDeferredRenderTargetContext(SkBackingFit::kExact,
159 kRenderTargetWidth,
160 kRenderTargetHeight,
161 GrColorType::kRGBA_8888,
162 nullptr,
163 sampleCnt,
164 GrMipMapped::kNo,
165 origin);
bsalomon@google.com91207482013-02-12 21:45:24 +0000166}
167
Hal Canary6f6961e2017-01-31 13:50:44 -0500168#if GR_TEST_UTILS
robertphillips28a838e2016-06-23 14:07:00 -0700169static void set_random_xpf(GrPaint* paint, GrProcessorTestData* d) {
Brian Salomona1633922017-01-09 11:46:10 -0500170 paint->setXPFactory(GrXPFactoryTestFactory::Get(d));
egdanielc2304142014-12-11 13:15:13 -0800171}
172
Brian Salomonaff329b2017-08-11 09:40:37 -0400173static std::unique_ptr<GrFragmentProcessor> create_random_proc_tree(GrProcessorTestData* d,
174 int minLevels, int maxLevels) {
wangyix059dffa2015-09-10 06:57:05 -0700175 SkASSERT(1 <= minLevels);
176 SkASSERT(minLevels <= maxLevels);
177
178 // Return a leaf node if maxLevels is 1 or if we randomly chose to terminate.
179 // If returning a leaf node, make sure that it doesn't have children (e.g. another
180 // GrComposeEffect)
181 const float terminateProbability = 0.3f;
182 if (1 == minLevels) {
183 bool terminate = (1 == maxLevels) || (d->fRandom->nextF() < terminateProbability);
184 if (terminate) {
Brian Salomonaff329b2017-08-11 09:40:37 -0400185 std::unique_ptr<GrFragmentProcessor> fp;
wangyix059dffa2015-09-10 06:57:05 -0700186 while (true) {
Brian Salomon1c053642017-07-24 10:16:19 -0400187 fp = GrFragmentProcessorTestFactory::Make(d);
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400188 if (!fp) {
189 return nullptr;
190 }
wangyix059dffa2015-09-10 06:57:05 -0700191 if (0 == fp->numChildProcessors()) {
192 break;
193 }
wangyix059dffa2015-09-10 06:57:05 -0700194 }
195 return fp;
196 }
197 }
198 // If we didn't terminate, choose either the left or right subtree to fulfill
199 // the minLevels requirement of this tree; the other child can have as few levels as it wants.
Brian Salomona12c1532017-02-13 12:41:44 -0500200 // Also choose a random xfer mode.
wangyix059dffa2015-09-10 06:57:05 -0700201 if (minLevels > 1) {
202 --minLevels;
203 }
Brian Salomonaff329b2017-08-11 09:40:37 -0400204 auto minLevelsChild = create_random_proc_tree(d, minLevels, maxLevels - 1);
205 std::unique_ptr<GrFragmentProcessor> otherChild(create_random_proc_tree(d, 1, maxLevels - 1));
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400206 if (!minLevelsChild || !otherChild) {
207 return nullptr;
208 }
Mike Reed7d954ad2016-10-28 15:42:34 -0400209 SkBlendMode mode = static_cast<SkBlendMode>(d->fRandom->nextRangeU(0,
Brian Salomona12c1532017-02-13 12:41:44 -0500210 (int)SkBlendMode::kLastMode));
Brian Salomonaff329b2017-08-11 09:40:37 -0400211 std::unique_ptr<GrFragmentProcessor> fp;
wangyix059dffa2015-09-10 06:57:05 -0700212 if (d->fRandom->nextF() < 0.5f) {
bungeman06ca8ec2016-06-09 08:01:03 -0700213 fp = GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(minLevelsChild),
214 std::move(otherChild), mode);
wangyix059dffa2015-09-10 06:57:05 -0700215 SkASSERT(fp);
216 } else {
bungeman06ca8ec2016-06-09 08:01:03 -0700217 fp = GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(otherChild),
218 std::move(minLevelsChild), mode);
wangyix059dffa2015-09-10 06:57:05 -0700219 SkASSERT(fp);
220 }
221 return fp;
222}
223
robertphillips28a838e2016-06-23 14:07:00 -0700224static void set_random_color_coverage_stages(GrPaint* paint,
225 GrProcessorTestData* d,
Greg Daniel78325c12017-06-19 16:39:13 -0400226 int maxStages,
227 int maxTreeLevels) {
wangyix059dffa2015-09-10 06:57:05 -0700228 // Randomly choose to either create a linear pipeline of procs or create one proc tree
229 const float procTreeProbability = 0.5f;
230 if (d->fRandom->nextF() < procTreeProbability) {
Brian Salomonaff329b2017-08-11 09:40:37 -0400231 std::unique_ptr<GrFragmentProcessor> fp(create_random_proc_tree(d, 2, maxTreeLevels));
Robert Phillips1c9686b2017-06-30 08:40:28 -0400232 if (fp) {
233 paint->addColorFragmentProcessor(std::move(fp));
234 }
wangyix059dffa2015-09-10 06:57:05 -0700235 } else {
236 int numProcs = d->fRandom->nextULessThan(maxStages + 1);
237 int numColorProcs = d->fRandom->nextULessThan(numProcs + 1);
joshualitt65171342014-10-09 07:25:36 -0700238
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400239 for (int s = 0; s < numProcs; ++s) {
Brian Salomonaff329b2017-08-11 09:40:37 -0400240 std::unique_ptr<GrFragmentProcessor> fp(GrFragmentProcessorTestFactory::Make(d));
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400241 if (!fp) {
242 continue;
243 }
wangyix059dffa2015-09-10 06:57:05 -0700244 // finally add the stage to the correct pipeline in the drawstate
245 if (s < numColorProcs) {
robertphillips28a838e2016-06-23 14:07:00 -0700246 paint->addColorFragmentProcessor(std::move(fp));
wangyix059dffa2015-09-10 06:57:05 -0700247 } else {
robertphillips28a838e2016-06-23 14:07:00 -0700248 paint->addCoverageFragmentProcessor(std::move(fp));
wangyix059dffa2015-09-10 06:57:05 -0700249 }
joshualitt65171342014-10-09 07:25:36 -0700250 }
joshualitt65171342014-10-09 07:25:36 -0700251 }
252}
253
Hal Canary6f6961e2017-01-31 13:50:44 -0500254#endif
joshualitt249af152014-09-15 11:41:13 -0700255
Hal Canary6f6961e2017-01-31 13:50:44 -0500256#if !GR_TEST_UTILS
257bool GrDrawingManager::ProgramUnitTest(GrContext*, int) { return true; }
258#else
Greg Daniel78325c12017-06-19 16:39:13 -0400259bool GrDrawingManager::ProgramUnitTest(GrContext* context, int maxStages, int maxLevels) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500260 GrDrawingManager* drawingManager = context->priv().drawingManager();
261 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
robertphillipsa13e2022015-11-11 12:01:09 -0800262
Robert Phillipse78b7252017-04-06 07:59:41 -0400263 sk_sp<GrTextureProxy> proxies[2];
264
joshualitt65171342014-10-09 07:25:36 -0700265 // setup dummy textures
Brian Salomon4687bdd2019-05-09 16:28:04 -0400266 GrMipMapped mipMapped = GrMipMapped(context->priv().caps()->mipMapSupport());
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500267 {
268 GrSurfaceDesc dummyDesc;
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500269 dummyDesc.fWidth = 34;
270 dummyDesc.fHeight = 18;
271 dummyDesc.fConfig = kRGBA_8888_GrPixelConfig;
Greg Daniel4065d452018-11-16 15:43:41 -0500272 const GrBackendFormat format =
Robert Phillips0a15cc62019-07-30 12:49:10 -0400273 context->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888,
274 GrRenderable::kYes);
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400275 proxies[0] = proxyProvider->createProxy(format, dummyDesc, GrRenderable::kYes, 1,
Brian Salomone8a766b2019-07-19 14:24:36 -0400276 kBottomLeft_GrSurfaceOrigin, mipMapped,
277 SkBackingFit::kExact, SkBudgeted::kNo,
278 GrProtected::kNo, GrInternalSurfaceFlags::kNone);
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500279 }
280 {
281 GrSurfaceDesc dummyDesc;
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500282 dummyDesc.fWidth = 16;
283 dummyDesc.fHeight = 22;
284 dummyDesc.fConfig = kAlpha_8_GrPixelConfig;
Greg Daniel4065d452018-11-16 15:43:41 -0500285 const GrBackendFormat format =
Robert Phillips0a15cc62019-07-30 12:49:10 -0400286 context->priv().caps()->getDefaultBackendFormat(GrColorType::kAlpha_8,
287 GrRenderable::kNo);
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400288 proxies[1] = proxyProvider->createProxy(format, dummyDesc, GrRenderable::kNo, 1,
Brian Salomone8a766b2019-07-19 14:24:36 -0400289 kTopLeft_GrSurfaceOrigin, mipMapped,
290 SkBackingFit::kExact, SkBudgeted::kNo,
291 GrProtected::kNo, GrInternalSurfaceFlags::kNone);
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500292 }
bsalomon@google.comd4726202012-08-03 14:34:46 +0000293
Robert Phillipse78b7252017-04-06 07:59:41 -0400294 if (!proxies[0] || !proxies[1]) {
joshualitt65171342014-10-09 07:25:36 -0700295 SkDebugf("Could not allocate dummy textures");
bsalomone904c092014-07-17 10:50:59 -0700296 return false;
297 }
298
Brian Salomond818ebf2018-07-02 14:08:49 +0000299 // dummy scissor state
300 GrScissorState scissor;
301
Brian Osman9f772a42017-07-10 13:03:50 -0400302 SkRandom random;
bsalomonf3261af2016-04-05 10:57:13 -0700303 static const int NUM_TESTS = 1024;
joshualitt6c891102015-05-13 08:51:49 -0700304 for (int t = 0; t < NUM_TESTS; t++) {
joshualitt65171342014-10-09 07:25:36 -0700305 // setup random render target(can fail)
Brian Salomonbf6b9792019-08-21 09:38:10 -0400306 auto renderTargetContext =
307 random_render_target_context(context, &random, context->priv().caps());
Brian Osman11052242016-10-27 14:47:55 -0400308 if (!renderTargetContext) {
309 SkDebugf("Could not allocate renderTargetContext");
joshualittf5883a62016-01-13 07:47:38 -0800310 return false;
311 }
robertphillips0dfa62c2015-11-16 06:23:31 -0800312
Brian Salomon17726632017-05-12 14:09:46 -0400313 GrPaint paint;
Robert Phillipse78b7252017-04-06 07:59:41 -0400314 GrProcessorTestData ptd(&random, context, renderTargetContext.get(), proxies);
Greg Daniel78325c12017-06-19 16:39:13 -0400315 set_random_color_coverage_stages(&paint, &ptd, maxStages, maxLevels);
Brian Salomon17726632017-05-12 14:09:46 -0400316 set_random_xpf(&paint, &ptd);
Brian Salomon17726632017-05-12 14:09:46 -0400317 GrDrawRandomOp(&random, renderTargetContext.get(), std::move(paint));
bsalomon@google.comc3841b92012-08-02 18:11:43 +0000318 }
joshualitt6c891102015-05-13 08:51:49 -0700319 // Flush everything, test passes if flush is successful(ie, no asserts are hit, no crashes)
Greg Daniel797efca2019-05-09 14:04:20 -0400320 drawingManager->flush(nullptr, 0, SkSurface::BackendSurfaceAccess::kNoAccess, GrFlushInfo(),
321 GrPrepareForExternalIORequests());
bsalomonb5b60322015-09-14 12:26:33 -0700322
323 // Validate that GrFPs work correctly without an input.
Brian Salomonbf6b9792019-08-21 09:38:10 -0400324 auto renderTargetContext =
Brian Salomon27ae52c2019-07-03 11:27:44 -0400325 context->priv().makeDeferredRenderTargetContext(SkBackingFit::kExact,
Brian Salomond6287472019-06-24 15:50:07 -0400326 kRenderTargetWidth,
327 kRenderTargetHeight,
Brian Salomond6287472019-06-24 15:50:07 -0400328 GrColorType::kRGBA_8888,
Brian Salomonbf6b9792019-08-21 09:38:10 -0400329 nullptr);
Brian Osman11052242016-10-27 14:47:55 -0400330 if (!renderTargetContext) {
331 SkDebugf("Could not allocate a renderTargetContext");
robertphillips82ec6e52016-05-19 14:01:05 -0700332 return false;
333 }
334
Brian Salomon1c053642017-07-24 10:16:19 -0400335 int fpFactoryCnt = GrFragmentProcessorTestFactory::Count();
bsalomonb5b60322015-09-14 12:26:33 -0700336 for (int i = 0; i < fpFactoryCnt; ++i) {
337 // Since FP factories internally randomize, call each 10 times.
338 for (int j = 0; j < 10; ++j) {
Robert Phillipse78b7252017-04-06 07:59:41 -0400339 GrProcessorTestData ptd(&random, context, renderTargetContext.get(), proxies);
bsalomonb5b60322015-09-14 12:26:33 -0700340
Brian Salomon17726632017-05-12 14:09:46 -0400341 GrPaint paint;
342 paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
Brian Salomonaff329b2017-08-11 09:40:37 -0400343 auto fp = GrFragmentProcessorTestFactory::MakeIdx(i, &ptd);
344 auto blockFP = BlockInputFragmentProcessor::Make(std::move(fp));
Brian Salomon17726632017-05-12 14:09:46 -0400345 paint.addColorFragmentProcessor(std::move(blockFP));
346 GrDrawRandomOp(&random, renderTargetContext.get(), std::move(paint));
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400347 drawingManager->flush(nullptr, 0, SkSurface::BackendSurfaceAccess::kNoAccess,
Greg Daniel797efca2019-05-09 14:04:20 -0400348 GrFlushInfo(), GrPrepareForExternalIORequests());
bsalomonb5b60322015-09-14 12:26:33 -0700349 }
350 }
351
bsalomon@google.comc3841b92012-08-02 18:11:43 +0000352 return true;
353}
Hal Canary6f6961e2017-01-31 13:50:44 -0500354#endif
bsalomon@google.coma8e686e2011-08-16 15:45:58 +0000355
Greg Danield895ca62017-06-19 14:39:43 -0400356static int get_glprograms_max_stages(const sk_gpu_test::ContextInfo& ctxInfo) {
357 GrContext* context = ctxInfo.grContext();
Robert Phillips9da87e02019-02-04 13:26:26 -0500358 GrGLGpu* gpu = static_cast<GrGLGpu*>(context->priv().getGpu());
Brian Salomone334c592017-05-15 11:00:58 -0400359 int maxStages = 6;
360 if (kGLES_GrGLStandard == gpu->glStandard()) {
361 // We've had issues with driver crashes and HW limits being exceeded with many effects on
362 // Android devices. We have passes on ARM devices with the default number of stages.
363 // TODO When we run ES 3.00 GLSL in more places, test again
364#ifdef SK_BUILD_FOR_ANDROID
365 if (kARM_GrGLVendor != gpu->ctxInfo().vendor()) {
366 maxStages = 1;
367 }
kkinnunen3e980c32015-12-23 01:33:00 -0800368#endif
Brian Salomone334c592017-05-15 11:00:58 -0400369 // On iOS we can exceed the maximum number of varyings. http://skbug.com/6627.
Brian Osman4e1868c2017-05-26 15:56:32 -0400370#ifdef SK_BUILD_FOR_IOS
Brian Salomone334c592017-05-15 11:00:58 -0400371 maxStages = 3;
372#endif
373 }
Greg Danield895ca62017-06-19 14:39:43 -0400374 if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D9_ES2_ContextType ||
375 ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES2_ContextType) {
376 // On Angle D3D we will hit a limit of out variables if we use too many stages.
377 maxStages = 3;
378 }
Brian Salomone334c592017-05-15 11:00:58 -0400379 return maxStages;
380}
381
Greg Daniel78325c12017-06-19 16:39:13 -0400382static int get_glprograms_max_levels(const sk_gpu_test::ContextInfo& ctxInfo) {
383 // A full tree with 5 levels (31 nodes) may cause a program that exceeds shader limits
384 // (e.g. uniform or varying limits); maxTreeLevels should be a number from 1 to 4 inclusive.
385 int maxTreeLevels = 4;
386 // On iOS we can exceed the maximum number of varyings. http://skbug.com/6627.
387#ifdef SK_BUILD_FOR_IOS
388 maxTreeLevels = 2;
389#endif
390 if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D9_ES2_ContextType ||
391 ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES2_ContextType) {
392 // On Angle D3D we will hit a limit of out variables if we use too many stages.
393 maxTreeLevels = 2;
394 }
395 return maxTreeLevels;
396}
397
Brian Salomone334c592017-05-15 11:00:58 -0400398static void test_glprograms(skiatest::Reporter* reporter, const sk_gpu_test::ContextInfo& ctxInfo) {
Greg Danield895ca62017-06-19 14:39:43 -0400399 int maxStages = get_glprograms_max_stages(ctxInfo);
kkinnunen3e980c32015-12-23 01:33:00 -0800400 if (maxStages == 0) {
401 return;
402 }
Greg Daniel78325c12017-06-19 16:39:13 -0400403 int maxLevels = get_glprograms_max_levels(ctxInfo);
404 if (maxLevels == 0) {
405 return;
406 }
Brian Osman9f772a42017-07-10 13:03:50 -0400407
Greg Daniel78325c12017-06-19 16:39:13 -0400408 REPORTER_ASSERT(reporter, GrDrawingManager::ProgramUnitTest(ctxInfo.grContext(), maxStages,
409 maxLevels));
kkinnunen3e980c32015-12-23 01:33:00 -0800410}
411
Brian Salomondcfca432017-11-15 15:48:03 -0500412DEF_GPUTEST(GLPrograms, reporter, options) {
bsalomon3318ee72015-03-16 11:56:29 -0700413 // Set a locale that would cause shader compilation to fail because of , as decimal separator.
414 // skbug 3330
415#ifdef SK_BUILD_FOR_WIN
416 GrAutoLocaleSetter als("sv-SE");
417#else
418 GrAutoLocaleSetter als("sv_SE.UTF-8");
419#endif
420
joshualitt6c891102015-05-13 08:51:49 -0700421 // We suppress prints to avoid spew
Brian Salomondcfca432017-11-15 15:48:03 -0500422 GrContextOptions opts = options;
joshualitt6c891102015-05-13 08:51:49 -0700423 opts.fSuppressPrints = true;
bsalomon3724e572016-03-30 18:56:19 -0700424 sk_gpu_test::GrContextFactory debugFactory(opts);
Brian Salomone334c592017-05-15 11:00:58 -0400425 skiatest::RunWithGPUTestContexts(test_glprograms, &skiatest::IsRenderingGLContextType, reporter,
Brian Salomondcfca432017-11-15 15:48:03 -0500426 opts);
bsalomon@google.coma8e686e2011-08-16 15:45:58 +0000427}
428