| Index: tests/GLProgramsTest.cpp
|
| diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
|
| index cd5bb9fc7c3bd5a2884288ef0f0add74643acbff..ce86c9bf38a7ff1807f07f18cab681edaa3fa521 100644
|
| --- a/tests/GLProgramsTest.cpp
|
| +++ b/tests/GLProgramsTest.cpp
|
| @@ -28,6 +28,7 @@
|
|
|
| #include "effects/GrConfigConversionEffect.h"
|
| #include "effects/GrPorterDuffXferProcessor.h"
|
| +#include "effects/GrXfermodeFragmentProcessor.h"
|
|
|
| #include "gl/GrGLGpu.h"
|
| #include "gl/GrGLPathRendering.h"
|
| @@ -136,23 +137,81 @@ static void set_random_xpf(GrPipelineBuilder* pipelineBuilder, GrProcessorTestDa
|
| pipelineBuilder->setXPFactory(xpf.get());
|
| }
|
|
|
| +static const GrFragmentProcessor* create_random_proc_tree(GrProcessorTestData* d,
|
| + int minLevels, int maxLevels) {
|
| + SkASSERT(1 <= minLevels);
|
| + SkASSERT(minLevels <= maxLevels);
|
| +
|
| + // Return a leaf node if maxLevels is 1 or if we randomly chose to terminate.
|
| + // If returning a leaf node, make sure that it doesn't have children (e.g. another
|
| + // GrComposeEffect)
|
| + const float terminateProbability = 0.3f;
|
| + if (1 == minLevels) {
|
| + bool terminate = (1 == maxLevels) || (d->fRandom->nextF() < terminateProbability);
|
| + if (terminate) {
|
| + const GrFragmentProcessor* fp;
|
| + while (true) {
|
| + fp = GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(d);
|
| + SkASSERT(fp);
|
| + if (0 == fp->numChildProcessors()) {
|
| + break;
|
| + }
|
| + fp->unref();
|
| + }
|
| + return fp;
|
| + }
|
| + }
|
| + // If we didn't terminate, choose either the left or right subtree to fulfill
|
| + // the minLevels requirement of this tree; the other child can have as few levels as it wants.
|
| + // Also choose a random xfer mode that's supported by CreateFrom2Procs().
|
| + if (minLevels > 1) {
|
| + --minLevels;
|
| + }
|
| + SkAutoTUnref<const GrFragmentProcessor> minLevelsChild(create_random_proc_tree(d, minLevels,
|
| + maxLevels - 1));
|
| + SkAutoTUnref<const GrFragmentProcessor> otherChild(create_random_proc_tree(d, 1,
|
| + maxLevels - 1));
|
| + SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(d->fRandom->nextRangeU(0,
|
| + SkXfermode::kLastCoeffMode));
|
| + const GrFragmentProcessor* fp;
|
| + if (d->fRandom->nextF() < 0.5f) {
|
| + fp = GrXfermodeFragmentProcessor::CreateFromTwoProcessors(minLevelsChild, otherChild, mode);
|
| + SkASSERT(fp);
|
| + } else {
|
| + fp = GrXfermodeFragmentProcessor::CreateFromTwoProcessors(otherChild, minLevelsChild, mode);
|
| + SkASSERT(fp);
|
| + }
|
| + return fp;
|
| +}
|
| +
|
| static void set_random_color_coverage_stages(GrPipelineBuilder* pipelineBuilder,
|
| GrProcessorTestData* d, int maxStages) {
|
| - int numProcs = d->fRandom->nextULessThan(maxStages + 1);
|
| - int numColorProcs = d->fRandom->nextULessThan(numProcs + 1);
|
| -
|
| - for (int s = 0; s < numProcs;) {
|
| + // Randomly choose to either create a linear pipeline of procs or create one proc tree
|
| + const float procTreeProbability = 0.5f;
|
| + if (d->fRandom->nextF() < procTreeProbability) {
|
| + // A full tree with 5 levels (31 nodes) may exceed the max allowed length of the gl
|
| + // processor key; maxTreeLevels should be a number from 1 to 4 inclusive.
|
| + const int maxTreeLevels = 4;
|
| SkAutoTUnref<const GrFragmentProcessor> fp(
|
| - GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(d));
|
| - SkASSERT(fp);
|
| + create_random_proc_tree(d, 2, maxTreeLevels));
|
| + pipelineBuilder->addColorFragmentProcessor(fp);
|
| + } else {
|
| + int numProcs = d->fRandom->nextULessThan(maxStages + 1);
|
| + int numColorProcs = d->fRandom->nextULessThan(numProcs + 1);
|
| +
|
| + for (int s = 0; s < numProcs;) {
|
| + SkAutoTUnref<const GrFragmentProcessor> fp(
|
| + GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(d));
|
| + SkASSERT(fp);
|
|
|
| - // finally add the stage to the correct pipeline in the drawstate
|
| - if (s < numColorProcs) {
|
| - pipelineBuilder->addColorFragmentProcessor(fp);
|
| - } else {
|
| - pipelineBuilder->addCoverageFragmentProcessor(fp);
|
| + // finally add the stage to the correct pipeline in the drawstate
|
| + if (s < numColorProcs) {
|
| + pipelineBuilder->addColorFragmentProcessor(fp);
|
| + } else {
|
| + pipelineBuilder->addCoverageFragmentProcessor(fp);
|
| + }
|
| + ++s;
|
| }
|
| - ++s;
|
| }
|
| }
|
|
|
|
|