diff options
author | Brian Salomon <bsalomon@google.com> | 2017-01-27 10:59:27 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-01-27 16:43:38 +0000 |
commit | 587e08f361ee3e775a6bbc6dca761dbba82e422c (patch) | |
tree | 9f64e10d50fab820419d29dea30a6c978c86c8c9 /tests/ProcessorTest.cpp | |
parent | 4d3adb6b0dea1c9f74fc00b007dfb1af425fc727 (diff) |
Revert "Revert "Start of rewrite of GrFragmentProcessor optimizations.""
This reverts commit 052fd5158f7f85e478a9f87c45fecaacf7d0f5f3.
Disables the test (of unused code) until platform-specific issues are addressed.
Change-Id: I7aa23a07954fccf382aa07d28afcbffb0bebcd6d
Reviewed-on: https://skia-review.googlesource.com/7656
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'tests/ProcessorTest.cpp')
-rw-r--r-- | tests/ProcessorTest.cpp | 146 |
1 files changed, 144 insertions, 2 deletions
diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp index 398e702f7e..ff31e49619 100644 --- a/tests/ProcessorTest.cpp +++ b/tests/ProcessorTest.cpp @@ -70,7 +70,7 @@ public: private: TestFP(const SkTArray<sk_sp<GrTexture>>& textures, const SkTArray<sk_sp<GrBuffer>>& buffers, const SkTArray<Image>& images) - : fSamplers(4), fBuffers(4), fImages(4) { + : INHERITED(kNone_OptimizationFlags), fSamplers(4), fBuffers(4), fImages(4) { for (const auto& texture : textures) { this->addTextureSampler(&fSamplers.emplace_back(texture.get())); } @@ -83,7 +83,8 @@ private: } } - TestFP(sk_sp<GrFragmentProcessor> child) : fSamplers(4), fBuffers(4), fImages(4) { + TestFP(sk_sp<GrFragmentProcessor> child) + : INHERITED(kNone_OptimizationFlags), fSamplers(4), fBuffers(4), fImages(4) { this->registerChildProcessor(std::move(child)); } @@ -106,6 +107,7 @@ private: GrTAllocator<TextureSampler> fSamplers; GrTAllocator<BufferAccess> fBuffers; GrTAllocator<ImageStorageAccess> fImages; + typedef GrFragmentProcessor INHERITED; }; } @@ -230,4 +232,144 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ProcessorRefTest, reporter, ctxInfo) { } } } + +// This test uses the random GrFragmentProcessor test factory, which relies on static initializers. +#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS + +static GrColor texel_color(int i, int j) { + SkASSERT((unsigned)i < 256 && (unsigned)j < 256); + GrColor color = GrColorPackRGBA(j, (uint8_t)(i + j), (uint8_t)(2 * j - i), i); + return GrPremulColor(color); +} + +static GrColor4f texel_color4f(int i, int j) { return GrColor4f::FromGrColor(texel_color(i, j)); } + +DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProcessorOptimizationValidationTest, reporter, ctxInfo) { + // This tests code under development but not used in skia lib. Leaving this disabled until + // some platform-specific issues are addressed. + if (1) { + return; + } + GrContext* context = ctxInfo.grContext(); + using FPFactory = GrProcessorTestFactory<GrFragmentProcessor>; + SkRandom random; + sk_sp<GrRenderTargetContext> rtc = context->makeRenderTargetContext( + SkBackingFit::kExact, 256, 256, kRGBA_8888_GrPixelConfig, nullptr); + GrSurfaceDesc desc; + desc.fWidth = 256; + desc.fHeight = 256; + desc.fFlags = kRenderTarget_GrSurfaceFlag; + desc.fConfig = kRGBA_8888_GrPixelConfig; + sk_sp<GrTexture> tex0(context->textureProvider()->createTexture(desc, SkBudgeted::kYes)); + desc.fConfig = kAlpha_8_GrPixelConfig; + sk_sp<GrTexture> tex1(context->textureProvider()->createTexture(desc, SkBudgeted::kYes)); + GrTexture* textures[] = {tex0.get(), tex1.get()}; + GrProcessorTestData testData(&random, context, rtc.get(), textures); + + std::unique_ptr<GrColor> data(new GrColor[256 * 256]); + for (int y = 0; y < 256; ++y) { + for (int x = 0; x < 256; ++x) { + data.get()[256 * y + x] = texel_color(x, y); + } + } + desc.fConfig = kRGBA_8888_GrPixelConfig; + sk_sp<GrTexture> dataTexture(context->textureProvider()->createTexture( + desc, SkBudgeted::kYes, data.get(), 256 * sizeof(GrColor))); + + // Because processors factories configure themselves in random ways, this is not exhaustive. + for (int i = 0; i < FPFactory::Count(); ++i) { + int timesToInvokeFactory = 5; + // Increase the number of attempts if the FP has child FPs since optimizations likely depend + // on child optimizations being present. + sk_sp<GrFragmentProcessor> fp = FPFactory::MakeIdx(i, &testData); + for (int j = 0; j < fp->numChildProcessors(); ++j) { + // This value made a reasonable trade off between time and coverage when this test was + // written. + timesToInvokeFactory *= FPFactory::Count() / 2; + } + for (int j = 0; j < timesToInvokeFactory; ++j) { + fp = FPFactory::MakeIdx(i, &testData); + if (!fp->hasConstantOutputForConstantInput() && !fp->preservesOpaqueInput() && + !fp->modulatesInput()) { + continue; + } + GrPaint paint; + paint.addColorTextureProcessor(dataTexture.get(), nullptr, SkMatrix::I()); + paint.addColorFragmentProcessor(fp); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); + rtc->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), + SkRect::MakeWH(256.f, 256.f)); + memset(data.get(), 0x0, sizeof(GrColor) * 256 * 256); + rtc->readPixels( + SkImageInfo::Make(256, 256, kRGBA_8888_SkColorType, kPremul_SkAlphaType), + data.get(), 0, 0, 0); + bool passing = true; + if (0) { // Useful to see what FPs are being tested. + SkString children; + for (int c = 0; c < fp->numChildProcessors(); ++c) { + if (!c) { + children.append("("); + } + children.append(fp->childProcessor(c).name()); + children.append(c == fp->numChildProcessors() - 1 ? ")" : ", "); + } + SkDebugf("%s %s\n", fp->name(), children.c_str()); + } + for (int y = 0; y < 256 && passing; ++y) { + for (int x = 0; x < 256 && passing; ++x) { + GrColor input = texel_color(x, y); + GrColor output = data.get()[y * 256 + x]; + if (fp->modulatesInput()) { + // A modulating processor is allowed to modulate either the input color or + // just the input alpha. + bool legalColorModulation = + GrColorUnpackA(output) <= GrColorUnpackA(input) && + GrColorUnpackR(output) <= GrColorUnpackR(input) && + GrColorUnpackG(output) <= GrColorUnpackG(input) && + GrColorUnpackB(output) <= GrColorUnpackB(input); + bool legalAlphaModulation = + GrColorUnpackA(output) <= GrColorUnpackA(input) && + GrColorUnpackR(output) <= GrColorUnpackA(input) && + GrColorUnpackG(output) <= GrColorUnpackA(input) && + GrColorUnpackB(output) <= GrColorUnpackA(input); + if (!legalColorModulation && !legalAlphaModulation) { + ERRORF(reporter, + "\"Modulating\" processor %s made color/alpha value larger. " + "Input: 0x%0x8, Output: 0x%08x.", + fp->name(), input, output); + passing = false; + } + } + GrColor4f input4f = texel_color4f(x, y); + GrColor4f output4f = GrColor4f::FromGrColor(output); + GrColor4f expected4f; + if (fp->hasConstantOutputForConstantInput(input4f, &expected4f)) { + float rDiff = fabsf(output4f.fRGBA[0] - expected4f.fRGBA[0]); + float gDiff = fabsf(output4f.fRGBA[1] - expected4f.fRGBA[1]); + float bDiff = fabsf(output4f.fRGBA[2] - expected4f.fRGBA[2]); + float aDiff = fabsf(output4f.fRGBA[3] - expected4f.fRGBA[3]); + static constexpr float kTol = 3 / 255.f; + if (rDiff > kTol || gDiff > kTol || bDiff > kTol || aDiff > kTol) { + ERRORF(reporter, + "Processor %s claimed output for const input doesn't match " + "actual output.", + fp->name()); + passing = false; + } + } + if (GrColorIsOpaque(input) && fp->preservesOpaqueInput() && + !GrColorIsOpaque(output)) { + ERRORF(reporter, + "Processor %s claimed opaqueness is preserved but it is not. Input: " + "0x%0x8, Output: 0x%08x.", + fp->name(), input, output); + passing = false; + } + } + } + } + } +} +#endif + #endif |