diff options
Diffstat (limited to 'src/gpu/GrDrawContext.cpp')
-rw-r--r-- | src/gpu/GrDrawContext.cpp | 139 |
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); |