Move determiniation of strokerect rects internal

BUG=skia:

Review URL: https://codereview.chromium.org/1345853005
This commit is contained in:
joshualitt 2015-09-22 12:50:33 -07:00 committed by Commit bot
parent 7f69144aaa
commit 10cae83e4b
5 changed files with 107 additions and 85 deletions

View File

@ -273,13 +273,12 @@ void GrDrawContext::drawRect(GrRenderTarget* rt,
if (needAA && canApplyAA) {
SkASSERT(!viewMatrix.hasPerspective());
SkRect devBoundRect;
viewMatrix.mapRect(&devBoundRect, rect);
SkAutoTUnref<GrDrawBatch> batch;
if (width >= 0) {
batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, rect, devBoundRect,
*strokeInfo));
batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, rect, *strokeInfo));
} else {
SkRect devBoundRect;
viewMatrix.mapRect(&devBoundRect, rect);
batch.reset(GrRectBatchFactory::CreateAAFill(color, viewMatrix, rect, devBoundRect));
}
fDrawTarget->drawBatch(pipelineBuilder, batch);

View File

@ -520,6 +520,68 @@ void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices,
}
}
inline static bool is_miter(const SkStrokeRec& stroke) {
// For hairlines, make bevel and round joins appear the same as mitered ones.
// small miter limit means right angles show bevel...
if ((stroke.getWidth() > 0) && (stroke.getJoin() != SkPaint::kMiter_Join ||
stroke.getMiter() < SK_ScalarSqrt2)) {
return false;
}
return true;
}
static void compute_rects(SkRect* devOutside, SkRect* devOutsideAssist, SkRect* devInside,
bool* isDegenerate, const SkMatrix& viewMatrix, const SkRect& rect,
SkScalar strokeWidth, bool miterStroke) {
SkRect devRect;
viewMatrix.mapRect(&devRect, rect);
SkVector devStrokeSize;
if (strokeWidth > 0) {
devStrokeSize.set(strokeWidth, strokeWidth);
viewMatrix.mapVectors(&devStrokeSize, 1);
devStrokeSize.setAbs(devStrokeSize);
} else {
devStrokeSize.set(SK_Scalar1, SK_Scalar1);
}
const SkScalar dx = devStrokeSize.fX;
const SkScalar dy = devStrokeSize.fY;
const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf);
const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf);
*devOutside = devRect;
*devOutsideAssist = devRect;
*devInside = devRect;
devOutside->outset(rx, ry);
devInside->inset(rx, ry);
// If we have a degenerate stroking rect(ie the stroke is larger than inner rect) then we
// make a degenerate inside rect to avoid double hitting. We will also jam all of the points
// together when we render these rects.
SkScalar spare;
{
SkScalar w = devRect.width() - dx;
SkScalar h = devRect.height() - dy;
spare = SkTMin(w, h);
}
*isDegenerate = spare <= 0;
if (*isDegenerate) {
devInside->fLeft = devInside->fRight = devRect.centerX();
devInside->fTop = devInside->fBottom = devRect.centerY();
}
// For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist)
// to draw the outside of the octagon. Because there are 8 vertices on the outer
// edge, while vertex number of inner edge is 4, the same as miter-stroke.
if (!miterStroke) {
devOutside->inset(0, ry);
devOutsideAssist->outset(0, ry);
}
}
namespace GrAAStrokeRectBatch {
GrDrawBatch* Create(GrColor color,
@ -535,22 +597,42 @@ GrDrawBatch* Create(GrColor color,
return batch;
}
GrDrawBatch* Create(GrColor color,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkStrokeRec& stroke) {
bool isMiterStroke = is_miter(stroke);
AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, isMiterStroke);
SkRect devOutside, devOutsideAssist, devInside;
bool isDegenerate;
compute_rects(&devOutside, &devOutsideAssist, &devInside, &isDegenerate, viewMatrix,
rect, stroke.getWidth(), isMiterStroke);
batch->append(color, devOutside, devOutsideAssist, devInside, isDegenerate);
batch->init();
return batch;
}
bool Append(GrBatch* origBatch,
GrColor color,
const SkMatrix& viewMatrix,
const SkRect& devOutside,
const SkRect& devOutsideAssist,
const SkRect& devInside,
bool miterStroke,
bool degenerate) {
const SkRect& rect,
const SkStrokeRec& stroke) {
AAStrokeRectBatch* batch = origBatch->cast<AAStrokeRectBatch>();
// we can't batch across vm changes
if (!batch->canAppend(viewMatrix, miterStroke)) {
bool isMiterStroke = is_miter(stroke);
if (!batch->canAppend(viewMatrix, isMiterStroke)) {
return false;
}
batch->appendAndUpdateBounds(color, devOutside, devOutsideAssist, devInside, degenerate);
SkRect devOutside, devOutsideAssist, devInside;
bool isDegenerate;
compute_rects(&devOutside, &devOutsideAssist, &devInside, &isDegenerate, viewMatrix,
rect, stroke.getWidth(), isMiterStroke);
batch->appendAndUpdateBounds(color, devOutside, devOutsideAssist, devInside, isDegenerate);
return true;
}

View File

@ -15,6 +15,7 @@ class GrDrawBatch;
class GrResourceProvider;
class SkMatrix;
struct SkRect;
class SkStrokeRec;
namespace GrAAStrokeRectBatch {
@ -26,14 +27,16 @@ GrDrawBatch* Create(GrColor color,
bool miterStroke,
bool degenerate);
GrDrawBatch* Create(GrColor color,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkStrokeRec& stroke);
bool Append(GrBatch*,
GrColor color,
const SkMatrix& viewMatrix,
const SkRect& devOutside,
const SkRect& devOutsideAssist,
const SkRect& devInside,
bool miterStroke,
bool degenerate);
const SkRect& rect,
const SkStrokeRec& stroke);
};

View File

@ -13,70 +13,6 @@
namespace GrRectBatchFactory {
GrDrawBatch* CreateAAStroke(GrColor color,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkRect& devRect,
const SkStrokeRec& stroke) {
SkVector devStrokeSize;
SkScalar width = stroke.getWidth();
if (width > 0) {
devStrokeSize.set(width, width);
viewMatrix.mapVectors(&devStrokeSize, 1);
devStrokeSize.setAbs(devStrokeSize);
} else {
devStrokeSize.set(SK_Scalar1, SK_Scalar1);
}
const SkScalar dx = devStrokeSize.fX;
const SkScalar dy = devStrokeSize.fY;
const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf);
const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf);
SkRect devOutside(devRect);
devOutside.outset(rx, ry);
bool miterStroke = true;
// For hairlines, make bevel and round joins appear the same as mitered ones.
// small miter limit means right angles show bevel...
if ((width > 0) && (stroke.getJoin() != SkPaint::kMiter_Join ||
stroke.getMiter() < SK_ScalarSqrt2)) {
miterStroke = false;
}
SkRect devInside(devRect);
devInside.inset(rx, ry);
// If we have a degenerate stroking rect(ie the stroke is larger than inner rect) then we
// make a degenerate inside rect to avoid double hitting. We will also jam all of the points
// together when we render these rects.
SkScalar spare;
{
SkScalar w = devRect.width() - dx;
SkScalar h = devRect.height() - dy;
spare = SkTMin(w, h);
}
bool degenerate = spare <= 0;
if (degenerate) {
devInside.fLeft = devInside.fRight = devRect.centerX();
devInside.fTop = devInside.fBottom = devRect.centerY();
}
SkRect devOutsideAssist(devRect);
// For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist)
// to draw the outer of the rect. Because there are 8 vertices on the outer
// edge, while vertex number of inner edge is 4, the same as miter-stroke.
if (!miterStroke) {
devOutside.inset(0, ry);
devOutsideAssist.outset(0, ry);
}
return GrAAStrokeRectBatch::Create(color, viewMatrix, devOutside, devOutsideAssist, devInside,
miterStroke, degenerate);
}
GrDrawBatch* CreateAAFillNestedRects(GrColor color,
const SkMatrix& viewMatrix,
const SkRect rects[2]) {

View File

@ -9,6 +9,7 @@
#define GrRectBatchFactory_DEFINED
#include "GrAAFillRectBatch.h"
#include "GrAAStrokeRectBatch.h"
#include "GrColor.h"
#include "GrNonAAFillRectBatch.h"
#include "GrNonAAStrokeRectBatch.h"
@ -59,11 +60,12 @@ inline GrDrawBatch* CreateNonAAStroke(GrColor color,
return GrNonAAStrokeRectBatch::Create(color, viewMatrix, rect, strokeWidth, snapToPixelCenters);
}
GrDrawBatch* CreateAAStroke(GrColor,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkRect& devRect,
const SkStrokeRec& stroke);
inline GrDrawBatch* CreateAAStroke(GrColor color,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkStrokeRec& stroke) {
return GrAAStrokeRectBatch::Create(color, viewMatrix, rect, stroke);
}
// First rect is outer; second rect is inner
GrDrawBatch* CreateAAFillNestedRects(GrColor,