Add per-vertex coverage field, use in AA rects when alpha tweak is not valid, add relevant sample/gm
Review URL: http://codereview.appspot.com/5181044/
git-svn-id: http://skia.googlecode.com/svn/trunk@2440 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index d9fb9e8..3f5ab54 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -677,6 +677,7 @@
return false;
}
if (disable_coverage_aa_for_blend(target)) {
+ GrPrintf("Turning off AA to correctly apply blend.\n");
return false;
}
return true;
@@ -937,18 +938,6 @@
verts[9] = verts[1];
}
-static GrColor getColorForMesh(const GrPaint& paint) {
- // FIXME: This was copied from SkGpuDevice, seems like
- // we should have already smeared a in caller if that
- // is what is desired.
- if (paint.hasTexture()) {
- unsigned a = GrColorUnpackA(paint.fColor);
- return GrColorPackRGBA(a, a, a, a);
- } else {
- return paint.fColor;
- }
-}
-
static void setInsetFan(GrPoint* pts, size_t stride,
const GrRect& r, GrScalar dx, GrScalar dy) {
pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride);
@@ -1019,11 +1008,26 @@
return fAAStrokeRectIndexBuffer;
}
+static GrVertexLayout aa_rect_layout(const GrDrawTarget* target,
+ bool useCoverage) {
+ GrVertexLayout layout = 0;
+ for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
+ if (NULL != target->getTexture(s)) {
+ layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s);
+ }
+ }
+ if (useCoverage) {
+ layout |= GrDrawTarget::kCoverage_VertexLayoutBit;
+ } else {
+ layout |= GrDrawTarget::kColor_VertexLayoutBit;
+ }
+ return layout;
+}
+
void GrContext::fillAARect(GrDrawTarget* target,
- const GrPaint& paint,
- const GrRect& devRect) {
- GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL) |
- GrDrawTarget::kColor_VertexLayoutBit;
+ const GrRect& devRect,
+ bool useVertexCoverage) {
+ GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage);
size_t vsize = GrDrawTarget::VertexSize(layout);
@@ -1051,7 +1055,13 @@
*reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
}
- GrColor innerColor = getColorForMesh(paint);
+ GrColor innerColor;
+ if (useVertexCoverage) {
+ innerColor = GrColorPackRGBA(0,0,0,0xff);
+ } else {
+ innerColor = target->getColor();
+ }
+
verts += 4 * vsize;
for (int i = 0; i < 4; ++i) {
*reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor;
@@ -1063,16 +1073,15 @@
0, 8, this->aaFillRectIndexCount());
}
-void GrContext::strokeAARect(GrDrawTarget* target, const GrPaint& paint,
- const GrRect& devRect, const GrVec& devStrokeSize) {
+void GrContext::strokeAARect(GrDrawTarget* target,
+ const GrRect& devRect,
+ const GrVec& devStrokeSize,
+ bool useVertexCoverage) {
const GrScalar& dx = devStrokeSize.fX;
const GrScalar& dy = devStrokeSize.fY;
const GrScalar rx = GrMul(dx, GR_ScalarHalf);
const GrScalar ry = GrMul(dy, GR_ScalarHalf);
- GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL) |
- GrDrawTarget::kColor_VertexLayoutBit;
-
GrScalar spare;
{
GrScalar w = devRect.width() - dx;
@@ -1083,10 +1092,10 @@
if (spare <= 0) {
GrRect r(devRect);
r.inset(-rx, -ry);
- fillAARect(target, paint, r);
+ fillAARect(target, r, useVertexCoverage);
return;
}
-
+ GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage);
size_t vsize = GrDrawTarget::VertexSize(layout);
GrDrawTarget::AutoReleaseGeometry geo(target, layout, 16, 0);
@@ -1117,7 +1126,12 @@
*reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
}
- GrColor innerColor = getColorForMesh(paint);
+ GrColor innerColor;
+ if (useVertexCoverage) {
+ innerColor = GrColorPackRGBA(0,0,0,0xff);
+ } else {
+ innerColor = target->getColor();
+ }
verts += 4 * vsize;
for (int i = 0; i < 8; ++i) {
*reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor;
@@ -1146,7 +1160,8 @@
GrScalar width,
const GrMatrix* matrix,
GrMatrix* combinedMatrix,
- GrRect* devRect) {
+ GrRect* devRect,
+ bool* useVertexCoverage) {
// we use a simple alpha ramp to do aa on axis-aligned rects
// do AA with alpha ramp if the caller requested AA, the rect
// will be axis-aligned,the render target is not
@@ -1156,8 +1171,22 @@
return false;
}
+ // we are keeping around the "tweak the alpha" trick because
+ // it is our only hope for the fixed-pipe implementation.
+ // In a shader implementation we can give a separate coverage input
+ *useVertexCoverage = false;
if (!target->canTweakAlphaForCoverage()) {
- return false;
+ if (target->getCaps().fSupportPerVertexCoverage) {
+ if (disable_coverage_aa_for_blend(target)) {
+ GrPrintf("Turning off AA to correctly apply blend.\n");
+ return false;
+ } else {
+ *useVertexCoverage = true;
+ }
+ } else {
+ GrPrintf("Rect AA dropped because no support for coverage.\n");
+ return false;
+ }
}
if (target->getRenderTarget()->isMultisampled()) {
@@ -1204,8 +1233,9 @@
GrRect devRect = rect;
GrMatrix combinedMatrix;
+ bool useVertexCoverage;
bool doAA = apply_aa_to_rect(target, rect, width, matrix,
- &combinedMatrix, &devRect);
+ &combinedMatrix, &devRect, &useVertexCoverage);
if (doAA) {
GrDrawTarget::AutoViewMatrixRestore avm(target);
@@ -1225,9 +1255,9 @@
} else {
strokeSize.set(GR_Scalar1, GR_Scalar1);
}
- strokeAARect(target, paint, devRect, strokeSize);
+ strokeAARect(target, devRect, strokeSize, useVertexCoverage);
} else {
- fillAARect(target, paint, devRect);
+ fillAARect(target, devRect, useVertexCoverage);
}
return;
}
@@ -1406,12 +1436,11 @@
}
int texOffsets[GrDrawTarget::kMaxTexCoords];
int colorOffset;
- int edgeOffset;
GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
texOffsets,
&colorOffset,
- &edgeOffset);
- GrAssert(-1 == edgeOffset);
+ NULL,
+ NULL);
void* curVertex = geo.vertices();
for (int i = 0; i < vertexCount; ++i) {
@@ -1462,6 +1491,7 @@
// 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)) {
+ GrPrintf("Turning off AA to correctly apply blend.\n");
target->disableState(GrDrawTarget::kAntialias_StateBit);
}