aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkDraw.cpp25
-rw-r--r--src/core/SkDrawProcs.h22
-rw-r--r--src/gpu/GrAAHairLinePathRenderer.cpp22
-rw-r--r--src/gpu/GrContext.cpp69
-rw-r--r--src/gpu/GrDefaultPathRenderer.cpp28
-rw-r--r--src/gpu/GrDrawState.cpp7
-rw-r--r--src/gpu/GrDrawState.h10
-rw-r--r--src/gpu/GrDrawTarget.h9
-rw-r--r--src/gpu/GrOvalRenderer.cpp28
-rw-r--r--src/gpu/GrOvalRenderer.h6
-rw-r--r--src/gpu/GrPathRenderer.h15
-rw-r--r--src/gpu/SkGpuDevice.cpp12
-rw-r--r--src/gpu/gl/GrGLProgram.cpp4
-rw-r--r--src/gpu/gl/GrGLProgramDesc.cpp2
14 files changed, 148 insertions, 111 deletions
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 0288dee409..52891ea521 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -988,24 +988,11 @@ static bool xfermodeSupportsCoverageAsAlpha(SkXfermode* xfer) {
}
}
-bool SkDrawTreatAsHairline(const SkPaint& paint, const SkMatrix& matrix,
- SkScalar* coverage) {
- SkASSERT(coverage);
- if (SkPaint::kStroke_Style != paint.getStyle()) {
- return false;
- }
- SkScalar strokeWidth = paint.getStrokeWidth();
- if (0 == strokeWidth) {
- *coverage = SK_Scalar1;
- return true;
- }
+bool SkDrawTreatAAStrokeAsHairline(SkScalar strokeWidth, const SkMatrix& matrix,
+ SkScalar* coverage) {
+ SkASSERT(strokeWidth > 0);
+ // We need to try to fake a thick-stroke with a modulated hairline.
- // if we get here, we need to try to fake a thick-stroke with a modulated
- // hairline
-
- if (!paint.isAntiAlias()) {
- return false;
- }
if (matrix.hasPerspective()) {
return false;
}
@@ -1017,7 +1004,9 @@ bool SkDrawTreatAsHairline(const SkPaint& paint, const SkMatrix& matrix,
SkScalar len0 = fast_len(dst[0]);
SkScalar len1 = fast_len(dst[1]);
if (len0 <= SK_Scalar1 && len1 <= SK_Scalar1) {
- *coverage = SkScalarAve(len0, len1);
+ if (NULL != coverage) {
+ *coverage = SkScalarAve(len0, len1);
+ }
return true;
}
return false;
diff --git a/src/core/SkDrawProcs.h b/src/core/SkDrawProcs.h
index cc2f3ed073..6911e5b017 100644
--- a/src/core/SkDrawProcs.h
+++ b/src/core/SkDrawProcs.h
@@ -75,12 +75,32 @@ struct SkDrawProcs {
#endif
};
+bool SkDrawTreatAAStrokeAsHairline(SkScalar strokeWidth, const SkMatrix&,
+ SkScalar* coverage);
+
/**
* If the current paint is set to stroke and the stroke-width when applied to
* the matrix is <= 1.0, then this returns true, and sets coverage (simulating
* a stroke by drawing a hairline with partial coverage). If any of these
* conditions are false, then this returns false and coverage is ignored.
*/
-bool SkDrawTreatAsHairline(const SkPaint&, const SkMatrix&, SkScalar* coverage);
+inline bool SkDrawTreatAsHairline(const SkPaint& paint, const SkMatrix& matrix,
+ SkScalar* coverage) {
+ if (SkPaint::kStroke_Style != paint.getStyle()) {
+ return false;
+ }
+
+ SkScalar strokeWidth = paint.getStrokeWidth();
+ if (0 == strokeWidth) {
+ *coverage = SK_Scalar1;
+ return true;
+ }
+
+ if (!paint.isAntiAlias()) {
+ return false;
+ }
+
+ return SkDrawTreatAAStrokeAsHairline(strokeWidth, matrix, coverage);
+}
#endif
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index 02c44191ad..39563105f8 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -759,7 +759,7 @@ bool GrAAHairLinePathRenderer::createLineGeom(const SkPath& path,
}
devBounds->set(lines.begin(), lines.count());
for (int i = 0; i < lineCnt; ++i) {
- add_line(&lines[2*i], toSrc, drawState->getCoverage(), &verts);
+ add_line(&lines[2*i], toSrc, drawState->getCoverageColor(), &verts);
}
// All the verts computed by add_line are within sqrt(1^2 + 0.5^2) of the end points.
static const SkScalar kSqrtOfOneAndAQuarter = SkFloatToScalar(1.118f);
@@ -839,7 +839,13 @@ bool GrAAHairLinePathRenderer::canDrawPath(const SkPath& path,
const SkStrokeRec& stroke,
const GrDrawTarget* target,
bool antiAlias) const {
- if (!stroke.isHairlineStyle() || !antiAlias) {
+ if (!antiAlias) {
+ return false;
+ }
+
+ if (!IsStrokeHairlineOrEquivalent(stroke,
+ target->getDrawState().getViewMatrix(),
+ NULL)) {
return false;
}
@@ -888,12 +894,20 @@ bool check_bounds(GrDrawState* drawState, const SkRect& devBounds, void* vertice
}
bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
- const SkStrokeRec&,
+ const SkStrokeRec& stroke,
GrDrawTarget* target,
bool antiAlias) {
-
GrDrawState* drawState = target->drawState();
+ SkScalar hairlineCoverage;
+ if (IsStrokeHairlineOrEquivalent(stroke,
+ target->getDrawState().getViewMatrix(),
+ &hairlineCoverage)) {
+ uint8_t newCoverage = SkScalarRoundToInt(hairlineCoverage *
+ target->getDrawState().getCoverage());
+ target->drawState()->setCoverage(newCoverage);
+ }
+
SkIRect devClipBounds;
target->getClip()->getConservativeBounds(drawState->getRenderTarget(), &devClipBounds);
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index b0d34fd039..cab4414ae2 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -43,10 +43,6 @@ SK_CONF_DECLARE(bool, c_Defer, "gpu.deferContext", true,
#define BUFFERED_DRAW (c_Defer ? kYes_BufferedDraw : kNo_BufferedDraw)
-// When we're using coverage AA but the blend is incompatible (given gpu
-// limitations) should we disable AA or draw wrong?
-#define DISABLE_COVERAGE_AA_FOR_BLEND 1
-
#ifdef SK_DEBUG
// change this to a 1 to see notifications when partial coverage fails
#define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0
@@ -695,14 +691,6 @@ void GrContext::dumpFontCache() const {
////////////////////////////////////////////////////////////////////////////////
-namespace {
-inline bool disable_coverage_aa_for_blend(GrDrawTarget* target) {
- return DISABLE_COVERAGE_AA_FOR_BLEND && !target->canApplyCoverage();
-}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
/* create a triangle strip that strokes the specified triangle. There are 8
unique vertices, but we repreat the last 2 to close up. Alternatively we
could use an indices array, and then only send 8 verts, but not sure that
@@ -746,7 +734,7 @@ static bool apply_aa_to_rect(GrDrawTarget* target,
// TODO: remove this ugliness when we drop the fixed-pipe impl
*useVertexCoverage = false;
if (!target->getDrawState().canTweakAlphaForCoverage()) {
- if (disable_coverage_aa_for_blend(target)) {
+ if (target->shouldDisableCoverageAAForBlend()) {
#ifdef SK_DEBUG
//GrPrintf("Turning off AA to correctly apply blend.\n");
#endif
@@ -1034,14 +1022,10 @@ void GrContext::drawRRect(const GrPaint& paint,
AutoCheckFlush acf(this);
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
- bool useAA = paint.isAntiAlias() &&
- !target->getDrawState().getRenderTarget()->isMultisampled() &&
- !disable_coverage_aa_for_blend(target);
-
- if (!fOvalRenderer->drawSimpleRRect(target, this, useAA, rect, stroke)) {
+ if (!fOvalRenderer->drawSimpleRRect(target, this, paint.isAntiAlias(), rect, stroke)) {
SkPath path;
path.addRRect(rect);
- this->internalDrawPath(target, useAA, path, stroke);
+ this->internalDrawPath(target, paint.isAntiAlias(), path, stroke);
}
}
@@ -1058,14 +1042,10 @@ void GrContext::drawOval(const GrPaint& paint,
AutoCheckFlush acf(this);
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
- bool useAA = paint.isAntiAlias() &&
- !target->getDrawState().getRenderTarget()->isMultisampled() &&
- !disable_coverage_aa_for_blend(target);
-
- if (!fOvalRenderer->drawOval(target, this, useAA, oval, stroke)) {
+ if (!fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), oval, stroke)) {
SkPath path;
path.addOval(oval);
- this->internalDrawPath(target, useAA, path, stroke);
+ this->internalDrawPath(target, paint.isAntiAlias(), path, stroke);
}
}
@@ -1091,7 +1071,7 @@ static bool is_nested_rects(GrDrawTarget* target,
*useVertexCoverage = false;
if (!target->getDrawState().canTweakAlphaForCoverage()) {
- if (disable_coverage_aa_for_blend(target)) {
+ if (target->shouldDisableCoverageAAForBlend()) {
return false;
} else {
*useVertexCoverage = true;
@@ -1141,15 +1121,17 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrok
AutoRestoreEffects are;
AutoCheckFlush acf(this);
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
+ GrDrawState* drawState = target->drawState();
- bool useAA = paint.isAntiAlias() && !target->getDrawState().getRenderTarget()->isMultisampled();
- if (useAA && stroke.getWidth() < 0 && !path.isConvex()) {
+ bool useCoverageAA = paint.isAntiAlias() && !drawState->getRenderTarget()->isMultisampled();
+
+ if (useCoverageAA && stroke.getWidth() < 0 && !path.isConvex()) {
// Concave AA paths are expensive - try to avoid them for special cases
bool useVertexCoverage;
SkRect rects[2];
if (is_nested_rects(target, path, stroke, rects, &useVertexCoverage)) {
- SkMatrix origViewMatrix = target->getDrawState().getViewMatrix();
+ SkMatrix origViewMatrix = drawState->getViewMatrix();
GrDrawState::AutoViewMatrixRestore avmr;
if (!avmr.setIdentity(target->drawState())) {
return;
@@ -1167,8 +1149,8 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrok
bool isOval = path.isOval(&ovalRect);
if (!isOval || path.isInverseFillType()
- || !fOvalRenderer->drawOval(target, this, useAA, ovalRect, stroke)) {
- this->internalDrawPath(target, useAA, path, stroke);
+ || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect, stroke)) {
+ this->internalDrawPath(target, paint.isAntiAlias(), path, stroke);
}
}
@@ -1180,15 +1162,14 @@ void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath&
// the src color (either the input alpha or in the frag shader) to implement
// aa. If we have some future driver-mojo path AA that can do the right
// thing WRT to the blend then we'll need some query on the PR.
- if (disable_coverage_aa_for_blend(target)) {
-#ifdef SK_DEBUG
- //GrPrintf("Turning off AA to correctly apply blend.\n");
-#endif
- useAA = false;
- }
+ bool useCoverageAA = useAA &&
+ !target->getDrawState().getRenderTarget()->isMultisampled() &&
+ !target->shouldDisableCoverageAAForBlend();
+
- GrPathRendererChain::DrawType type = useAA ? GrPathRendererChain::kColorAntiAlias_DrawType :
- GrPathRendererChain::kColor_DrawType;
+ GrPathRendererChain::DrawType type =
+ useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType :
+ GrPathRendererChain::kColor_DrawType;
const SkPath* pathPtr = &path;
SkPath tmpPath;
@@ -1198,16 +1179,16 @@ void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath&
GrPathRenderer* pr = this->getPathRenderer(*pathPtr, strokeRec, target, false, type);
if (NULL == pr) {
- if (!strokeRec.isHairlineStyle()) {
+ if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(strokeRec, this->getMatrix(), NULL)) {
// It didn't work the 1st time, so try again with the stroked path
if (strokeRec.applyToPath(&tmpPath, *pathPtr)) {
pathPtr = &tmpPath;
strokeRec.setFillStyle();
+ if (pathPtr->isEmpty()) {
+ return;
+ }
}
}
- if (pathPtr->isEmpty()) {
- return;
- }
// This time, allow SW renderer
pr = this->getPathRenderer(*pathPtr, strokeRec, target, true, type);
@@ -1220,7 +1201,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath&
return;
}
- pr->drawPath(*pathPtr, strokeRec, target, useAA);
+ pr->drawPath(*pathPtr, strokeRec, target, useCoverageAA);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index 85485c86a3..1f20ac2724 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -12,6 +12,7 @@
#include "GrPathUtils.h"
#include "SkString.h"
#include "SkStrokeRec.h"
+#include "SkTLazy.h"
#include "SkTrace.h"
@@ -325,11 +326,25 @@ FINISHED:
}
bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path,
- const SkStrokeRec& stroke,
+ const SkStrokeRec& origStroke,
GrDrawTarget* target,
bool stencilOnly) {
SkMatrix viewM = target->getDrawState().getViewMatrix();
+ SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke);
+
+ SkScalar hairlineCoverage;
+ if (IsStrokeHairlineOrEquivalent(*stroke, target->getDrawState().getViewMatrix(),
+ &hairlineCoverage)) {
+ uint8_t newCoverage = SkScalarRoundToInt(hairlineCoverage *
+ target->getDrawState().getCoverage());
+ target->drawState()->setCoverage(newCoverage);
+
+ if (!stroke->isHairlineStyle()) {
+ stroke.writable()->setHairlineStyle();
+ }
+ }
+
SkScalar tol = SK_Scalar1;
tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds());
@@ -338,7 +353,7 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path,
GrPrimitiveType primType;
GrDrawTarget::AutoReleaseGeometry arg;
if (!this->createGeom(path,
- stroke,
+ *stroke,
tol,
target,
&primType,
@@ -361,7 +376,7 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path,
bool reverse = false;
bool lastPassIsBounds;
- if (stroke.isHairlineStyle()) {
+ if (stroke->isHairlineStyle()) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;
@@ -371,7 +386,7 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path,
lastPassIsBounds = false;
drawFace[0] = GrDrawState::kBoth_DrawFace;
} else {
- if (single_pass_path(path, stroke)) {
+ if (single_pass_path(path, *stroke)) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;
@@ -499,7 +514,10 @@ bool GrDefaultPathRenderer::canDrawPath(const SkPath& path,
const GrDrawTarget* target,
bool antiAlias) const {
// this class can draw any path with any fill but doesn't do any anti-aliasing.
- return (stroke.isFillStyle() || stroke.isHairlineStyle()) && !antiAlias;
+
+ return !antiAlias &&
+ (stroke.isFillStyle() ||
+ IsStrokeHairlineOrEquivalent(stroke, target->getDrawState().getViewMatrix(), NULL));
}
bool GrDefaultPathRenderer::onDrawPath(const SkPath& path,
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index 1743604a19..1bbcc26325 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -54,7 +54,6 @@ void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende
this->enableState(GrDrawState::kClip_StateBit);
this->setColor(paint.getColor());
- this->setCoverage4(paint.getCoverage());
this->setState(GrDrawState::kDither_StateBit, paint.isDither());
this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
@@ -220,7 +219,7 @@ bool GrDrawState::srcAlphaWillBeOne() const {
// Check whether coverage is treated as color. If so we run through the coverage computation.
if (this->isCoverageDrawing()) {
- GrColor coverageColor = this->getCoverage();
+ GrColor coverageColor = this->getCoverageColor();
GrColor oldColor = color;
color = 0;
for (int c = 0; c < 4; ++c) {
@@ -312,7 +311,7 @@ GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
bool covIsZero = !this->isCoverageDrawing() &&
!this->hasCoverageVertexAttribute() &&
- 0 == this->getCoverage();
+ 0 == this->getCoverageColor();
// When coeffs are (0,1) there is no reason to draw at all, unless
// stenciling is enabled. Having color writes disabled is effectively
// (0,1). The same applies when coverage is known to be 0.
@@ -327,7 +326,7 @@ GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
// check for coverage due to constant coverage, per-vertex coverage, or coverage stage
bool hasCoverage = forceCoverage ||
- 0xffffffff != this->getCoverage() ||
+ 0xffffffff != this->getCoverageColor() ||
this->hasCoverageVertexAttribute() ||
fCoverageStages.count() > 0;
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 2e4d7f86c4..3de0b12e85 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -311,15 +311,11 @@ public:
fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
}
- /**
- * Version of above that specifies 4 channel per-vertex color. The value
- * should be premultiplied.
- */
- void setCoverage4(GrColor coverage) {
- fCommon.fCoverage = coverage;
+ uint8_t getCoverage() const {
+ return GrColorUnpackR(fCommon.fCoverage);
}
- GrColor getCoverage() const {
+ GrColor getCoverageColor() const {
return fCommon.fCoverage;
}
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 266dc0712b..c5058699b5 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -100,6 +100,15 @@ public:
*/
bool canApplyCoverage() const;
+ /** When we're using coverage AA but the blend is incompatible (given gpu
+ * limitations) we should disable AA. */
+ bool shouldDisableCoverageAAForBlend() {
+ // Enable below if we should draw with AA even when it produces
+ // incorrect blending.
+ // return false;
+ return !this->canApplyCoverage();
+ }
+
/**
* Given the current draw state and hw support, will HW AA lines be used (if
* a line primitive type is drawn)?
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
index aeeb85d2e1..8f078dbc45 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -460,7 +460,11 @@ void GrOvalRenderer::reset() {
bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, bool useAA,
const SkRect& oval, const SkStrokeRec& stroke)
{
- if (!useAA) {
+ bool useCoverageAA = useAA &&
+ !target->getDrawState().getRenderTarget()->isMultisampled() &&
+ !target->shouldDisableCoverageAAForBlend();
+
+ if (!useCoverageAA) {
return false;
}
@@ -469,13 +473,13 @@ bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, bo
// we can draw circles
if (SkScalarNearlyEqual(oval.width(), oval.height())
&& circle_stays_circle(vm)) {
- this->drawCircle(target, useAA, oval, stroke);
+ this->drawCircle(target, useCoverageAA, oval, stroke);
// if we have shader derivative support, render as device-independent
} else if (target->caps()->shaderDerivativeSupport()) {
- return this->drawDIEllipse(target, useAA, oval, stroke);
+ return this->drawDIEllipse(target, useCoverageAA, oval, stroke);
// otherwise axis-aligned ellipses only
} else if (vm.rectStaysRect()) {
- return this->drawEllipse(target, useAA, oval, stroke);
+ return this->drawEllipse(target, useCoverageAA, oval, stroke);
} else {
return false;
}
@@ -492,7 +496,7 @@ extern const GrVertexAttrib gCircleVertexAttribs[] = {
};
void GrOvalRenderer::drawCircle(GrDrawTarget* target,
- bool useAA,
+ bool useCoverageAA,
const SkRect& circle,
const SkStrokeRec& stroke)
{
@@ -597,7 +601,7 @@ extern const GrVertexAttrib gDIEllipseVertexAttribs[] = {
};
bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
- bool useAA,
+ bool useCoverageAA,
const SkRect& ellipse,
const SkStrokeRec& stroke)
{
@@ -606,7 +610,7 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
{
// we should have checked for this previously
bool isAxisAlignedEllipse = drawState->getViewMatrix().rectStaysRect();
- SkASSERT(useAA && isAxisAlignedEllipse);
+ SkASSERT(useCoverageAA && isAxisAlignedEllipse);
}
#endif
@@ -729,7 +733,7 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
}
bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
- bool useAA,
+ bool useCoverageAA,
const SkRect& ellipse,
const SkStrokeRec& stroke)
{
@@ -882,8 +886,12 @@ GrIndexBuffer* GrOvalRenderer::rRectIndexBuffer(GrGpu* gpu) {
bool GrOvalRenderer::drawSimpleRRect(GrDrawTarget* target, GrContext* context, bool useAA,
const SkRRect& rrect, const SkStrokeRec& stroke)
{
+ bool useCoverageAA = useAA &&
+ !target->getDrawState().getRenderTarget()->isMultisampled() &&
+ !target->shouldDisableCoverageAAForBlend();
+
// only anti-aliased rrects for now
- if (!useAA) {
+ if (!useCoverageAA) {
return false;
}
@@ -891,7 +899,7 @@ bool GrOvalRenderer::drawSimpleRRect(GrDrawTarget* target, GrContext* context, b
#ifdef SK_DEBUG
{
// we should have checked for this previously
- SkASSERT(useAA && vm.rectStaysRect() && rrect.isSimple());
+ SkASSERT(useCoverageAA && vm.rectStaysRect() && rrect.isSimple());
}
#endif
diff --git a/src/gpu/GrOvalRenderer.h b/src/gpu/GrOvalRenderer.h
index b58abb7989..9653fccd72 100644
--- a/src/gpu/GrOvalRenderer.h
+++ b/src/gpu/GrOvalRenderer.h
@@ -37,13 +37,13 @@ public:
const SkRRect& rrect, const SkStrokeRec& stroke);
private:
- bool drawEllipse(GrDrawTarget* target, bool useAA,
+ bool drawEllipse(GrDrawTarget* target, bool useCoverageAA,
const SkRect& ellipse,
const SkStrokeRec& stroke);
- bool drawDIEllipse(GrDrawTarget* target, bool useAA,
+ bool drawDIEllipse(GrDrawTarget* target, bool useCoverageAA,
const SkRect& ellipse,
const SkStrokeRec& stroke);
- void drawCircle(GrDrawTarget* target, bool useAA,
+ void drawCircle(GrDrawTarget* target, bool useCoverageAA,
const SkRect& circle,
const SkStrokeRec& stroke);
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index f86eb9fe54..88665c1d42 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -13,6 +13,7 @@
#include "GrPathRendererChain.h"
#include "GrStencil.h"
+#include "SkDrawProcs.h"
#include "SkStrokeRec.h"
#include "SkTArray.h"
@@ -137,6 +138,20 @@ public:
this->onStencilPath(path, stroke, target);
}
+ // Helper for determining if we can treat a thin stroke as a hairline w/ coverage.
+ // If we can, we draw lots faster (raster device does this same test).
+ static bool IsStrokeHairlineOrEquivalent(const SkStrokeRec& stroke, const SkMatrix& matrix,
+ SkScalar* outCoverage) {
+ if (stroke.isHairlineStyle()) {
+ if (NULL != outCoverage) {
+ *outCoverage = SK_Scalar1;
+ }
+ return true;
+ }
+ return stroke.getStyle() == SkStrokeRec::kStroke_Style &&
+ SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage);
+ }
+
protected:
/**
* Subclass overrides if it has any limitations of stenciling support.
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 063509a5a4..b83baf7fa3 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -846,14 +846,6 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
return;
}
- // can we cheat, and treat a thin stroke as a hairline w/ coverage
- // if we can, we draw lots faster (raster device does this same test)
- SkScalar hairlineCoverage;
- bool doHairLine = SkDrawTreatAsHairline(paint, fContext->getMatrix(), &hairlineCoverage);
- if (doHairLine) {
- grPaint.setCoverage(SkScalarRoundToInt(hairlineCoverage * grPaint.getCoverage()));
- }
-
// If we have a prematrix, apply it to the path, optimizing for the case
// where the original path can in fact be modified in place (even though
// its parameter type is const).
@@ -883,10 +875,6 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
pathPtr = &effectPath;
}
- if (!pathEffect && doHairLine) {
- stroke.setHairlineStyle();
- }
-
if (paint.getMaskFilter()) {
if (!stroke.isHairlineStyle()) {
if (stroke.applyToPath(&tmpPath, *pathPtr)) {
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index accaf884d1..5b030fa36a 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -207,10 +207,10 @@ void GrGLProgram::setData(GrDrawState::BlendOptFlags blendOpts,
coverage = 0;
} else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) {
color = 0xffffffff;
- coverage = drawState.getCoverage();
+ coverage = drawState.getCoverageColor();
} else {
color = drawState.getColor();
- coverage = drawState.getCoverage();
+ coverage = drawState.getCoverageColor();
}
this->setColor(drawState, color, sharedState);
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
index e655210a45..381461a03b 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -156,7 +156,7 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
header->fHasVertexCode = true;
}
- bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverage();
+ bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverageColor();
if (skipCoverage) {
header->fCoverageInput = kTransBlack_ColorInput;