Index: src/gpu/GrAALinearizingConvexPathRenderer.cpp |
diff --git a/src/gpu/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/GrAALinearizingConvexPathRenderer.cpp |
index 5ded4d4b43de1888bcc16b8653f9919f5099370f..786378ba8410429ad929f6db94093855b4aa391d 100644 |
--- a/src/gpu/GrAALinearizingConvexPathRenderer.cpp |
+++ b/src/gpu/GrAALinearizingConvexPathRenderer.cpp |
@@ -23,11 +23,16 @@ |
#include "SkGeometry.h" |
#include "SkString.h" |
#include "SkTraceEvent.h" |
+#include "SkPathPriv.h" |
#include "gl/GrGLProcessor.h" |
#include "gl/GrGLGeometryProcessor.h" |
#include "gl/builders/GrGLProgramBuilder.h" |
-#define DEFAULT_BUFFER_SIZE 100 |
+static const int DEFAULT_BUFFER_SIZE = 100; |
+ |
+// The thicker the stroke, the harder it is to produce high-quality results using tessellation. For |
+// the time being, we simply drop back to software rendering above this stroke width. |
+static const SkScalar kMaxStrokeWidth = 20.0; |
GrAALinearizingConvexPathRenderer::GrAALinearizingConvexPathRenderer() { |
} |
@@ -40,7 +45,21 @@ |
const SkPath& path, |
const GrStrokeInfo& stroke, |
bool antiAlias) const { |
- return (antiAlias && stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex()); |
+ if (!antiAlias) { |
+ return false; |
+ } |
+ if (path.isInverseFillType()) { |
+ return false; |
+ } |
+ if (!path.isConvex()) { |
+ return false; |
+ } |
+ if (stroke.getStyle() == SkStrokeRec::kStroke_Style) { |
+ return viewMatrix.isSimilarity() && stroke.getWidth() >= 1.0f && |
+ stroke.getWidth() <= kMaxStrokeWidth && !stroke.isDashed() && |
+ SkPathPriv::LastVerbIsClose(path) && stroke.getJoin() != SkPaint::Join::kRound_Join; |
+ } |
+ return stroke.getStyle() == SkStrokeRec::kFill_Style; |
} |
// extract the result vertices and indices from the GrAAConvexTessellator |
@@ -60,16 +79,15 @@ |
// Make 'verts' point to the colors |
verts += sizeof(SkPoint); |
for (int i = 0; i < tess.numPts(); ++i) { |
- SkASSERT(tess.depth(i) >= -0.5f && tess.depth(i) <= 0.5f); |
if (tweakAlphaForCoverage) { |
- SkASSERT(SkScalarRoundToInt(255.0f * (tess.depth(i) + 0.5f)) <= 255); |
- unsigned scale = SkScalarRoundToInt(255.0f * (tess.depth(i) + 0.5f)); |
+ SkASSERT(SkScalarRoundToInt(255.0f * tess.coverage(i)) <= 255); |
+ unsigned scale = SkScalarRoundToInt(255.0f * tess.coverage(i)); |
GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale); |
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; |
} else { |
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
*reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) = |
- tess.depth(i) + 0.5f; |
+ tess.coverage(i); |
} |
} |
@@ -97,6 +115,9 @@ |
GrColor fColor; |
SkMatrix fViewMatrix; |
SkPath fPath; |
+ SkScalar fStrokeWidth; |
+ SkPaint::Join fJoin; |
+ SkScalar fMiterLimit; |
}; |
static GrBatch* Create(const Geometry& geometry) { |
@@ -158,7 +179,7 @@ |
firstIndex, vertexCount, indexCount); |
batchTarget->draw(info); |
} |
- |
+ |
void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { |
bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); |
@@ -181,8 +202,6 @@ |
SkASSERT(canTweakAlphaForCoverage ? |
vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) : |
vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr)); |
- |
- GrAAConvexTessellator tess; |
int instanceCount = fGeoData.count(); |
@@ -193,9 +212,8 @@ |
uint8_t* vertices = (uint8_t*) malloc(maxVertices * vertexStride); |
uint16_t* indices = (uint16_t*) malloc(maxIndices * sizeof(uint16_t)); |
for (int i = 0; i < instanceCount; i++) { |
- tess.rewind(); |
- |
Geometry& args = fGeoData[i]; |
+ GrAAConvexTessellator tess(args.fStrokeWidth, args.fJoin, args.fMiterLimit); |
if (!tess.tessellate(args.fViewMatrix, args.fPath)) { |
continue; |
@@ -287,7 +305,7 @@ |
GrColor color, |
const SkMatrix& vm, |
const SkPath& path, |
- const GrStrokeInfo&, |
+ const GrStrokeInfo& stroke, |
bool antiAlias) { |
if (path.isEmpty()) { |
return true; |
@@ -296,6 +314,9 @@ |
geometry.fColor = color; |
geometry.fViewMatrix = vm; |
geometry.fPath = path; |
+ geometry.fStrokeWidth = stroke.isFillStyle() ? -1.0f : stroke.getWidth(); |
+ geometry.fJoin = stroke.isFillStyle() ? SkPaint::Join::kMiter_Join : stroke.getJoin(); |
+ geometry.fMiterLimit = stroke.getMiter(); |
SkAutoTUnref<GrBatch> batch(AAFlatteningConvexPathBatch::Create(geometry)); |
target->drawBatch(pipelineBuilder, batch); |