Revert "Do not apply hairline optimization for paths if nv_path_rendering is used"
This reverts commit r12185.
Review URL: https://codereview.chromium.org/66813002
git-svn-id: http://skia.googlecode.com/svn/trunk@12187 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index 50d7764..02c4419 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -759,7 +759,7 @@
}
devBounds->set(lines.begin(), lines.count());
for (int i = 0; i < lineCnt; ++i) {
- add_line(&lines[2*i], toSrc, drawState->getCoverageColor(), &verts);
+ add_line(&lines[2*i], toSrc, drawState->getCoverage(), &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);
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 5eee243..b0d34fd 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -25,7 +25,6 @@
#include "GrSoftwarePathRenderer.h"
#include "GrStencilBuffer.h"
#include "GrTextStrike.h"
-#include "SkDrawProcs.h"
#include "SkRTConf.h"
#include "SkRRect.h"
#include "SkStrokeRec.h"
@@ -44,6 +43,10 @@
#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
@@ -692,6 +695,14 @@
////////////////////////////////////////////////////////////////////////////////
+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
@@ -735,7 +746,7 @@
// TODO: remove this ugliness when we drop the fixed-pipe impl
*useVertexCoverage = false;
if (!target->getDrawState().canTweakAlphaForCoverage()) {
- if (target->shouldDisableCoverageAAForBlend()) {
+ if (disable_coverage_aa_for_blend(target)) {
#ifdef SK_DEBUG
//GrPrintf("Turning off AA to correctly apply blend.\n");
#endif
@@ -1023,10 +1034,14 @@
AutoCheckFlush acf(this);
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
- if (!fOvalRenderer->drawSimpleRRect(target, this, paint.isAntiAlias(), rect, stroke)) {
+ bool useAA = paint.isAntiAlias() &&
+ !target->getDrawState().getRenderTarget()->isMultisampled() &&
+ !disable_coverage_aa_for_blend(target);
+
+ if (!fOvalRenderer->drawSimpleRRect(target, this, useAA, rect, stroke)) {
SkPath path;
path.addRRect(rect);
- this->internalDrawPath(target, paint.isAntiAlias(), path, stroke);
+ this->internalDrawPath(target, useAA, path, stroke);
}
}
@@ -1043,10 +1058,14 @@
AutoCheckFlush acf(this);
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
- if (!fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), oval, stroke)) {
+ bool useAA = paint.isAntiAlias() &&
+ !target->getDrawState().getRenderTarget()->isMultisampled() &&
+ !disable_coverage_aa_for_blend(target);
+
+ if (!fOvalRenderer->drawOval(target, this, useAA, oval, stroke)) {
SkPath path;
path.addOval(oval);
- this->internalDrawPath(target, paint.isAntiAlias(), path, stroke);
+ this->internalDrawPath(target, useAA, path, stroke);
}
}
@@ -1072,7 +1091,7 @@
*useVertexCoverage = false;
if (!target->getDrawState().canTweakAlphaForCoverage()) {
- if (target->shouldDisableCoverageAAForBlend()) {
+ if (disable_coverage_aa_for_blend(target)) {
return false;
} else {
*useVertexCoverage = true;
@@ -1122,17 +1141,15 @@
AutoRestoreEffects are;
AutoCheckFlush acf(this);
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
- GrDrawState* drawState = target->drawState();
- bool useCoverageAA = paint.isAntiAlias() && !drawState->getRenderTarget()->isMultisampled();
-
- if (useCoverageAA && stroke.getWidth() < 0 && !path.isConvex()) {
+ bool useAA = paint.isAntiAlias() && !target->getDrawState().getRenderTarget()->isMultisampled();
+ if (useAA && 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 = drawState->getViewMatrix();
+ SkMatrix origViewMatrix = target->getDrawState().getViewMatrix();
GrDrawState::AutoViewMatrixRestore avmr;
if (!avmr.setIdentity(target->drawState())) {
return;
@@ -1150,73 +1167,42 @@
bool isOval = path.isOval(&ovalRect);
if (!isOval || path.isInverseFillType()
- || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect, stroke)) {
- this->internalDrawPath(target, paint.isAntiAlias(), path, stroke);
+ || !fOvalRenderer->drawOval(target, this, useAA, ovalRect, stroke)) {
+ this->internalDrawPath(target, useAA, path, stroke);
}
}
-namespace {
-// See also: SkDrawTreatAsHairline.
-static inline bool should_convert_to_hairline(bool useAA, const SkStrokeRec& stroke,
- const SkMatrix& matrix, SkScalar* coverage) {
-
- if (stroke.getStyle() != SkStrokeRec::kStroke_Style) {
- return false;
- }
-
- SkASSERT(0 != stroke.getWidth());
-
- if (!useAA) {
- return false;
- }
-
- return SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, coverage);
-}
-}
-
-
-void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA,
- const SkPath& path, const SkStrokeRec& origStroke) {
+void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path,
+ const SkStrokeRec& stroke) {
SkASSERT(!path.isEmpty());
// An Assumption here is that path renderer would use some form of tweaking
// 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.
- bool useCoverageAA = useAA &&
- !target->getDrawState().getRenderTarget()->isMultisampled() &&
- !target->shouldDisableCoverageAAForBlend();
-
- SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke);
- // Can we treat a thin stroke as a hairline w/ coverage? If we can, we draw lots faster (raster
- // device does this same test).
-
- // Do not do this if gpu supports path rendering natively and we might be using the support
- // (useCoverageAA == false). Hairline renderer is likely to be slow due to program switches.
- if (!useCoverageAA || !fGpu->caps()->pathRenderingSupport()) {
- SkScalar hairlineCoverage;
- if (should_convert_to_hairline(useAA, *stroke, this->getMatrix(), &hairlineCoverage)) {
- target->drawState()->setCoverage(SkScalarRoundToInt(hairlineCoverage * target->getDrawState().getCoverage()));
- stroke.writable()->setHairlineStyle();
- }
+ if (disable_coverage_aa_for_blend(target)) {
+#ifdef SK_DEBUG
+ //GrPrintf("Turning off AA to correctly apply blend.\n");
+#endif
+ useAA = false;
}
- GrPathRendererChain::DrawType type =
- useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType :
- GrPathRendererChain::kColor_DrawType;
+ GrPathRendererChain::DrawType type = useAA ? GrPathRendererChain::kColorAntiAlias_DrawType :
+ GrPathRendererChain::kColor_DrawType;
const SkPath* pathPtr = &path;
SkPath tmpPath;
+ SkStrokeRec strokeRec(stroke);
// Try a 1st time without stroking the path and without allowing the SW renderer
- GrPathRenderer* pr = this->getPathRenderer(*pathPtr, *stroke, target, false, type);
+ GrPathRenderer* pr = this->getPathRenderer(*pathPtr, strokeRec, target, false, type);
if (NULL == pr) {
- if (!stroke->isHairlineStyle()) {
+ if (!strokeRec.isHairlineStyle()) {
// It didn't work the 1st time, so try again with the stroked path
- if (stroke->applyToPath(&tmpPath, *pathPtr)) {
+ if (strokeRec.applyToPath(&tmpPath, *pathPtr)) {
pathPtr = &tmpPath;
- stroke.writable()->setFillStyle();
+ strokeRec.setFillStyle();
}
}
if (pathPtr->isEmpty()) {
@@ -1224,7 +1210,7 @@
}
// This time, allow SW renderer
- pr = this->getPathRenderer(*pathPtr, *stroke, target, true, type);
+ pr = this->getPathRenderer(*pathPtr, strokeRec, target, true, type);
}
if (NULL == pr) {
@@ -1234,7 +1220,7 @@
return;
}
- pr->drawPath(*pathPtr, *stroke, target, useCoverageAA);
+ pr->drawPath(*pathPtr, strokeRec, target, useAA);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index 1bbcc26..1743604 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -54,6 +54,7 @@
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());
@@ -219,7 +220,7 @@
// Check whether coverage is treated as color. If so we run through the coverage computation.
if (this->isCoverageDrawing()) {
- GrColor coverageColor = this->getCoverageColor();
+ GrColor coverageColor = this->getCoverage();
GrColor oldColor = color;
color = 0;
for (int c = 0; c < 4; ++c) {
@@ -311,7 +312,7 @@
bool covIsZero = !this->isCoverageDrawing() &&
!this->hasCoverageVertexAttribute() &&
- 0 == this->getCoverageColor();
+ 0 == this->getCoverage();
// 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.
@@ -326,7 +327,7 @@
// check for coverage due to constant coverage, per-vertex coverage, or coverage stage
bool hasCoverage = forceCoverage ||
- 0xffffffff != this->getCoverageColor() ||
+ 0xffffffff != this->getCoverage() ||
this->hasCoverageVertexAttribute() ||
fCoverageStages.count() > 0;
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 3de0b12..2e4d7f8 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -311,11 +311,15 @@
fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
}
- uint8_t getCoverage() const {
- return GrColorUnpackR(fCommon.fCoverage);
+ /**
+ * Version of above that specifies 4 channel per-vertex color. The value
+ * should be premultiplied.
+ */
+ void setCoverage4(GrColor coverage) {
+ fCommon.fCoverage = coverage;
}
- GrColor getCoverageColor() const {
+ GrColor getCoverage() const {
return fCommon.fCoverage;
}
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index c505869..266dc07 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -100,15 +100,6 @@
*/
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 8f078db..aeeb85d 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -460,11 +460,7 @@
bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, bool useAA,
const SkRect& oval, const SkStrokeRec& stroke)
{
- bool useCoverageAA = useAA &&
- !target->getDrawState().getRenderTarget()->isMultisampled() &&
- !target->shouldDisableCoverageAAForBlend();
-
- if (!useCoverageAA) {
+ if (!useAA) {
return false;
}
@@ -473,13 +469,13 @@
// we can draw circles
if (SkScalarNearlyEqual(oval.width(), oval.height())
&& circle_stays_circle(vm)) {
- this->drawCircle(target, useCoverageAA, oval, stroke);
+ this->drawCircle(target, useAA, oval, stroke);
// if we have shader derivative support, render as device-independent
} else if (target->caps()->shaderDerivativeSupport()) {
- return this->drawDIEllipse(target, useCoverageAA, oval, stroke);
+ return this->drawDIEllipse(target, useAA, oval, stroke);
// otherwise axis-aligned ellipses only
} else if (vm.rectStaysRect()) {
- return this->drawEllipse(target, useCoverageAA, oval, stroke);
+ return this->drawEllipse(target, useAA, oval, stroke);
} else {
return false;
}
@@ -496,7 +492,7 @@
};
void GrOvalRenderer::drawCircle(GrDrawTarget* target,
- bool useCoverageAA,
+ bool useAA,
const SkRect& circle,
const SkStrokeRec& stroke)
{
@@ -601,7 +597,7 @@
};
bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
- bool useCoverageAA,
+ bool useAA,
const SkRect& ellipse,
const SkStrokeRec& stroke)
{
@@ -610,7 +606,7 @@
{
// we should have checked for this previously
bool isAxisAlignedEllipse = drawState->getViewMatrix().rectStaysRect();
- SkASSERT(useCoverageAA && isAxisAlignedEllipse);
+ SkASSERT(useAA && isAxisAlignedEllipse);
}
#endif
@@ -733,7 +729,7 @@
}
bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
- bool useCoverageAA,
+ bool useAA,
const SkRect& ellipse,
const SkStrokeRec& stroke)
{
@@ -886,12 +882,8 @@
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 (!useCoverageAA) {
+ if (!useAA) {
return false;
}
@@ -899,7 +891,7 @@
#ifdef SK_DEBUG
{
// we should have checked for this previously
- SkASSERT(useCoverageAA && vm.rectStaysRect() && rrect.isSimple());
+ SkASSERT(useAA && vm.rectStaysRect() && rrect.isSimple());
}
#endif
diff --git a/src/gpu/GrOvalRenderer.h b/src/gpu/GrOvalRenderer.h
index 9653fcc..b58abb7 100644
--- a/src/gpu/GrOvalRenderer.h
+++ b/src/gpu/GrOvalRenderer.h
@@ -37,13 +37,13 @@
const SkRRect& rrect, const SkStrokeRec& stroke);
private:
- bool drawEllipse(GrDrawTarget* target, bool useCoverageAA,
+ bool drawEllipse(GrDrawTarget* target, bool useAA,
const SkRect& ellipse,
const SkStrokeRec& stroke);
- bool drawDIEllipse(GrDrawTarget* target, bool useCoverageAA,
+ bool drawDIEllipse(GrDrawTarget* target, bool useAA,
const SkRect& ellipse,
const SkStrokeRec& stroke);
- void drawCircle(GrDrawTarget* target, bool useCoverageAA,
+ void drawCircle(GrDrawTarget* target, bool useAA,
const SkRect& circle,
const SkStrokeRec& stroke);
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 52dc5a7..ca86b84 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -12,8 +12,7 @@
#include "GrContext.h"
#include "GrBitmapTextContext.h"
-#include "GrGpu.h"
-#include "GrDrawTargetCaps.h"
+
#include "SkGrTexturePixelRef.h"
#include "SkColorFilter.h"
@@ -851,6 +850,14 @@
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).
@@ -880,6 +887,10 @@
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 5b030fa..accaf88 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -207,10 +207,10 @@
coverage = 0;
} else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) {
color = 0xffffffff;
- coverage = drawState.getCoverageColor();
+ coverage = drawState.getCoverage();
} else {
color = drawState.getColor();
- coverage = drawState.getCoverageColor();
+ coverage = drawState.getCoverage();
}
this->setColor(drawState, color, sharedState);
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
index 6e9d8a4..d958742 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -156,7 +156,7 @@
header->fHasVertexCode = true;
}
- bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverageColor();
+ bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverage();
if (skipCoverage) {
header->fCoverageInput = kTransBlack_ColorInput;