aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrDrawContext.cpp
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/GrDrawContext.cpp
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/GrDrawContext.cpp')
-rw-r--r--src/gpu/GrDrawContext.cpp139
1 files changed, 69 insertions, 70 deletions
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp
index 6c80f52bba..a7c7f6ae5f 100644
--- a/src/gpu/GrDrawContext.cpp
+++ b/src/gpu/GrDrawContext.cpp
@@ -279,18 +279,22 @@ void GrDrawContext::drawRect(const GrClip& clip,
const GrPaint& paint,
const SkMatrix& viewMatrix,
const SkRect& rect,
- const GrStrokeInfo* strokeInfo) {
+ const GrStyle* style) {
+ if (!style) {
+ style = &GrStyle::SimpleFill();
+ }
ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED
SkDEBUGCODE(this->validate();)
GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRect");
- // Dashing should've been devolved to a path in SkGpuDevice
- SkASSERT(!strokeInfo || !strokeInfo->isDashed());
+ // Path effects should've been devolved to a path in SkGpuDevice
+ SkASSERT(!style->pathEffect());
AutoCheckFlush acf(fDrawingManager);
- SkScalar width = !strokeInfo ? -1 : strokeInfo->getWidth();
+ const SkStrokeRec& stroke = style->strokeRec();
+ SkScalar width = stroke.getWidth();
// Check if this is a full RT draw and can be replaced with a clear. We don't bother checking
// cases where the RT is fully inside a stroke.
@@ -337,7 +341,7 @@ void GrDrawContext::drawRect(const GrClip& clip,
// The stroke path needs the rect to remain axis aligned (no rotation or skew).
if (viewMatrix.rectStaysRect()) {
batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, rect,
- *strokeInfo));
+ stroke));
}
} else {
// Non-AA hairlines are snapped to pixel centers to make which pixels are hit
@@ -367,8 +371,7 @@ void GrDrawContext::drawRect(const GrClip& clip,
SkPath path;
path.setIsVolatile(true);
path.addRect(rect);
- this->internalDrawPath(clip, paint, viewMatrix, path,
- strokeInfo ? *strokeInfo : GrStrokeInfo::FillInfo());
+ this->internalDrawPath(clip, paint, viewMatrix, path, *style);
}
bool GrDrawContextPriv::drawAndStencilRect(const SkIRect* scissorRect,
@@ -536,7 +539,7 @@ void GrDrawContext::drawRRect(const GrClip& clip,
const GrPaint& paint,
const SkMatrix& viewMatrix,
const SkRRect& rrect,
- const GrStrokeInfo& strokeInfo) {
+ const GrStyle& style) {
ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED
SkDEBUGCODE(this->validate();)
@@ -546,8 +549,8 @@ void GrDrawContext::drawRRect(const GrClip& clip,
return;
}
- SkASSERT(!strokeInfo.isDashed()); // this should've been devolved to a path in SkGpuDevice
-
+ SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
+ const SkStrokeRec stroke = style.strokeRec();
AutoCheckFlush acf(fDrawingManager);
if (should_apply_coverage_aa(paint, fRenderTarget.get())) {
@@ -556,7 +559,7 @@ void GrDrawContext::drawRRect(const GrClip& clip,
SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateRRectBatch(paint.getColor(),
viewMatrix,
rrect,
- strokeInfo,
+ stroke,
shaderCaps));
if (batch) {
GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
@@ -568,7 +571,7 @@ void GrDrawContext::drawRRect(const GrClip& clip,
SkPath path;
path.setIsVolatile(true);
path.addRRect(rrect);
- this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo);
+ this->internalDrawPath(clip, paint, viewMatrix, path, style);
}
bool GrDrawContext::drawFilledDRRect(const GrClip& clip,
@@ -654,7 +657,7 @@ void GrDrawContext::drawDRRect(const GrClip& clip,
path.setFillType(SkPath::kEvenOdd_FillType);
GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
- this->internalDrawPath(clip, paint, viewMatrix, path, GrStrokeInfo::FillInfo());
+ this->internalDrawPath(clip, paint, viewMatrix, path, GrStyle::SimpleFill());
}
///////////////////////////////////////////////////////////////////////////////
@@ -663,7 +666,7 @@ void GrDrawContext::drawOval(const GrClip& clip,
const GrPaint& paint,
const SkMatrix& viewMatrix,
const SkRect& oval,
- const GrStrokeInfo& strokeInfo) {
+ const GrStyle& style) {
ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED
SkDEBUGCODE(this->validate();)
@@ -673,16 +676,16 @@ void GrDrawContext::drawOval(const GrClip& clip,
return;
}
- SkASSERT(!strokeInfo.isDashed()); // this should've been devolved to a path in SkGpuDevice
+ SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
AutoCheckFlush acf(fDrawingManager);
-
+ const SkStrokeRec& stroke = style.strokeRec();
if (should_apply_coverage_aa(paint, fRenderTarget.get())) {
GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.getColor(),
viewMatrix,
oval,
- strokeInfo,
+ stroke,
shaderCaps));
if (batch) {
GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
@@ -694,7 +697,7 @@ void GrDrawContext::drawOval(const GrClip& clip,
SkPath path;
path.setIsVolatile(true);
path.addOval(oval);
- this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo);
+ this->internalDrawPath(clip, paint, viewMatrix, path, style);
}
void GrDrawContext::drawImageNine(const GrClip& clip,
@@ -721,11 +724,7 @@ void GrDrawContext::drawImageNine(const GrClip& clip,
// Can 'path' be drawn as a pair of filled nested rectangles?
-static bool is_nested_rects(const SkMatrix& viewMatrix,
- const SkPath& path,
- const SkStrokeRec& stroke,
- SkRect rects[2]) {
- SkASSERT(stroke.isFillStyle());
+static bool fills_as_nested_rects(const SkMatrix& viewMatrix, const SkPath& path, SkRect rects[2]) {
if (path.isInverseFillType()) {
return false;
@@ -799,7 +798,7 @@ void GrDrawContext::drawPath(const GrClip& clip,
const GrPaint& paint,
const SkMatrix& viewMatrix,
const SkPath& path,
- const GrStrokeInfo& strokeInfo) {
+ const GrStyle& style) {
ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED
SkDEBUGCODE(this->validate();)
@@ -814,12 +813,12 @@ void GrDrawContext::drawPath(const GrClip& clip,
AutoCheckFlush acf(fDrawingManager);
- if (should_apply_coverage_aa(paint, fRenderTarget.get()) && !strokeInfo.isDashed()) {
- if (strokeInfo.getWidth() < 0 && !path.isConvex()) {
+ if (should_apply_coverage_aa(paint, fRenderTarget.get()) && !style.pathEffect()) {
+ if (style.isSimpleFill() && !path.isConvex()) {
// Concave AA paths are expensive - try to avoid them for special cases
SkRect rects[2];
- if (is_nested_rects(viewMatrix, path, strokeInfo, rects)) {
+ if (fills_as_nested_rects(viewMatrix, path, rects)) {
SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFillNestedRects(
paint.getColor(), viewMatrix, rects));
if (batch) {
@@ -837,7 +836,7 @@ void GrDrawContext::drawPath(const GrClip& clip,
SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.getColor(),
viewMatrix,
ovalRect,
- strokeInfo,
+ style.strokeRec(),
shaderCaps));
if (batch) {
GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
@@ -852,7 +851,7 @@ void GrDrawContext::drawPath(const GrClip& clip,
// cache. This presents a potential hazard for buffered drawing. However,
// the writePixels that uploads to the scratch will perform a flush so we're
// OK.
- this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo);
+ this->internalDrawPath(clip, paint, viewMatrix, path, style);
}
bool GrDrawContextPriv::drawAndStencilPath(const SkIRect* scissorRect,
@@ -892,7 +891,7 @@ bool GrDrawContextPriv::drawAndStencilPath(const SkIRect* scissorRect,
canDrawArgs.fShaderCaps = fDrawContext->fDrawingManager->getContext()->caps()->shaderCaps();
canDrawArgs.fViewMatrix = &viewMatrix;
canDrawArgs.fPath = &path;
- canDrawArgs.fStroke = &GrStrokeInfo::FillInfo();
+ canDrawArgs.fStyle = &GrStyle::SimpleFill();
canDrawArgs.fAntiAlias = useCoverageAA;
canDrawArgs.fIsStencilDisabled = isStencilDisabled;
canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
@@ -923,7 +922,7 @@ bool GrDrawContextPriv::drawAndStencilPath(const SkIRect* scissorRect,
args.fColor = GrColor_WHITE;
args.fViewMatrix = &viewMatrix;
args.fPath = &path;
- args.fStroke = &GrStrokeInfo::FillInfo();
+ args.fStyle = &GrStyle::SimpleFill();
args.fAntiAlias = useCoverageAA;
args.fGammaCorrect = fDrawContext->isGammaCorrect();
pr->drawPath(args);
@@ -933,16 +932,12 @@ bool GrDrawContextPriv::drawAndStencilPath(const SkIRect* scissorRect,
void GrDrawContext::internalDrawPath(const GrClip& clip,
const GrPaint& paint,
const SkMatrix& viewMatrix,
- const SkPath& path,
- const GrStrokeInfo& strokeInfo) {
+ const SkPath& origPath,
+ const GrStyle& origStyle) {
ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED
- SkASSERT(!path.isEmpty());
+ SkASSERT(!origPath.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 = should_apply_coverage_aa(paint, fRenderTarget.get());
const bool isStencilDisabled = true;
bool isStencilBufferMSAA = fRenderTarget->isStencilBufferMultisampled();
@@ -951,61 +946,65 @@ void GrDrawContext::internalDrawPath(const GrClip& clip,
useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType
: GrPathRendererChain::kColor_DrawType;
- const SkPath* pathPtr = &path;
SkTLazy<SkPath> tmpPath;
- const GrStrokeInfo* strokeInfoPtr = &strokeInfo;
+ SkTLazy<GrStyle> tmpStyle;
GrPathRenderer::CanDrawPathArgs canDrawArgs;
canDrawArgs.fShaderCaps = fDrawingManager->getContext()->caps()->shaderCaps();
canDrawArgs.fViewMatrix = &viewMatrix;
- canDrawArgs.fPath = pathPtr;
- canDrawArgs.fStroke = strokeInfoPtr;
+ canDrawArgs.fPath = &origPath;
+ canDrawArgs.fStyle = &origStyle;
canDrawArgs.fAntiAlias = useCoverageAA;
canDrawArgs.fIsStencilDisabled = isStencilDisabled;
canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
- // Try a 1st time without stroking the path and without allowing the SW renderer
+ // Try a 1st time without applying any of the style to the geometry (and barring sw)
GrPathRenderer* pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
-
- GrStrokeInfo dashlessStrokeInfo(strokeInfo, false);
- if (nullptr == pr && strokeInfo.isDashed()) {
- // It didn't work above, so try again with dashed stroke converted to a dashless stroke.
- if (!strokeInfo.applyDashToPath(tmpPath.init(), &dashlessStrokeInfo, *pathPtr)) {
+ SkScalar styleScale = GrStyle::MatrixToScaleFactor(viewMatrix);
+
+ if (!pr && canDrawArgs.fStyle->pathEffect()) {
+ // It didn't work above, so try again with the path effect applied.
+ SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
+ if (!canDrawArgs.fStyle->applyPathEffectToPath(tmpPath.init(), &rec, *canDrawArgs.fPath,
+ styleScale)) {
+ GrStyle noPathEffect(canDrawArgs.fStyle->strokeRec(), nullptr);
+ this->internalDrawPath(clip, paint, viewMatrix, *canDrawArgs.fPath, noPathEffect);
return;
}
- pathPtr = tmpPath.get();
- if (pathPtr->isEmpty()) {
+ tmpStyle.init(rec, nullptr);
+ canDrawArgs.fPath = tmpPath.get();
+ canDrawArgs.fStyle = tmpStyle.get();
+ if (canDrawArgs.fPath->isEmpty()) {
return;
}
- strokeInfoPtr = &dashlessStrokeInfo;
-
- canDrawArgs.fPath = pathPtr;
- canDrawArgs.fStroke = strokeInfoPtr;
pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
}
-
- if (nullptr == pr) {
- if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*strokeInfoPtr, viewMatrix, nullptr) &&
- !strokeInfoPtr->isFillStyle()) {
- // It didn't work above, so try again with stroke converted to a fill.
+ if (!pr) {
+ SkASSERT(!canDrawArgs.fStyle->pathEffect());
+ if (canDrawArgs.fStyle->strokeRec().needToApply()) {
if (!tmpPath.isValid()) {
tmpPath.init();
}
- dashlessStrokeInfo.setResScale(SkScalarAbs(viewMatrix.getMaxScale()));
- if (!dashlessStrokeInfo.applyToPath(tmpPath.get(), *pathPtr)) {
+ // It didn't work above, so try again by applying the stroke to the geometry.
+ SkStrokeRec::InitStyle fillOrHairline;
+ if (!canDrawArgs.fStyle->applyToPath(tmpPath.get(), &fillOrHairline,
+ *canDrawArgs.fPath, styleScale)) {
return;
}
- pathPtr = tmpPath.get();
- if (pathPtr->isEmpty()) {
+ if (!tmpStyle.isValid()) {
+ tmpStyle.init(fillOrHairline);
+ } else {
+ tmpStyle.get()->resetToInitStyle(fillOrHairline);
+ }
+ canDrawArgs.fPath = tmpPath.get();
+ canDrawArgs.fStyle = tmpStyle.get();
+ if (canDrawArgs.fPath->isEmpty()) {
return;
}
- dashlessStrokeInfo.setFillStyle();
- strokeInfoPtr = &dashlessStrokeInfo;
- }
- canDrawArgs.fPath = pathPtr;
- canDrawArgs.fStroke = strokeInfoPtr;
+ pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
+ }
// This time, allow SW renderer
pr = fDrawingManager->getPathRenderer(canDrawArgs, true, type);
@@ -1026,8 +1025,8 @@ void GrDrawContext::internalDrawPath(const GrClip& clip,
args.fPipelineBuilder = &pipelineBuilder;
args.fColor = paint.getColor();
args.fViewMatrix = &viewMatrix;
- args.fPath = pathPtr;
- args.fStroke = strokeInfoPtr;
+ args.fPath = canDrawArgs.fPath;
+ args.fStyle = canDrawArgs.fStyle;
args.fAntiAlias = useCoverageAA;
args.fGammaCorrect = this->isGammaCorrect();
pr->drawPath(args);