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; }