static void set_random_color_coverage_stages(GrPaint* paint, GrProcessorTestData* d, int maxStages, int maxTreeLevels) { // 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) { std::unique_ptr<GrFragmentProcessor> fp(create_random_proc_tree(d, 2, maxTreeLevels)); if (fp) { paint->addColorFragmentProcessor(std::move(fp)); } } else { int numProcs = d->fRandom->nextULessThan(maxStages + 1); int numColorProcs = d->fRandom->nextULessThan(numProcs + 1); for (int s = 0; s < numProcs;) { std::unique_ptr<GrFragmentProcessor> fp(GrFragmentProcessorTestFactory::Make(d)); SkASSERT(fp); // finally add the stage to the correct pipeline in the drawstate if (s < numColorProcs) { paint->addColorFragmentProcessor(std::move(fp)); } else { paint->addCoverageFragmentProcessor(std::move(fp)); } ++s; } } }
static void set_random_color_coverage_stages(GrPaint* paint, GrProcessorTestData* d, int maxStages) { // 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; sk_sp<GrFragmentProcessor> fp(create_random_proc_tree(d, 2, maxTreeLevels)); paint->addColorFragmentProcessor(std::move(fp)); } else { int numProcs = d->fRandom->nextULessThan(maxStages + 1); int numColorProcs = d->fRandom->nextULessThan(numProcs + 1); for (int s = 0; s < numProcs;) { sk_sp<GrFragmentProcessor> fp(GrProcessorTestFactory<GrFragmentProcessor>::Make(d)); SkASSERT(fp); // finally add the stage to the correct pipeline in the drawstate if (s < numColorProcs) { paint->addColorFragmentProcessor(std::move(fp)); } else { paint->addCoverageFragmentProcessor(std::move(fp)); } ++s; } } }
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>::Create(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 std::unique_ptr<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) { std::unique_ptr<GrFragmentProcessor> fp; while (true) { fp = GrFragmentProcessorTestFactory::Make(d); SkASSERT(fp); if (0 == fp->numChildProcessors()) { break; } } 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. if (minLevels > 1) { --minLevels; } auto minLevelsChild = create_random_proc_tree(d, minLevels, maxLevels - 1); std::unique_ptr<GrFragmentProcessor> otherChild(create_random_proc_tree(d, 1, maxLevels - 1)); SkBlendMode mode = static_cast<SkBlendMode>(d->fRandom->nextRangeU(0, (int)SkBlendMode::kLastMode)); std::unique_ptr<GrFragmentProcessor> fp; if (d->fRandom->nextF() < 0.5f) { fp = GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(minLevelsChild), std::move(otherChild), mode); SkASSERT(fp); } else { fp = GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(otherChild), std::move(minLevelsChild), mode); SkASSERT(fp); } return fp; }