aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/batches
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2016-05-10 05:57:27 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-05-10 05:57:27 -0700
commit33595bdf4b64a745f6340338d307e806e96c587f (patch)
treee6a4e7abd27df7aa3fdc764d67ec9e3b4cf86868 /src/gpu/batches
parent82595b6fa4733e1525f357bdcac22db058790550 (diff)
Replace GrStrokeInfo with GrStyle.
A side effect is that arbitrary path effects can no be pushed deeper into the Ganesh flow for paths. They may be applied by path renderers. GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1957363002 Review-Url: https://codereview.chromium.org/1957363002
Diffstat (limited to 'src/gpu/batches')
-rw-r--r--src/gpu/batches/GrAAConvexPathRenderer.cpp3
-rw-r--r--src/gpu/batches/GrAADistanceFieldPathRenderer.cpp33
-rw-r--r--src/gpu/batches/GrAAHairLinePathRenderer.cpp16
-rw-r--r--src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp26
-rw-r--r--src/gpu/batches/GrDashLinePathRenderer.cpp6
-rw-r--r--src/gpu/batches/GrDefaultPathRenderer.cpp34
-rw-r--r--src/gpu/batches/GrDefaultPathRenderer.h2
-rw-r--r--src/gpu/batches/GrMSAAPathRenderer.cpp43
-rw-r--r--src/gpu/batches/GrMSAAPathRenderer.h1
-rw-r--r--src/gpu/batches/GrPLSPathRenderer.cpp4
-rw-r--r--src/gpu/batches/GrStencilAndCoverPathRenderer.cpp20
-rw-r--r--src/gpu/batches/GrTessellatingPathRenderer.cpp98
12 files changed, 154 insertions, 132 deletions
diff --git a/src/gpu/batches/GrAAConvexPathRenderer.cpp b/src/gpu/batches/GrAAConvexPathRenderer.cpp
index 8c55de7e79..f557c9b9e9 100644
--- a/src/gpu/batches/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAAConvexPathRenderer.cpp
@@ -18,7 +18,6 @@
#include "GrPathUtils.h"
#include "GrProcessor.h"
#include "GrPipelineBuilder.h"
-#include "GrStrokeInfo.h"
#include "SkGeometry.h"
#include "SkPathPriv.h"
#include "SkString.h"
@@ -682,7 +681,7 @@ const GrGeometryProcessor* QuadEdgeEffect::TestCreate(GrProcessorTestData* d) {
bool GrAAConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
return (args.fShaderCaps->shaderDerivativeSupport() && args.fAntiAlias &&
- args.fStroke->isFillStyle() && !args.fPath->isInverseFillType() &&
+ args.fStyle->isSimpleFill() && !args.fPath->isInverseFillType() &&
args.fPath->isConvex());
}
diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
index f891b8d1f5..ba52bf9213 100644
--- a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
@@ -81,13 +81,14 @@ GrAADistanceFieldPathRenderer::~GrAADistanceFieldPathRenderer() {
////////////////////////////////////////////////////////////////////////////////
bool GrAADistanceFieldPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
-
+ // We don't currently apply the dash or factor it into the DF key. (skbug.com/5082)
+ if (args.fStyle->pathEffect()) {
+ return false;
+ }
// TODO: Support inverse fill
if (!args.fShaderCaps->shaderDerivativeSupport() || !args.fAntiAlias ||
- SkStrokeRec::kHairline_Style == args.fStroke->getStyle() ||
- args.fPath->isInverseFillType() || args.fPath->isVolatile() ||
- // We don't currently apply the dash or factor it into the DF key. (skbug.com/5082)
- args.fStroke->isDashed()) {
+ args.fStyle->isSimpleHairline() || args.fPath->isInverseFillType() ||
+ args.fPath->isVolatile()) {
return false;
}
@@ -100,16 +101,23 @@ bool GrAADistanceFieldPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) c
// scaled to have bounds within 2.0f*kLargeMIP by 2.0f*kLargeMIP
// the goal is to accelerate rendering of lots of small paths that may be scaling
SkScalar maxScale = args.fViewMatrix->getMaxScale();
+#if 0 // This is more accurate but changes some GMs. TODO: Standalone change to enable this.
+ SkRect bounds;
+ args.fStyle->adjustBounds(&bounds, args.fPath->getBounds());
+ SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
+#else
const SkRect& bounds = args.fPath->getBounds();
SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
+ const SkStrokeRec& stroke = args.fStyle->strokeRec();
// Approximate stroked size by adding the maximum of the stroke width or 2x the miter limit
- if (!args.fStroke->isFillStyle()) {
- SkScalar extraWidth = args.fStroke->getWidth();
- if (SkPaint::kMiter_Join == args.fStroke->getJoin()) {
- extraWidth = SkTMax(extraWidth, 2.0f*args.fStroke->getMiter());
+ if (!stroke.isFillStyle()) {
+ SkScalar extraWidth = stroke.getWidth();
+ if (SkPaint::kMiter_Join == stroke.getJoin()) {
+ extraWidth = SkTMax(extraWidth, 2.0f*stroke.getMiter());
}
maxDim += extraWidth;
}
+#endif
return maxDim <= kMediumMIP && maxDim * maxScale <= 2.0f*kLargeMIP;
}
@@ -552,11 +560,12 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(const DrawPathArgs& args) {
}
}
- AADistanceFieldPathBatch::Geometry geometry(*args.fStroke);
- if (SkStrokeRec::kFill_Style == args.fStroke->getStyle()) {
+ // It's ok to ignore style's path effect because canDrawPath filtered out path effects.
+ AADistanceFieldPathBatch::Geometry geometry(args.fStyle->strokeRec());
+ if (args.fStyle->isSimpleFill()) {
geometry.fPath = *args.fPath;
} else {
- args.fStroke->applyToPath(&geometry.fPath, *args.fPath);
+ args.fStyle->strokeRec().applyToPath(&geometry.fPath, *args.fPath);
}
geometry.fColor = args.fColor;
geometry.fAntiAlias = args.fAntiAlias;
diff --git a/src/gpu/batches/GrAAHairLinePathRenderer.cpp b/src/gpu/batches/GrAAHairLinePathRenderer.cpp
index effd8c3b0f..db4bbdfdb3 100644
--- a/src/gpu/batches/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/batches/GrAAHairLinePathRenderer.cpp
@@ -618,7 +618,12 @@ bool GrAAHairLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const
return false;
}
- if (!IsStrokeHairlineOrEquivalent(*args.fStroke, *args.fViewMatrix, nullptr)) {
+ if (!IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullptr)) {
+ return false;
+ }
+
+ // We don't currently handle dashing in this class though perhaps we should.
+ if (args.fStyle->pathEffect()) {
return false;
}
@@ -939,11 +944,11 @@ void AAHairlineBatch::onPrepareDraws(Target* target) const {
static GrDrawBatch* create_hairline_batch(GrColor color,
const SkMatrix& viewMatrix,
const SkPath& path,
- const GrStrokeInfo& stroke,
+ const GrStyle& style,
const SkIRect& devClipBounds) {
SkScalar hairlineCoverage;
uint8_t newCoverage = 0xff;
- if (GrPathRenderer::IsStrokeHairlineOrEquivalent(stroke, viewMatrix, &hairlineCoverage)) {
+ if (GrPathRenderer::IsStrokeHairlineOrEquivalent(style, viewMatrix, &hairlineCoverage)) {
newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff);
}
@@ -964,7 +969,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
args.fPipelineBuilder->clip().getConservativeBounds(rt->width(), rt->height(), &devClipBounds);
SkAutoTUnref<GrDrawBatch> batch(create_hairline_batch(args.fColor, *args.fViewMatrix, *args.fPath,
- *args.fStroke, devClipBounds));
+ *args.fStyle, devClipBounds));
args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
return true;
@@ -977,11 +982,10 @@ bool GrAAHairLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
DRAW_BATCH_TEST_DEFINE(AAHairlineBatch) {
GrColor color = GrRandomColor(random);
SkMatrix viewMatrix = GrTest::TestMatrix(random);
- GrStrokeInfo stroke(SkStrokeRec::kHairline_InitStyle);
SkPath path = GrTest::TestPath(random);
SkIRect devClipBounds;
devClipBounds.setEmpty();
- return create_hairline_batch(color, viewMatrix, path, stroke, devClipBounds);
+ return create_hairline_batch(color, viewMatrix, path, GrStyle::SimpleHairline(), devClipBounds);
}
#endif
diff --git a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
index 446f67f1c0..91d3338c32 100644
--- a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
@@ -17,7 +17,7 @@
#include "GrPathUtils.h"
#include "GrProcessor.h"
#include "GrPipelineBuilder.h"
-#include "GrStrokeInfo.h"
+#include "GrStyle.h"
#include "SkGeometry.h"
#include "SkString.h"
#include "SkTraceEvent.h"
@@ -46,16 +46,20 @@ bool GrAALinearizingConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& arg
if (!args.fPath->isConvex()) {
return false;
}
- if (args.fStroke->getStyle() == SkStrokeRec::kStroke_Style) {
+ if (args.fStyle->pathEffect()) {
+ return false;
+ }
+ const SkStrokeRec& stroke = args.fStyle->strokeRec();
+ if (stroke.getStyle() == SkStrokeRec::kStroke_Style) {
if (!args.fViewMatrix->isSimilarity()) {
return false;
}
- SkScalar strokeWidth = args.fViewMatrix->getMaxScale() * args.fStroke->getWidth();
- return strokeWidth >= 1.0f && strokeWidth <= kMaxStrokeWidth && !args.fStroke->isDashed() &&
- SkPathPriv::IsClosedSingleContour(*args.fPath) &&
- args.fStroke->getJoin() != SkPaint::Join::kRound_Join;
+ SkScalar strokeWidth = args.fViewMatrix->getMaxScale() * stroke.getWidth();
+ return strokeWidth >= 1.0f && strokeWidth <= kMaxStrokeWidth &&
+ SkPathPriv::IsClosedSingleContour(*args.fPath) &&
+ stroke.getJoin() != SkPaint::Join::kRound_Join;
}
- return args.fStroke->getStyle() == SkStrokeRec::kFill_Style;
+ return stroke.getStyle() == SkStrokeRec::kFill_Style;
}
// extract the result vertices and indices from the GrAAConvexTessellator
@@ -325,10 +329,10 @@ bool GrAALinearizingConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
geometry.fColor = args.fColor;
geometry.fViewMatrix = *args.fViewMatrix;
geometry.fPath = *args.fPath;
- geometry.fStrokeWidth = args.fStroke->isFillStyle() ? -1.0f : args.fStroke->getWidth();
- geometry.fJoin = args.fStroke->isFillStyle() ? SkPaint::Join::kMiter_Join :
- args.fStroke->getJoin();
- geometry.fMiterLimit = args.fStroke->getMiter();
+ bool fill = args.fStyle->isSimpleFill();
+ geometry.fStrokeWidth = fill ? -1.0f : args.fStyle->strokeRec().getWidth();
+ geometry.fJoin = fill ? SkPaint::Join::kMiter_Join : args.fStyle->strokeRec().getJoin();
+ geometry.fMiterLimit = args.fStyle->strokeRec().getMiter();
SkAutoTUnref<GrDrawBatch> batch(AAFlatteningConvexPathBatch::Create(geometry));
args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
diff --git a/src/gpu/batches/GrDashLinePathRenderer.cpp b/src/gpu/batches/GrDashLinePathRenderer.cpp
index 9ee27c78dd..8cb8046af4 100644
--- a/src/gpu/batches/GrDashLinePathRenderer.cpp
+++ b/src/gpu/batches/GrDashLinePathRenderer.cpp
@@ -12,8 +12,8 @@
bool GrDashLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
SkPoint pts[2];
- if (args.fStroke->isDashed() && args.fPath->isLine(pts)) {
- return GrDashingEffect::CanDrawDashLine(pts, *args.fStroke, *args.fViewMatrix);
+ if (args.fStyle->isDashed() && args.fPath->isLine(pts)) {
+ return GrDashingEffect::CanDrawDashLine(pts, *args.fStyle, *args.fViewMatrix);
}
return false;
}
@@ -28,7 +28,7 @@ bool GrDashLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
pts,
args.fAntiAlias,
msaaIsEnabled,
- *args.fStroke));
+ *args.fStyle));
if (!batch) {
return false;
}
diff --git a/src/gpu/batches/GrDefaultPathRenderer.cpp b/src/gpu/batches/GrDefaultPathRenderer.cpp
index 1de0bf771e..9994b26a1a 100644
--- a/src/gpu/batches/GrDefaultPathRenderer.cpp
+++ b/src/gpu/batches/GrDefaultPathRenderer.cpp
@@ -422,22 +422,21 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
GrColor color,
const SkMatrix& viewMatrix,
const SkPath& path,
- const GrStrokeInfo& origStroke,
+ const GrStyle& origStyle,
bool stencilOnly) {
- SkTCopyOnFirstWrite<GrStrokeInfo> stroke(origStroke);
+ const GrStyle* style = &origStyle;
SkScalar hairlineCoverage;
uint8_t newCoverage = 0xff;
- if (IsStrokeHairlineOrEquivalent(*stroke, viewMatrix, &hairlineCoverage)) {
+ bool isHairline = false;
+ if (IsStrokeHairlineOrEquivalent(*style, viewMatrix, &hairlineCoverage)) {
newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff);
-
- if (!stroke->isHairlineStyle()) {
- stroke.writable()->setHairlineStyle();
- }
+ style = &GrStyle::SimpleHairline();
+ isHairline = true;
+ } else {
+ SkASSERT(style->isSimpleFill());
}
- const bool isHairline = stroke->isHairlineStyle();
-
// Save the current xp on the draw state so we can reset it if needed
const GrXPFactory* xpFactory = pipelineBuilder->getXPFactory();
SkAutoTUnref<const GrXPFactory> backupXPFactory(SkSafeRef(xpFactory));
@@ -460,7 +459,7 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
lastPassIsBounds = false;
drawFace[0] = GrPipelineBuilder::kBoth_DrawFace;
} else {
- if (single_pass_path(path, *stroke)) {
+ if (single_pass_path(path, style->strokeRec())) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;
@@ -596,10 +595,11 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
}
bool GrDefaultPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
- // this class can draw any path with any fill but doesn't do any anti-aliasing.
- return !args.fAntiAlias && (args.fStroke->isFillStyle() ||
- IsStrokeHairlineOrEquivalent(*args.fStroke, *args.fViewMatrix,
- nullptr));
+ // this class can draw any path with any simple fill style but doesn't do any anti-aliasing.
+ return !args.fAntiAlias &&
+ (args.fStyle->isSimpleFill() || IsStrokeHairlineOrEquivalent(*args.fStyle,
+ *args.fViewMatrix,
+ nullptr));
}
bool GrDefaultPathRenderer::onDrawPath(const DrawPathArgs& args) {
@@ -609,7 +609,7 @@ bool GrDefaultPathRenderer::onDrawPath(const DrawPathArgs& args) {
args.fColor,
*args.fViewMatrix,
*args.fPath,
- *args.fStroke,
+ *args.fStyle,
false);
}
@@ -618,7 +618,7 @@ void GrDefaultPathRenderer::onStencilPath(const StencilPathArgs& args) {
SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType());
SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType());
this->internalDrawPath(args.fTarget, args.fPipelineBuilder, GrColor_WHITE, *args.fViewMatrix,
- *args.fPath, GrStrokeInfo::FillInfo(), true);
+ *args.fPath, GrStyle::SimpleFill(), true);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -631,7 +631,7 @@ DRAW_BATCH_TEST_DEFINE(DefaultPathBatch) {
// For now just hairlines because the other types of draws require two batches.
// TODO we should figure out a way to combine the stencil and cover steps into one batch
- GrStrokeInfo stroke(SkStrokeRec::kHairline_InitStyle);
+ GrStyle style(SkStrokeRec::kHairline_InitStyle);
SkPath path = GrTest::TestPath(random);
// Compute srcSpaceTol
diff --git a/src/gpu/batches/GrDefaultPathRenderer.h b/src/gpu/batches/GrDefaultPathRenderer.h
index 8156462a51..8a74d3a011 100644
--- a/src/gpu/batches/GrDefaultPathRenderer.h
+++ b/src/gpu/batches/GrDefaultPathRenderer.h
@@ -35,7 +35,7 @@ private:
GrColor,
const SkMatrix& viewMatrix,
const SkPath&,
- const GrStrokeInfo&,
+ const GrStyle&,
bool stencilOnly);
bool fSeparateStencil;
diff --git a/src/gpu/batches/GrMSAAPathRenderer.cpp b/src/gpu/batches/GrMSAAPathRenderer.cpp
index a9ba06c5f4..a382c42054 100644
--- a/src/gpu/batches/GrMSAAPathRenderer.cpp
+++ b/src/gpu/batches/GrMSAAPathRenderer.cpp
@@ -29,7 +29,7 @@ static const float kTolerance = 0.5f;
////////////////////////////////////////////////////////////////////////////////
// Helpers for drawPath
-static inline bool single_pass_path(const SkPath& path, const SkStrokeRec& stroke) {
+static inline bool single_pass_path(const SkPath& path) {
if (!path.isInverseFillType()) {
return path.isConvex();
}
@@ -38,7 +38,7 @@ static inline bool single_pass_path(const SkPath& path, const SkStrokeRec& strok
GrPathRenderer::StencilSupport
GrMSAAPathRenderer::onGetStencilSupport(const SkPath& path) const {
- if (single_pass_path(path, SkStrokeRec(SkStrokeRec::kFill_InitStyle))) {
+ if (single_pass_path(path)) {
return GrPathRenderer::kNoRestriction_StencilSupport;
} else {
return GrPathRenderer::kStencilOnly_StencilSupport;
@@ -571,9 +571,7 @@ bool GrMSAAPathRenderer::internalDrawPath(GrDrawTarget* target,
GrColor color,
const SkMatrix& viewMatrix,
const SkPath& path,
- const GrStrokeInfo& origStroke,
bool stencilOnly) {
- SkTCopyOnFirstWrite<GrStrokeInfo> stroke(origStroke);
const GrXPFactory* xpFactory = pipelineBuilder->getXPFactory();
SkAutoTUnref<const GrXPFactory> backupXPFactory(SkSafeRef(xpFactory));
@@ -586,7 +584,7 @@ bool GrMSAAPathRenderer::internalDrawPath(GrDrawTarget* target,
bool reverse = false;
bool lastPassIsBounds;
- if (single_pass_path(path, *stroke)) {
+ if (single_pass_path(path)) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;
@@ -703,34 +701,35 @@ bool GrMSAAPathRenderer::internalDrawPath(GrDrawTarget* target,
}
bool GrMSAAPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
- return !IsStrokeHairlineOrEquivalent(*args.fStroke, *args.fViewMatrix, nullptr) &&
- !args.fAntiAlias;
+ // This path renderer does not support hairlines. We defer on anything that could be handled
+ // as a hairline by another path renderer. Also, arbitrary path effects could produce
+ // a hairline result.
+ return !IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullptr) &&
+ !args.fStyle->hasNonDashPathEffect() && !args.fAntiAlias;
}
bool GrMSAAPathRenderer::onDrawPath(const DrawPathArgs& args) {
GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrMSAAPathRenderer::onDrawPath");
- SkPath path;
- GrStrokeInfo stroke(*args.fStroke);
- if (stroke.isDashed()) {
- if (!stroke.applyDashToPath(&path, &stroke, *args.fPath)) {
+ SkPath tmpPath;
+ const SkPath* path;
+ if (args.fStyle->applies()) {
+ SkStrokeRec::InitStyle fill;
+ SkScalar styleScale = GrStyle::MatrixToScaleFactor(*args.fViewMatrix);
+ if (!args.fStyle->applyToPath(&tmpPath, &fill, *args.fPath, styleScale)) {
return false;
}
+ // We don't accept styles that are hairlines or have path effects that could produce
+ // hairlines.
+ SkASSERT(SkStrokeRec::kFill_InitStyle == fill);
+ path = &tmpPath;
} else {
- path = *args.fPath;
- }
- if (!stroke.isFillStyle()) {
- stroke.setResScale(SkScalarAbs(args.fViewMatrix->getMaxScale()));
- if (!stroke.applyToPath(&path, path)) {
- return false;
- }
- stroke.setFillStyle();
+ path = args.fPath;
}
return this->internalDrawPath(args.fTarget,
args.fPipelineBuilder,
args.fColor,
*args.fViewMatrix,
- path,
- stroke,
+ *path,
false);
}
@@ -739,7 +738,7 @@ void GrMSAAPathRenderer::onStencilPath(const StencilPathArgs& args) {
SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType());
SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType());
this->internalDrawPath(args.fTarget, args.fPipelineBuilder, GrColor_WHITE, *args.fViewMatrix,
- *args.fPath, GrStrokeInfo::FillInfo(), true);
+ *args.fPath, true);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/batches/GrMSAAPathRenderer.h b/src/gpu/batches/GrMSAAPathRenderer.h
index a35536014e..434a962190 100644
--- a/src/gpu/batches/GrMSAAPathRenderer.h
+++ b/src/gpu/batches/GrMSAAPathRenderer.h
@@ -26,7 +26,6 @@ private:
GrColor,
const SkMatrix& viewMatrix,
const SkPath&,
- const GrStrokeInfo&,
bool stencilOnly);
typedef GrPathRenderer INHERITED;
diff --git a/src/gpu/batches/GrPLSPathRenderer.cpp b/src/gpu/batches/GrPLSPathRenderer.cpp
index 46993c7f33..c26b4c0243 100644
--- a/src/gpu/batches/GrPLSPathRenderer.cpp
+++ b/src/gpu/batches/GrPLSPathRenderer.cpp
@@ -23,7 +23,7 @@
#include "GrPathUtils.h"
#include "GrProcessor.h"
#include "GrPipelineBuilder.h"
-#include "GrStrokeInfo.h"
+#include "GrStyle.h"
#include "GrTessellator.h"
#include "batches/GrVertexBatch.h"
#include "glsl/GrGLSLGeometryProcessor.h"
@@ -778,7 +778,7 @@ bool GrPLSPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
// We have support for even-odd rendering, but are having some troublesome
// seams. Disable in the presence of even-odd for now.
return args.fShaderCaps->shaderDerivativeSupport() && args.fAntiAlias &&
- args.fStroke->isFillStyle() && !args.fPath->isInverseFillType() &&
+ args.fStyle->isSimpleFill() && !args.fPath->isInverseFillType() &&
args.fPath->getFillType() == SkPath::FillType::kWinding_FillType;
}
diff --git a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
index 6933efebe3..9d8d07de84 100644
--- a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
@@ -14,7 +14,7 @@
#include "GrPath.h"
#include "GrRenderTarget.h"
#include "GrResourceProvider.h"
-#include "GrStrokeInfo.h"
+#include "GrStyle.h"
#include "batches/GrRectBatchFactory.h"
GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrResourceProvider* resourceProvider,
@@ -31,7 +31,9 @@ GrStencilAndCoverPathRenderer::GrStencilAndCoverPathRenderer(GrResourceProvider*
}
bool GrStencilAndCoverPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
- if (args.fStroke->isHairlineStyle()) {
+ // GrPath doesn't support hairline paths. Also, an arbitrary path effect could change
+ // the style type to hairline.
+ if (!args.fStyle->hasNonDashPathEffect() || args.fStyle->strokeRec().isHairlineStyle()) {
return false;
}
if (!args.fIsStencilDisabled) {
@@ -45,19 +47,19 @@ bool GrStencilAndCoverPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) c
}
static GrPath* get_gr_path(GrResourceProvider* resourceProvider, const SkPath& skPath,
- const GrStrokeInfo& stroke) {
+ const GrStyle& style) {
GrUniqueKey key;
bool isVolatile;
- GrPath::ComputeKey(skPath, stroke, &key, &isVolatile);
+ GrPath::ComputeKey(skPath, style, &key, &isVolatile);
SkAutoTUnref<GrPath> path(
static_cast<GrPath*>(resourceProvider->findAndRefResourceByUniqueKey(key)));
if (!path) {
- path.reset(resourceProvider->createPath(skPath, stroke));
+ path.reset(resourceProvider->createPath(skPath, style));
if (!isVolatile) {
resourceProvider->assignUniqueKeyToResource(key, path);
}
} else {
- SkASSERT(path->isEqualTo(skPath, stroke));
+ SkASSERT(path->isEqualTo(skPath, style));
}
return path.release();
}
@@ -66,14 +68,14 @@ void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) {
GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),
"GrStencilAndCoverPathRenderer::onStencilPath");
SkASSERT(!args.fPath->isInverseFillType());
- SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, *args.fPath, GrStrokeInfo::FillInfo()));
+ SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, *args.fPath, GrStyle::SimpleFill()));
args.fTarget->stencilPath(*args.fPipelineBuilder, *args.fViewMatrix, p, p->getFillType());
}
bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),
"GrStencilAndCoverPathRenderer::onDrawPath");
- SkASSERT(!args.fStroke->isHairlineStyle());
+ SkASSERT(!args.fStyle->strokeRec().isHairlineStyle());
const SkPath& path = *args.fPath;
GrPipelineBuilder* pipelineBuilder = args.fPipelineBuilder;
const SkMatrix& viewMatrix = *args.fViewMatrix;
@@ -85,7 +87,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
pipelineBuilder->enableState(GrPipelineBuilder::kHWAntialias_Flag);
}
- SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, *args.fStroke));
+ SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, *args.fStyle));
if (path.isInverseFillType()) {
static constexpr GrStencilSettings kInvertedStencilPass(
diff --git a/src/gpu/batches/GrTessellatingPathRenderer.cpp b/src/gpu/batches/GrTessellatingPathRenderer.cpp
index 2c8520b28a..d2cfb6e9cb 100644
--- a/src/gpu/batches/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/batches/GrTessellatingPathRenderer.cpp
@@ -105,9 +105,10 @@ GrTessellatingPathRenderer::GrTessellatingPathRenderer() {
bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
// This path renderer can draw all fill styles, all stroke styles except hairlines, but does
// not do antialiasing. It can do convex and concave paths, but we'll leave the convex ones to
- // simpler algorithms.
- return !IsStrokeHairlineOrEquivalent(*args.fStroke, *args.fViewMatrix, nullptr) &&
- !args.fAntiAlias && !args.fPath->isConvex();
+ // simpler algorithms. Similary, we skip the non-hairlines that can be treated as hairline.
+ // An arbitrary path effect could produce a hairline result so we pass on those.
+ return !IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullptr) &&
+ !args.fStyle->hasNonDashPathEffect() && !args.fAntiAlias && !args.fPath->isConvex();
}
class TessellatingPathBatch : public GrVertexBatch {
@@ -116,10 +117,10 @@ public:
static GrDrawBatch* Create(const GrColor& color,
const SkPath& path,
- const GrStrokeInfo& stroke,
+ const GrStyle& style,
const SkMatrix& viewMatrix,
SkRect clipBounds) {
- return new TessellatingPathBatch(color, path, stroke, viewMatrix, clipBounds);
+ return new TessellatingPathBatch(color, path, style, viewMatrix, clipBounds);
}
const char* name() const override { return "TessellatingPathBatch"; }
@@ -142,48 +143,51 @@ private:
}
void draw(Target* target, const GrGeometryProcessor* gp) const {
+ GrResourceProvider* rp = target->resourceProvider();
+ SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
+ SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, fViewMatrix,
+ fPath.getBounds());
+
+ SkScalar styleScale = SK_Scalar1;
+ if (fStyle.applies()) {
+ styleScale = GrStyle::MatrixToScaleFactor(fViewMatrix);
+ }
+
// construct a cache key from the path's genID and the view matrix
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
GrUniqueKey key;
- int clipBoundsSize32 =
+ int clipBoundsCnt =
fPath.isInverseFillType() ? sizeof(fClipBounds) / sizeof(uint32_t) : 0;
- int strokeDataSize32 = fStroke.computeUniqueKeyFragmentData32Cnt();
- GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsSize32 + strokeDataSize32);
- builder[0] = fPath.getGenerationID();
- builder[1] = fPath.getFillType();
- // For inverse fills, the tessellation is dependent on clip bounds.
- if (fPath.isInverseFillType()) {
- memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds));
- }
- fStroke.asUniqueKeyFragment(&builder[2 + clipBoundsSize32]);
- builder.finish();
- GrResourceProvider* rp = target->resourceProvider();
- SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey<GrBuffer>(key));
- int actualCount;
- SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
- SkScalar tol = GrPathUtils::scaleToleranceToSrc(
- screenSpaceTol, fViewMatrix, fPath.getBounds());
- if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) {
- this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actualCount);
- return;
+ int styleDataCnt = GrStyle::KeySize(fStyle, GrStyle::Apply::kPathEffectAndStrokeRec);
+ if (styleDataCnt >= 0) {
+ GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsCnt + styleDataCnt);
+ builder[0] = fPath.getGenerationID();
+ builder[1] = fPath.getFillType();
+ // For inverse fills, the tessellation is dependent on clip bounds.
+ if (fPath.isInverseFillType()) {
+ memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds));
+ }
+ if (styleDataCnt) {
+ GrStyle::WriteKey(&builder[2 + clipBoundsCnt], fStyle,
+ GrStyle::Apply::kPathEffectAndStrokeRec, styleScale);
+ }
+ builder.finish();
+ SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey<GrBuffer>(key));
+ int actualCount;
+ if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) {
+ this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actualCount);
+ return;
+ }
}
SkPath path;
- GrStrokeInfo stroke(fStroke);
- if (stroke.isDashed()) {
- if (!stroke.applyDashToPath(&path, &stroke, fPath)) {
- return;
- }
+ if (fStyle.applies()) {
+ SkStrokeRec::InitStyle fill;
+ SkAssertResult(fStyle.applyToPath(&path, &fill, fPath, styleScale));
+ SkASSERT(SkStrokeRec::kFill_InitStyle == fill);
} else {
path = fPath;
}
- if (!stroke.isFillStyle()) {
- stroke.setResScale(SkScalarAbs(fViewMatrix.getMaxScale()));
- if (!stroke.applyToPath(&path, path)) {
- return;
- }
- stroke.setFillStyle();
- }
bool isLinear;
bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags();
StaticVertexAllocator allocator(rp, canMapVB);
@@ -192,7 +196,7 @@ private:
return;
}
this->drawVertices(target, gp, allocator.vertexBuffer(), 0, count);
- if (!fPath.isVolatile()) {
+ if (!fPath.isVolatile() && styleDataCnt >= 0) {
TessInfo info;
info.fTolerance = isLinear ? 0 : tol;
info.fCount = count;
@@ -240,13 +244,13 @@ private:
TessellatingPathBatch(const GrColor& color,
const SkPath& path,
- const GrStrokeInfo& stroke,
+ const GrStyle& style,
const SkMatrix& viewMatrix,
const SkRect& clipBounds)
: INHERITED(ClassID())
, fColor(color)
, fPath(path)
- , fStroke(stroke)
+ , fStyle(style)
, fViewMatrix(viewMatrix) {
const SkRect& pathBounds = path.getBounds();
fClipBounds = clipBounds;
@@ -258,14 +262,13 @@ private:
} else {
fBounds = path.getBounds();
}
- SkScalar radius = stroke.getInflationRadius();
- fBounds.outset(radius, radius);
+ style.adjustBounds(&fBounds, fBounds);
viewMatrix.mapRect(&fBounds);
}
GrColor fColor;
SkPath fPath;
- GrStrokeInfo fStroke;
+ GrStyle fStyle;
SkMatrix fViewMatrix;
SkRect fClipBounds; // in source space
GrXPOverridesForBatch fPipelineInfo;
@@ -291,7 +294,7 @@ bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) {
}
vmi.mapRect(&clipBounds);
SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fColor, *args.fPath,
- *args.fStroke, *args.fViewMatrix,
+ *args.fStyle, *args.fViewMatrix,
clipBounds));
args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
@@ -313,8 +316,11 @@ DRAW_BATCH_TEST_DEFINE(TesselatingPathBatch) {
SkFAIL("Cannot invert matrix\n");
}
vmi.mapRect(&clipBounds);
- GrStrokeInfo strokeInfo = GrTest::TestStrokeInfo(random);
- return TessellatingPathBatch::Create(color, path, strokeInfo, viewMatrix, clipBounds);
+ GrStyle style;
+ do {
+ GrTest::TestStyle(random, &style);
+ } while (style.strokeRec().isHairlineStyle());
+ return TessellatingPathBatch::Create(color, path, style, viewMatrix, clipBounds);
}
#endif