From c52968170df32d88bc4cb27a80a0beed7586e0d3 Mon Sep 17 00:00:00 2001 From: Greg Daniel Date: Fri, 28 Feb 2020 13:06:02 -0500 Subject: [PATCH] Fix CompatibleCoverageAsAlpha flag when reducing src-over to src. Change-Id: I087ff64e0f23aee15ac2bf7b9d3c450e28400cef Reviewed-on: https://skia-review.googlesource.com/c/skia/+/274036 Commit-Queue: Greg Daniel Reviewed-by: Brian Salomon --- gn/tests.gni | 1 + src/gpu/GrXferProcessor.cpp | 3 +++ tests/GrPorterDuffTest.cpp | 30 +++++++++++----------- tests/SrcSrcOverBatchTest.cpp | 47 +++++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 tests/SrcSrcOverBatchTest.cpp diff --git a/gn/tests.gni b/gn/tests.gni index 679dc251de..7acbc7266e 100644 --- a/gn/tests.gni +++ b/gn/tests.gni @@ -266,6 +266,7 @@ tests_sources = [ "$_tests/SpecialImageTest.cpp", "$_tests/SpecialSurfaceTest.cpp", "$_tests/SrcOverTest.cpp", + "$_tests/SrcSrcOverBatchTest.cpp", "$_tests/StreamBufferTest.cpp", "$_tests/StreamTest.cpp", "$_tests/StringTest.cpp", diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp index 359dfb0c4a..bcfa550665 100644 --- a/src/gpu/GrXferProcessor.cpp +++ b/src/gpu/GrXferProcessor.cpp @@ -166,6 +166,9 @@ GrXPFactory::AnalysisProperties GrXPFactory::GetAnalysisProperties( result = GrPorterDuffXPFactory::SrcOverAnalysisProperties(color, coverage, caps, clampType); } + if (coverage == GrProcessorAnalysisCoverage::kNone) { + result |= AnalysisProperties::kCompatibleWithCoverageAsAlpha; + } SkASSERT(!(result & AnalysisProperties::kRequiresDstTexture)); if ((result & AnalysisProperties::kReadsDstInShader) && !caps.shaderCaps()->dstReadInShaderSupport()) { diff --git a/tests/GrPorterDuffTest.cpp b/tests/GrPorterDuffTest.cpp index 6f70933f68..c3af99d77e 100644 --- a/tests/GrPorterDuffTest.cpp +++ b/tests/GrPorterDuffTest.cpp @@ -459,7 +459,7 @@ static void test_color_not_opaque_no_coverage(skiatest::Reporter* reporter, cons switch (xfermode) { case SkBlendMode::kClear: TEST_ASSERT(xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -469,7 +469,7 @@ static void test_color_not_opaque_no_coverage(skiatest::Reporter* reporter, cons break; case SkBlendMode::kSrc: TEST_ASSERT(!xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -509,7 +509,7 @@ static void test_color_not_opaque_no_coverage(skiatest::Reporter* reporter, cons break; case SkBlendMode::kSrcIn: TEST_ASSERT(!xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -519,7 +519,7 @@ static void test_color_not_opaque_no_coverage(skiatest::Reporter* reporter, cons break; case SkBlendMode::kDstIn: TEST_ASSERT(!xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -529,7 +529,7 @@ static void test_color_not_opaque_no_coverage(skiatest::Reporter* reporter, cons break; case SkBlendMode::kSrcOut: TEST_ASSERT(!xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -559,7 +559,7 @@ static void test_color_not_opaque_no_coverage(skiatest::Reporter* reporter, cons break; case SkBlendMode::kDstATop: TEST_ASSERT(!xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -589,7 +589,7 @@ static void test_color_not_opaque_no_coverage(skiatest::Reporter* reporter, cons break; case SkBlendMode::kModulate: TEST_ASSERT(!xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -789,7 +789,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr switch (xfermode) { case SkBlendMode::kClear: TEST_ASSERT(xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -799,7 +799,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kSrc: TEST_ASSERT(!xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -844,7 +844,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kSrcIn: TEST_ASSERT(!xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -864,7 +864,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kSrcOut: TEST_ASSERT(!xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -874,7 +874,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kDstOut: TEST_ASSERT(xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -884,7 +884,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kSrcATop: TEST_ASSERT(!xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -904,7 +904,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kXor: TEST_ASSERT(!xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -924,7 +924,7 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kModulate: TEST_ASSERT(!xpi.fIgnoresInputColor); - TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); diff --git a/tests/SrcSrcOverBatchTest.cpp b/tests/SrcSrcOverBatchTest.cpp new file mode 100644 index 0000000000..48e5a39b6f --- /dev/null +++ b/tests/SrcSrcOverBatchTest.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2020 Google LLC + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// We want to make sure that if we collapse src-over down to src when blending, that batching still +// works correctly with a draw that explicitly requests src. + +#include "include/core/SkCanvas.h" +#include "include/core/SkShader.h" +#include "include/core/SkSurface.h" +#include "tests/Test.h" +#include "tools/gpu/GrContextFactory.h" + +DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SrcSrcOverBatchTest, reporter, ctxInfo) { + GrContext* ctx = ctxInfo.grContext(); + + static const int kSize = 8; + const SkImageInfo ii = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, + kPremul_SkAlphaType); + + sk_sp surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, + ii, 0, kTopLeft_GrSurfaceOrigin, + nullptr)); + + auto canvas = surface->getCanvas(); + + SkPaint paint; + // Setting a shader so that we actually build a processor set and don't fallback to all + // defaults. + paint.setShader(SkShaders::Color(SK_ColorRED)); + + SkIRect rect = SkIRect::MakeWH(2, 2); + + canvas->drawIRect(rect, paint); + + // Now draw a rect with src blend mode. If we collapsed the previous draw to src blend mode (a + // setting on caps plus not having any coverage), then we expect this second draw to try to + // batch with it. This test is a success if we don't hit any asserts, specifically making sure + // that both things we decided can be batched together claim to have the same value for + // CompatibleWithCoverageAsAlpha. + canvas->translate(3, 0); + paint.setBlendMode(SkBlendMode::kSrc); + canvas->drawIRect(rect, paint); +}