Index: tests/GLProgramsTest.cpp |
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp |
index ce86c9bf38a7ff1807f07f18cab681edaa3fa521..ba64a7c9cb12f34d2943c2fc748679f25308a24f 100644 |
--- a/tests/GLProgramsTest.cpp |
+++ b/tests/GLProgramsTest.cpp |
@@ -47,7 +47,11 @@ public: |
virtual void emitCode(EmitArgs& args) override { |
// pass through |
GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); |
- fsBuilder->codeAppendf("%s = %s;\n", args.fOutputColor, args.fInputColor); |
+ if (args.fInputColor) { |
+ fsBuilder->codeAppendf("%s = %s;\n", args.fOutputColor, args.fInputColor); |
+ } else { |
+ fsBuilder->codeAppendf("%s = vec4(1.0);\n", args.fOutputColor); |
+ } |
} |
static void GenKey(const GrProcessor& processor, const GrGLSLCaps&, GrProcessorKeyBuilder* b) { |
@@ -95,6 +99,49 @@ const GrFragmentProcessor* BigKeyProcessor::TestCreate(GrProcessorTestData*) { |
return BigKeyProcessor::Create(); |
} |
+////////////////////////////////////////////////////////////////////////////// |
+ |
+class BlockInputFragmentProcessor : public GrFragmentProcessor { |
+public: |
+ static GrFragmentProcessor* Create(const GrFragmentProcessor* fp) { |
+ return new BlockInputFragmentProcessor(fp); |
+ } |
+ |
+ const char* name() const override { return "Block Input"; } |
+ |
+ GrGLFragmentProcessor* onCreateGLInstance() const override { return new GLFP; } |
+ |
+private: |
+ class GLFP : public GrGLFragmentProcessor { |
+ public: |
+ void emitCode(EmitArgs& args) override { |
+ this->emitChild(0, nullptr, args.fOutputColor, args); |
+ } |
+ |
+ private: |
+ typedef GrGLFragmentProcessor INHERITED; |
+ }; |
+ |
+ BlockInputFragmentProcessor(const GrFragmentProcessor* child) { |
+ this->initClassID<BlockInputFragmentProcessor>(); |
+ this->registerChildProcessor(child); |
+ } |
+ |
+ void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {} |
+ |
+ bool onIsEqual(const GrFragmentProcessor&) const override { return true; } |
+ |
+ void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
+ inout->setToOther(kRGBA_GrColorComponentFlags, GrColor_WHITE, |
+ GrInvariantOutput::kWillNot_ReadInput); |
+ this->childProcessor(0).computeInvariantOutput(inout); |
+ } |
+ |
+ typedef GrFragmentProcessor INHERITED; |
+}; |
+ |
+////////////////////////////////////////////////////////////////////////////// |
+ |
/* |
* Begin test code |
*/ |
@@ -132,7 +179,7 @@ static GrRenderTarget* random_render_target(GrTextureProvider* textureProvider, |
} |
static void set_random_xpf(GrPipelineBuilder* pipelineBuilder, GrProcessorTestData* d) { |
- SkAutoTUnref<const GrXPFactory> xpf(GrProcessorTestFactory<GrXPFactory>::CreateStage(d)); |
+ SkAutoTUnref<const GrXPFactory> xpf(GrProcessorTestFactory<GrXPFactory>::Create(d)); |
SkASSERT(xpf); |
pipelineBuilder->setXPFactory(xpf.get()); |
} |
@@ -151,7 +198,7 @@ static const GrFragmentProcessor* create_random_proc_tree(GrProcessorTestData* d |
if (terminate) { |
const GrFragmentProcessor* fp; |
while (true) { |
- fp = GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(d); |
+ fp = GrProcessorTestFactory<GrFragmentProcessor>::Create(d); |
SkASSERT(fp); |
if (0 == fp->numChildProcessors()) { |
break; |
@@ -201,7 +248,7 @@ static void set_random_color_coverage_stages(GrPipelineBuilder* pipelineBuilder, |
for (int s = 0; s < numProcs;) { |
SkAutoTUnref<const GrFragmentProcessor> fp( |
- GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(d)); |
+ GrProcessorTestFactory<GrFragmentProcessor>::Create(d)); |
SkASSERT(fp); |
// finally add the stage to the correct pipeline in the drawstate |
@@ -309,9 +356,42 @@ bool GrDrawTarget::programUnitTest(GrContext* context, int maxStages) { |
this->drawBatch(pipelineBuilder, batch); |
} |
- |
// Flush everything, test passes if flush is successful(ie, no asserts are hit, no crashes) |
this->flush(); |
+ |
+ // Validate that GrFPs work correctly without an input. |
+ GrSurfaceDesc rtDesc; |
+ rtDesc.fWidth = kRenderTargetWidth; |
+ rtDesc.fHeight = kRenderTargetHeight; |
+ rtDesc.fFlags = kRenderTarget_GrSurfaceFlag; |
+ rtDesc.fConfig = kRGBA_8888_GrPixelConfig; |
+ SkAutoTUnref<GrRenderTarget> rt( |
+ fContext->textureProvider()->createTexture(rtDesc, false)->asRenderTarget()); |
+ int fpFactoryCnt = GrProcessorTestFactory<GrFragmentProcessor>::Count(); |
+ for (int i = 0; i < fpFactoryCnt; ++i) { |
+ // Since FP factories internally randomize, call each 10 times. |
+ for (int j = 0; j < 10; ++j) { |
+ SkAutoTUnref<GrDrawBatch> batch(GrRandomDrawBatch(&random, context)); |
+ SkASSERT(batch); |
+ GrProcessorDataManager procDataManager; |
+ GrProcessorTestData ptd(&random, context, &procDataManager, this->caps(), |
+ dummyTextures); |
+ GrPipelineBuilder builder; |
+ builder.setXPFactory(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref(); |
+ builder.setRenderTarget(rt); |
+ builder.setClip(clip); |
+ |
+ SkAutoTUnref<const GrFragmentProcessor> fp( |
+ GrProcessorTestFactory<GrFragmentProcessor>::CreateIdx(i, &ptd)); |
+ SkAutoTUnref<const GrFragmentProcessor> blockFP( |
+ BlockInputFragmentProcessor::Create(fp)); |
+ builder.addColorFragmentProcessor(blockFP); |
+ |
+ this->drawBatch(builder, batch); |
+ this->flush(); |
+ } |
+ } |
+ |
return true; |
} |