Chromium Code Reviews| Index: src/gpu/GrDrawContext.cpp |
| diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp |
| index 6c80f52bba5c9260e815fed142a708bd1e0708d1..984b7422d1064f4bdd9e873fa61d8111ad20d0df 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 |
|
egdaniel
2016/05/09 20:08:40
so previously this seemed to allow some none dashe
bsalomon
2016/05/09 20:38:55
Updated the comment to say path effects instead of
|
| - SkASSERT(!strokeInfo || !strokeInfo->isDashed()); |
| + 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); |