When filling nested rect path check for empty inner and empty outer rects

BUG=skia:5221
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1936073003

Review-Url: https://codereview.chromium.org/1936073003
This commit is contained in:
bsalomon 2016-05-02 13:22:13 -07:00 committed by Commit bot
parent 6536ae590e
commit 40ef48580b
5 changed files with 68 additions and 31 deletions

View File

@ -822,9 +822,10 @@ void GrDrawContext::drawPath(const GrClip& clip,
if (is_nested_rects(viewMatrix, path, strokeInfo, rects)) {
SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFillNestedRects(
paint.getColor(), viewMatrix, rects));
GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
this->getDrawTarget()->drawBatch(pipelineBuilder, batch);
if (batch) {
GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
this->getDrawTarget()->drawBatch(pipelineBuilder, batch);
}
return;
}
}

View File

@ -580,15 +580,14 @@ static void compute_rects(SkRect* devOutside, SkRect* devOutsideAssist, SkRect*
namespace GrAAStrokeRectBatch {
GrDrawBatch* Create(GrColor color,
const SkMatrix& viewMatrix,
const SkRect& devOutside,
const SkRect& devOutsideAssist,
const SkRect& devInside,
bool miterStroke,
bool degenerate) {
AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, miterStroke);
batch->append(color, devOutside, devOutsideAssist, devInside, degenerate);
GrDrawBatch* CreateFillBetweenRects(GrColor color,
const SkMatrix& viewMatrix,
const SkRect& devOutside,
const SkRect& devInside) {
SkASSERT(!devOutside.isEmpty())
SkASSERT(!devInside.isEmpty())
AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, true);
batch->append(color, devOutside, devOutside, devInside, false);
batch->init();
return batch;
}
@ -643,19 +642,21 @@ bool Append(GrBatch* origBatch,
DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) {
bool miterStroke = random->nextBool();
// Create mock stroke rect
SkRect outside = GrTest::TestRect(random);
SkScalar minDim = SkMinScalar(outside.width(), outside.height());
SkScalar strokeWidth = minDim * 0.1f;
SkRect outsideAssist = outside;
outsideAssist.outset(strokeWidth, strokeWidth);
SkRect inside = outside;
inside.inset(strokeWidth, strokeWidth);
// Create either a empty rect or a non-empty rect.
SkRect rect = random->nextBool() ? SkRect::MakeXYWH(10, 10, 50, 40) :
SkRect::MakeXYWH(6, 7, 0, 0);
SkScalar minDim = SkMinScalar(rect.width(), rect.height());
SkScalar strokeWidth = random->nextUScalar1() * minDim;
GrColor color = GrRandomColor(random);
return GrAAStrokeRectBatch::Create(color, GrTest::TestMatrix(random), outside, outsideAssist,
inside, miterStroke, inside.isFinite() && inside.isEmpty());
SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
rec.setStrokeStyle(strokeWidth);
rec.setStrokeParams(SkPaint::kButt_Cap,
miterStroke ? SkPaint::kMiter_Join : SkPaint::kBevel_Join,
1.f);
SkMatrix matrix = GrTest::TestMatrixRectStaysRect(random);
return GrAAStrokeRectBatch::Create(color, matrix, rect, rec);
}
#endif

View File

@ -19,13 +19,10 @@ class SkStrokeRec;
namespace GrAAStrokeRectBatch {
GrDrawBatch* Create(GrColor color,
const SkMatrix& viewMatrix,
const SkRect& devOutside,
const SkRect& devOutsideAssist,
const SkRect& devInside,
bool miterStroke,
bool degenerate);
GrDrawBatch* CreateFillBetweenRects(GrColor color,
const SkMatrix& viewMatrix,
const SkRect& devOutside,
const SkRect& devInside);
GrDrawBatch* Create(GrColor color,
const SkMatrix& viewMatrix,

View File

@ -22,9 +22,14 @@ GrDrawBatch* CreateAAFillNestedRects(GrColor color,
SkRect devOutside, devInside;
viewMatrix.mapRect(&devOutside, rects[0]);
viewMatrix.mapRect(&devInside, rects[1]);
if (devInside.isEmpty()) {
if (devOutside.isEmpty()) {
return nullptr;
}
return GrAAFillRectBatch::Create(color, viewMatrix, devOutside, devOutside);
}
return GrAAStrokeRectBatch::Create(color, viewMatrix, devOutside, devOutside, devInside, true,
devInside.isEmpty());
return GrAAStrokeRectBatch::CreateFillBetweenRects(color, viewMatrix, devOutside, devInside);
}
};

33
tests/skbug5221.cpp Normal file
View File

@ -0,0 +1,33 @@
/*
* Copyright 2016 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"
#include "SkCanvas.h"
#include "SkSurface.h"
// This passes by not crashing.
static void test(SkCanvas* canvas) {
SkPaint paint;
paint.setAntiAlias(true);
canvas->scale(63, 0);
static const char kTxt[] = "A";
canvas->drawText(kTxt, SK_ARRAY_COUNT(kTxt), 50, 50, paint);
}
DEF_TEST(skbug5221, r) {
sk_sp<SkSurface> surface(SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(256, 256)));
test(surface->getCanvas());
}
#if SK_SUPPORT_GPU
DEF_GPUTEST_FOR_ALL_CONTEXTS(skbug5221_GPU, r, contextInfo) {
sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(contextInfo.fGrContext, SkBudgeted::kYes,
SkImageInfo::MakeN32Premul(256, 256), 0,
nullptr));
test(surface->getCanvas());
}
#endif