diff options
author | Robert Phillips <robertphillips@google.com> | 2017-10-30 18:02:48 +0000 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-10-30 18:02:59 +0000 |
commit | ec3253472947b0df618261479336a7b50b24f0c8 (patch) | |
tree | 0d1dce628e874c17211b616a6258113643f0f00b | |
parent | 4c390b96f30a281acb1b072f447b83e879087926 (diff) |
Revert "Revert "Fix GrDefaultPathRender inversely wound path bug""
This reverts commit fc28138c0422637741ac2839914ef10c56438054.
Reason for revert: Suppression have landed for failing tests
Original change's description:
> Revert "Fix GrDefaultPathRender inversely wound path bug"
>
> This reverts commit 511a9d49998ec6a74c375e6cfc55f660f7987c40.
>
> Reason for revert: vulkan
>
> Original change's description:
> > Fix GrDefaultPathRender inversely wound path bug
> >
> > Bug: 769898
> > Change-Id: I3b1a43b1e114b35105493a0cfa01a1f01b65fa56
> > Reviewed-on: https://skia-review.googlesource.com/64065
> > Commit-Queue: Robert Phillips <robertphillips@google.com>
> > Reviewed-by: Brian Salomon <bsalomon@google.com>
>
> TBR=bsalomon@google.com,robertphillips@google.com
>
> Change-Id: Ib1a987294d14f0526bf5ff5a8fd90bbd5f6f3a0d
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: 769898
> Reviewed-on: https://skia-review.googlesource.com/65201
> Reviewed-by: Robert Phillips <robertphillips@google.com>
> Commit-Queue: Robert Phillips <robertphillips@google.com>
TBR=bsalomon@google.com,robertphillips@google.com
Change-Id: I3a3543c46b3192f1ffd31a5566cf337dc03561a8
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 769898
Reviewed-on: https://skia-review.googlesource.com/65202
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
-rw-r--r-- | dm/DM.cpp | 5 | ||||
-rw-r--r-- | gn/tests.gni | 1 | ||||
-rw-r--r-- | src/gpu/ops/GrDefaultPathRenderer.cpp | 6 | ||||
-rw-r--r-- | src/gpu/ops/GrMSAAPathRenderer.cpp | 6 | ||||
-rw-r--r-- | tests/DefaultPathRendererTest.cpp | 136 | ||||
-rw-r--r-- | tests/ResourceCacheTest.cpp | 2 | ||||
-rw-r--r-- | tests/Test.h | 49 |
7 files changed, 182 insertions, 23 deletions
@@ -1281,8 +1281,11 @@ static void run_test(skiatest::Test test, const GrContextOptions& grCtxOptions) } reporter; if (!FLAGS_dryRun && !is_blacklisted("_", "tests", "_", test.name)) { + GrContextOptions options = grCtxOptions; + test.modifyGrContextOptions(&options); + start("unit", "test", "", test.name); - GrContextFactory factory(grCtxOptions); + GrContextFactory factory(options); test.run(&reporter, &factory); } done("unit", "test", "", test.name); diff --git a/gn/tests.gni b/gn/tests.gni index 3c42b80ba2..b051326d8d 100644 --- a/gn/tests.gni +++ b/gn/tests.gni @@ -48,6 +48,7 @@ tests_sources = [ "$_tests/DashPathEffectTest.cpp", "$_tests/DataRefTest.cpp", "$_tests/DequeTest.cpp", + "$_tests/DefaultPathRendererTest.cpp", "$_tests/DetermineDomainModeTest.cpp", "$_tests/DeviceLooperTest.cpp", "$_tests/DeviceTest.cpp", diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp index 40631a74ff..4a9f0c2c04 100644 --- a/src/gpu/ops/GrDefaultPathRenderer.cpp +++ b/src/gpu/ops/GrDefaultPathRenderer.cpp @@ -568,8 +568,10 @@ bool GrDefaultPathRenderer::internalDrawPath(GrRenderTargetContext* renderTarget SkScalar srcSpaceTol = GrPathUtils::scaleToleranceToSrc(tol, viewMatrix, path.getBounds()); SkRect devBounds; - GetPathDevBounds(path, renderTargetContext->width(), renderTargetContext->height(), viewMatrix, - &devBounds); + GetPathDevBounds(path, + renderTargetContext->asRenderTargetProxy()->worstCaseWidth(), + renderTargetContext->asRenderTargetProxy()->worstCaseHeight(), + viewMatrix, &devBounds); for (int p = 0; p < passCount; ++p) { if (lastPassIsBounds && (p == passCount-1)) { diff --git a/src/gpu/ops/GrMSAAPathRenderer.cpp b/src/gpu/ops/GrMSAAPathRenderer.cpp index 27d78a782c..50741bc537 100644 --- a/src/gpu/ops/GrMSAAPathRenderer.cpp +++ b/src/gpu/ops/GrMSAAPathRenderer.cpp @@ -637,8 +637,10 @@ bool GrMSAAPathRenderer::internalDrawPath(GrRenderTargetContext* renderTargetCon } SkRect devBounds; - GetPathDevBounds(path, renderTargetContext->width(), renderTargetContext->height(), viewMatrix, - &devBounds); + GetPathDevBounds(path, + renderTargetContext->asRenderTargetProxy()->worstCaseWidth(), + renderTargetContext->asRenderTargetProxy()->worstCaseHeight(), + viewMatrix, &devBounds); SkASSERT(passes[0]); { // First pass diff --git a/tests/DefaultPathRendererTest.cpp b/tests/DefaultPathRendererTest.cpp new file mode 100644 index 0000000000..d1e102bc5e --- /dev/null +++ b/tests/DefaultPathRendererTest.cpp @@ -0,0 +1,136 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Test.h" + +#if SK_SUPPORT_GPU +#include "GrClip.h" +#include "GrRenderTargetContext.h" +#include "GrStyle.h" +#include "GrTypesPriv.h" + +#include "effects/GrConstColorProcessor.h" + +static void allow_default_and_msaa(GrContextOptions* options) { + options->fGpuPathRenderers = GpuPathRenderers::kMSAA; +} + +static void only_allow_default(GrContextOptions* options) { + options->fGpuPathRenderers = GpuPathRenderers::kNone; +} + +static SkBitmap read_back(GrRenderTargetContext* rtc, int width, int height) { + + SkImageInfo dstII = SkImageInfo::MakeN32Premul(width, height); + + SkBitmap bm; + bm.allocPixels(dstII); + + rtc->readPixels(dstII, bm.getAddr(0, 0), bm.rowBytes(), 0, 0, 0); + + return bm; +} + +static SkPath make_path(const SkRect& outer, int inset, SkPath::FillType fill) { + SkPath p; + + p.addRect(outer, SkPath::kCW_Direction); + p.addRect(outer.makeInset(inset, inset), SkPath::kCCW_Direction); + p.setFillType(fill); + return p; +} + + +static const int kBigSize = 64; // This should be a power of 2 +static const int kPad = 3; + +// From crbug.com/769898: +// create an approx fit render target context that will have extra space (i.e., npot) +// draw an inverse wound concave path into it - forcing use of the stencil-using path renderer +// throw the RTC away so the backing GrSurface/GrStencilBuffer can be reused +// create a new render target context that will reuse the prior GrSurface +// draw a normally wound concave path that touches outside of the approx fit RTC's content rect +// +// When the bug manifests the GrDefaultPathRenderer/GrMSAAPathRenderer is/was leaving the stencil +// buffer outside of the first content rect in a bad state and the second draw would be incorrect. + +static void run_test(GrContext* ctx, skiatest::Reporter* reporter) { + SkPath invPath = make_path(SkRect::MakeXYWH(0, 0, kBigSize, kBigSize), + kBigSize/2-1, SkPath::kInverseWinding_FillType); + SkPath path = make_path(SkRect::MakeXYWH(0, 0, kBigSize, kBigSize), + kPad, SkPath::kWinding_FillType); + + GrStyle style(SkStrokeRec::kFill_InitStyle); + + { + auto rtc = ctx->makeDeferredRenderTargetContext(SkBackingFit::kApprox, + kBigSize/2+1, kBigSize/2+1, + kRGBA_8888_GrPixelConfig, nullptr); + + rtc->clear(nullptr, GrColorPackRGBA(0x0, 0x0, 0x0, 0xFF), true); + + GrPaint paint; + + const GrColor4f color = { 1.0f, 0.0f, 0.0f, 1.0f }; + auto fp = GrConstColorProcessor::Make(color, GrConstColorProcessor::kIgnore_InputMode); + paint.addColorFragmentProcessor(std::move(fp)); + + rtc->drawPath(GrNoClip(), std::move(paint), GrAA::kNo, + SkMatrix::I(), invPath, style); + + rtc->prepareForExternalIO(0, nullptr); + } + + { + auto rtc = ctx->makeDeferredRenderTargetContext(SkBackingFit::kExact, kBigSize, kBigSize, + kRGBA_8888_GrPixelConfig, nullptr); + + rtc->clear(nullptr, GrColorPackRGBA(0x0, 0x0, 0x0, 0xFF), true); + + GrPaint paint; + + const GrColor4f color = { 0.0f, 1.0f, 0.0f, 1.0f }; + auto fp = GrConstColorProcessor::Make(color, GrConstColorProcessor::kIgnore_InputMode); + paint.addColorFragmentProcessor(std::move(fp)); + + rtc->drawPath(GrNoClip(), std::move(paint), GrAA::kNo, + SkMatrix::I(), path, style); + + SkBitmap bm = read_back(rtc.get(), kBigSize, kBigSize); + + bool correct = true; + for (int y = kBigSize/2+1; y < kBigSize-kPad-1 && correct; ++y) { + for (int x = kPad+1; x < kBigSize-kPad-1 && correct; ++x) { + correct = bm.getColor(x, y) == SK_ColorBLACK; + REPORTER_ASSERT(reporter, correct); + } + } + } + +} + +DEF_GPUTEST_FOR_CONTEXTS(GrDefaultPathRendererTest, + sk_gpu_test::GrContextFactory::IsRenderingContext, + reporter, ctxInfo, only_allow_default) { + GrContext* ctx = ctxInfo.grContext(); + + run_test(ctx, reporter); +} + +DEF_GPUTEST_FOR_CONTEXTS(GrMSAAPathRendererTest, + sk_gpu_test::GrContextFactory::IsRenderingContext, + reporter, ctxInfo, allow_default_and_msaa) { + GrContext* ctx = ctxInfo.grContext(); + + if (!ctx->caps()->sampleShadingSupport()) { // The MSAAPathRenderer requires this + return; + } + + run_test(ctx, reporter); +} + +#endif diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp index 0cb1d2b269..863830aefe 100644 --- a/tests/ResourceCacheTest.cpp +++ b/tests/ResourceCacheTest.cpp @@ -120,7 +120,7 @@ static sk_sp<GrRenderTarget> create_RT_with_SB(GrResourceProvider* provider, // This currently fails on ES3 ANGLE contexts DEF_GPUTEST_FOR_CONTEXTS(ResourceCacheStencilBuffers, &is_rendering_and_not_angle_es3, reporter, - ctxInfo) { + ctxInfo, nullptr) { GrContext* context = ctxInfo.grContext(); if (context->caps()->avoidStencilBuffers()) { return; diff --git a/tests/Test.h b/tests/Test.h index c9a381eb12..7ef29325b7 100644 --- a/tests/Test.h +++ b/tests/Test.h @@ -22,6 +22,7 @@ class ContextInfo; class GLTestContext; } // namespace sk_gpu_test class GrContext; +class GrContextOptions; #endif namespace skiatest { @@ -89,12 +90,21 @@ private: }; typedef void (*TestProc)(skiatest::Reporter*, sk_gpu_test::GrContextFactory*); +typedef void (*ContextOptionsProc)(GrContextOptions*); struct Test { - Test(const char* n, bool g, TestProc p) : name(n), needsGpu(g), proc(p) {} + Test(const char* n, bool g, TestProc p, ContextOptionsProc optionsProc = nullptr) + : name(n), needsGpu(g), proc(p), fContextOptionsProc(optionsProc) {} const char* name; bool needsGpu; TestProc proc; + ContextOptionsProc fContextOptionsProc; + + void modifyGrContextOptions(GrContextOptions* options) { + if (fContextOptionsProc) { + (*fContextOptionsProc)(options); + } + } void run(skiatest::Reporter* r, sk_gpu_test::GrContextFactory* factory) const { TRACE_EVENT1("test", TRACE_FUNC, "name", this->name/*these are static*/); @@ -200,31 +210,36 @@ private: skiatest::Test(#name, true, test_##name)); \ void test_##name(skiatest::Reporter* reporter, sk_gpu_test::GrContextFactory* factory) -#define DEF_GPUTEST_FOR_CONTEXTS(name, context_filter, reporter, context_info) \ - static void test_##name(skiatest::Reporter*, \ - const sk_gpu_test::ContextInfo& context_info); \ - static void test_gpu_contexts_##name(skiatest::Reporter* reporter, \ - sk_gpu_test::GrContextFactory* factory) { \ - skiatest::RunWithGPUTestContexts(test_##name, context_filter, reporter, factory); \ - } \ - skiatest::TestRegistry name##TestRegistry( \ - skiatest::Test(#name, true, test_gpu_contexts_##name)); \ - void test_##name(skiatest::Reporter* reporter, \ +#define DEF_GPUTEST_FOR_CONTEXTS(name, context_filter, reporter, context_info, options_filter) \ + static void test_##name(skiatest::Reporter*, \ + const sk_gpu_test::ContextInfo& context_info); \ + static void test_gpu_contexts_##name(skiatest::Reporter* reporter, \ + sk_gpu_test::GrContextFactory* factory) { \ + skiatest::RunWithGPUTestContexts(test_##name, context_filter, reporter, factory); \ + } \ + skiatest::TestRegistry name##TestRegistry( \ + skiatest::Test(#name, true, test_gpu_contexts_##name, options_filter)); \ + void test_##name(skiatest::Reporter* reporter, \ const sk_gpu_test::ContextInfo& context_info) #define DEF_GPUTEST_FOR_ALL_CONTEXTS(name, reporter, context_info) \ - DEF_GPUTEST_FOR_CONTEXTS(name, nullptr, reporter, context_info) + DEF_GPUTEST_FOR_CONTEXTS(name, nullptr, reporter, context_info, nullptr) + #define DEF_GPUTEST_FOR_RENDERING_CONTEXTS(name, reporter, context_info) \ DEF_GPUTEST_FOR_CONTEXTS(name, sk_gpu_test::GrContextFactory::IsRenderingContext, \ - reporter, context_info) + reporter, context_info, nullptr) #define DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(name, reporter, context_info) \ - DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsGLContextType, reporter, context_info) + DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsGLContextType, \ + reporter, context_info, nullptr) #define DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(name, reporter, context_info) \ - DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsRenderingGLContextType, reporter, context_info) + DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsRenderingGLContextType, \ + reporter, context_info, nullptr) #define DEF_GPUTEST_FOR_NULLGL_CONTEXT(name, reporter, context_info) \ - DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsNullGLContextType, reporter, context_info) + DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsNullGLContextType, \ + reporter, context_info, nullptr) #define DEF_GPUTEST_FOR_VULKAN_CONTEXT(name, reporter, context_info) \ - DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsVulkanContextType, reporter, context_info) + DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsVulkanContextType, \ + reporter, context_info, nullptr) #define REQUIRE_PDF_DOCUMENT(TEST_NAME, REPORTER) \ do { \ |