| Index: src/gpu/GrBlurUtils.cpp
|
| diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
|
| index 0a8351fd07793ab25863b5a0fa275ceac14b1bfa..aee158113b759275fd34635eaea67a5feec82332 100644
|
| --- a/src/gpu/GrBlurUtils.cpp
|
| +++ b/src/gpu/GrBlurUtils.cpp
|
| @@ -10,7 +10,7 @@
|
| #include "GrCaps.h"
|
| #include "GrContext.h"
|
| #include "effects/GrSimpleTextureEffect.h"
|
| -#include "GrStyle.h"
|
| +#include "GrStrokeInfo.h"
|
| #include "GrTexture.h"
|
| #include "GrTextureProvider.h"
|
| #include "SkDraw.h"
|
| @@ -54,10 +54,11 @@
|
| const SkMaskFilter* filter,
|
| const SkIRect& clipBounds,
|
| GrPaint* grp,
|
| - SkStrokeRec::InitStyle fillOrHairline) {
|
| + SkStrokeRec::InitStyle style) {
|
| SkMask srcM, dstM;
|
| +
|
| if (!SkDraw::DrawToMask(devPath, &clipBounds, filter, &viewMatrix, &srcM,
|
| - SkMask::kComputeBoundsAndRenderImage_CreateMode, fillOrHairline)) {
|
| + SkMask::kComputeBoundsAndRenderImage_CreateMode, style)) {
|
| return false;
|
| }
|
| SkAutoMaskFreeImage autoSrc(srcM.fImage);
|
| @@ -95,7 +96,7 @@
|
| static sk_sp<GrTexture> create_mask_GPU(GrContext* context,
|
| SkRect* maskRect,
|
| const SkPath& devPath,
|
| - SkStrokeRec::InitStyle fillOrHairline,
|
| + SkStrokeRec::InitStyle style,
|
| bool doAA,
|
| int sampleCnt) {
|
| // This mask will ultimately be drawn as a non-AA rect (see draw_mask).
|
| @@ -138,7 +139,7 @@
|
| // the origin using tempPaint.
|
| SkMatrix translate;
|
| translate.setTranslate(-maskRect->fLeft, -maskRect->fTop);
|
| - drawContext->drawPath(clip, tempPaint, translate, devPath, GrStyle(fillOrHairline));
|
| + drawContext->drawPath(clip, tempPaint, translate, devPath, GrStrokeInfo(style));
|
| return drawContext->asTexture();;
|
| }
|
|
|
| @@ -148,50 +149,52 @@
|
| GrPaint* paint,
|
| const SkMatrix& viewMatrix,
|
| const SkMaskFilter* maskFilter,
|
| - const GrStyle& style,
|
| - const SkPath* path,
|
| + const SkPathEffect* pathEffect,
|
| + const GrStrokeInfo& strokeInfo,
|
| + SkPath* pathPtr,
|
| bool pathIsMutable) {
|
| SkASSERT(maskFilter);
|
|
|
| SkIRect clipBounds;
|
| clip.getConservativeBounds(drawContext->width(), drawContext->height(), &clipBounds);
|
| SkTLazy<SkPath> tmpPath;
|
| - SkStrokeRec::InitStyle fillOrHairline;
|
| -
|
| - // We just fully apply the style here.
|
| - if (style.applies()) {
|
| - if (!style.applyToPath(tmpPath.init(), &fillOrHairline, *path,
|
| - GrStyle::MatrixToScaleFactor(viewMatrix))) {
|
| - return;
|
| - }
|
| - pathIsMutable = true;
|
| - path = tmpPath.get();
|
| - } else if (style.isSimpleHairline()) {
|
| - fillOrHairline = SkStrokeRec::kHairline_InitStyle;
|
| +
|
| + static const SkRect* cullRect = nullptr; // TODO: what is our bounds?
|
| +
|
| + SkASSERT(strokeInfo.isDashed() || !pathEffect);
|
| + SkStrokeRec::InitStyle maskStyle;
|
| + if (strokeInfo.isHairlineStyle()) {
|
| + maskStyle = SkStrokeRec::kHairline_InitStyle;
|
| } else {
|
| - SkASSERT(style.isSimpleFill());
|
| - fillOrHairline = SkStrokeRec::kFill_InitStyle;
|
| + SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init();
|
| + SkStrokeRec rec = strokeInfo;
|
| + if (strokeInfo.isDashed()) {
|
| + if (pathEffect->filterPath(strokedPath, *pathPtr, &rec, cullRect)) {
|
| + pathPtr = strokedPath;
|
| + pathPtr->setIsVolatile(true);
|
| + pathIsMutable = true;
|
| + }
|
| + }
|
| + if (rec.applyToPath(strokedPath, *pathPtr)) {
|
| + // Apply the stroke to the path if there is one
|
| + pathPtr = strokedPath;
|
| + pathPtr->setIsVolatile(true);
|
| + pathIsMutable = true;
|
| + }
|
| + maskStyle = SkStrokeRec::kFill_InitStyle;
|
| + }
|
| +
|
| + // avoid possibly allocating a new path in transform if we can
|
| + SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath.init();
|
| + if (!pathIsMutable) {
|
| + devPathPtr->setIsVolatile(true);
|
| }
|
|
|
| // transform the path into device space
|
| - if (!viewMatrix.isIdentity()) {
|
| - SkPath* result;
|
| - if (pathIsMutable) {
|
| - result = const_cast<SkPath*>(path);
|
| - } else {
|
| - if (!tmpPath.isValid()) {
|
| - tmpPath.init();
|
| - }
|
| - result = tmpPath.get();
|
| - }
|
| - path->transform(viewMatrix, result);
|
| - path = result;
|
| - result->setIsVolatile(true);
|
| - pathIsMutable = true;
|
| - }
|
| + pathPtr->transform(viewMatrix, devPathPtr);
|
|
|
| SkRect maskRect;
|
| - if (maskFilter->canFilterMaskGPU(SkRRect::MakeRect(path->getBounds()),
|
| + if (maskFilter->canFilterMaskGPU(SkRRect::MakeRect(devPathPtr->getBounds()),
|
| clipBounds,
|
| viewMatrix,
|
| &maskRect)) {
|
| @@ -207,8 +210,8 @@
|
| paint,
|
| clip,
|
| viewMatrix,
|
| - SkStrokeRec(fillOrHairline),
|
| - *path)) {
|
| + SkStrokeRec(maskStyle),
|
| + *devPathPtr)) {
|
| // the mask filter was able to draw itself directly, so there's nothing
|
| // left to do.
|
| return;
|
| @@ -216,8 +219,8 @@
|
|
|
| sk_sp<GrTexture> mask(create_mask_GPU(context,
|
| &maskRect,
|
| - *path,
|
| - fillOrHairline,
|
| + *devPathPtr,
|
| + maskStyle,
|
| paint->isAntiAlias(),
|
| drawContext->numColorSamples()));
|
| if (mask) {
|
| @@ -235,58 +238,95 @@
|
| }
|
|
|
| sw_draw_with_mask_filter(drawContext, context->textureProvider(),
|
| - clip, viewMatrix, *path,
|
| - maskFilter, clipBounds, paint, fillOrHairline);
|
| -}
|
| -
|
| -void GrBlurUtils::drawPathWithMaskFilter(GrContext* context,
|
| - GrDrawContext* drawContext,
|
| - const GrClip& clip,
|
| - const SkPath& path,
|
| - GrPaint* paint,
|
| - const SkMatrix& viewMatrix,
|
| - const SkMaskFilter* mf,
|
| - const GrStyle& style,
|
| - bool pathIsMutable) {
|
| - draw_path_with_mask_filter(context, drawContext, clip, paint, viewMatrix, mf,
|
| - style, &path, pathIsMutable);
|
| + clip, viewMatrix, *devPathPtr,
|
| + maskFilter, clipBounds, paint, maskStyle);
|
| }
|
|
|
| void GrBlurUtils::drawPathWithMaskFilter(GrContext* context,
|
| GrDrawContext* drawContext,
|
| const GrClip& clip,
|
| const SkPath& origPath,
|
| + GrPaint* paint,
|
| + const SkMatrix& viewMatrix,
|
| + const SkMaskFilter* mf,
|
| + const SkPathEffect* pathEffect,
|
| + const GrStrokeInfo& origStrokeInfo,
|
| + bool pathIsMutable) {
|
| + SkPath* pathPtr = const_cast<SkPath*>(&origPath);
|
| +
|
| + SkTLazy<SkPath> tmpPath;
|
| + GrStrokeInfo strokeInfo(origStrokeInfo);
|
| +
|
| + if (!strokeInfo.isDashed() && pathEffect && pathEffect->filterPath(tmpPath.init(), *pathPtr,
|
| + &strokeInfo, nullptr)) {
|
| + pathPtr = tmpPath.get();
|
| + pathPtr->setIsVolatile(true);
|
| + pathIsMutable = true;
|
| + pathEffect = nullptr;
|
| + }
|
| +
|
| + draw_path_with_mask_filter(context, drawContext, clip, paint, viewMatrix, mf, pathEffect,
|
| + strokeInfo, pathPtr, pathIsMutable);
|
| +}
|
| +
|
| +void GrBlurUtils::drawPathWithMaskFilter(GrContext* context,
|
| + GrDrawContext* drawContext,
|
| + const GrClip& clip,
|
| + const SkPath& origSrcPath,
|
| const SkPaint& paint,
|
| const SkMatrix& origViewMatrix,
|
| const SkMatrix* prePathMatrix,
|
| const SkIRect& clipBounds,
|
| bool pathIsMutable) {
|
| - SkASSERT(!pathIsMutable || origPath.isVolatile());
|
| -
|
| - GrStyle style(paint);
|
| + SkASSERT(!pathIsMutable || origSrcPath.isVolatile());
|
| +
|
| + GrStrokeInfo strokeInfo(paint);
|
| + // comment out the line below to determine if it is the reason that the chrome mac perf bot
|
| + // has begun crashing
|
| + // strokeInfo.setResScale(SkDraw::ComputeResScaleForStroking(origViewMatrix));
|
| +
|
| // If we have a prematrix, apply it to the path, optimizing for the case
|
| // where the original path can in fact be modified in place (even though
|
| // its parameter type is const).
|
| -
|
| - const SkPath* path = &origPath;
|
| + SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath);
|
| SkTLazy<SkPath> tmpPath;
|
| + SkTLazy<SkPath> effectPath;
|
| + SkPathEffect* pathEffect = paint.getPathEffect();
|
|
|
| SkMatrix viewMatrix = origViewMatrix;
|
|
|
| if (prePathMatrix) {
|
| - // Styling, blurs, and shading are supposed to be applied *after* the prePathMatrix.
|
| - if (!paint.getMaskFilter() && !paint.getShader() && !style.applies()) {
|
| + // stroking, path effects, and blurs are supposed to be applied *after* the prePathMatrix.
|
| + // The pre-path-matrix also should not affect shading.
|
| + if (!paint.getMaskFilter() && !pathEffect && !paint.getShader() &&
|
| + (strokeInfo.isFillStyle() || strokeInfo.isHairlineStyle())) {
|
| viewMatrix.preConcat(*prePathMatrix);
|
| } else {
|
| - SkPath* result = pathIsMutable ? const_cast<SkPath*>(path) : tmpPath.init();
|
| - pathIsMutable = true;
|
| - path->transform(*prePathMatrix, result);
|
| - path = result;
|
| - result->setIsVolatile(true);
|
| + SkPath* result = pathPtr;
|
| +
|
| + if (!pathIsMutable) {
|
| + result = tmpPath.init();
|
| + result->setIsVolatile(true);
|
| + pathIsMutable = true;
|
| + }
|
| + // should I push prePathMatrix on our MV stack temporarily, instead
|
| + // of applying it here? See SkDraw.cpp
|
| + pathPtr->transform(*prePathMatrix, result);
|
| + pathPtr = result;
|
| }
|
| }
|
| // at this point we're done with prePathMatrix
|
| SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
|
| +
|
| + SkTLazy<SkPath> tmpPath2;
|
| +
|
| + if (!strokeInfo.isDashed() && pathEffect &&
|
| + pathEffect->filterPath(tmpPath2.init(), *pathPtr, &strokeInfo, nullptr)) {
|
| + pathPtr = tmpPath2.get();
|
| + pathPtr->setIsVolatile(true);
|
| + pathIsMutable = true;
|
| + pathEffect = nullptr;
|
| + }
|
|
|
| GrPaint grPaint;
|
| if (!SkPaintToGrPaint(context, paint, viewMatrix, drawContext->isGammaCorrect(),
|
| @@ -296,9 +336,9 @@
|
|
|
| if (paint.getMaskFilter()) {
|
| draw_path_with_mask_filter(context, drawContext, clip, &grPaint, viewMatrix,
|
| - paint.getMaskFilter(), style,
|
| - path, pathIsMutable);
|
| + paint.getMaskFilter(), pathEffect, strokeInfo,
|
| + pathPtr, pathIsMutable);
|
| } else {
|
| - drawContext->drawPath(clip, grPaint, viewMatrix, *path, style);
|
| - }
|
| -}
|
| + drawContext->drawPath(clip, grPaint, viewMatrix, *pathPtr, strokeInfo);
|
| + }
|
| +}
|
|
|