diff options
author | egdaniel <egdaniel@google.com> | 2014-06-11 10:30:05 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-06-11 10:30:05 -0700 |
commit | d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40 (patch) | |
tree | 76bf2e32924ec9a1988e68c226eb0c22d017848b | |
parent | 9b7906672eb6794497d560761aa8bab824a13a90 (diff) |
Push dash checks into GrContext.
Add class to hold stroke and dash info.
R=bsalomon@google.com, robertphillips@google.com, jvanverth@google.com
Author: egdaniel@google.com
Review URL: https://codereview.chromium.org/311183002
-rw-r--r-- | gyp/gpu.gypi | 1 | ||||
-rw-r--r-- | include/gpu/GrContext.h | 26 | ||||
-rw-r--r-- | src/gpu/GrAARectRenderer.cpp | 6 | ||||
-rw-r--r-- | src/gpu/GrAARectRenderer.h | 2 | ||||
-rwxr-xr-x | src/gpu/GrBitmapTextContext.cpp | 5 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 81 | ||||
-rwxr-xr-x | src/gpu/GrDistanceFieldTextContext.cpp | 5 | ||||
-rw-r--r-- | src/gpu/GrStrokeInfo.h | 88 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 79 |
9 files changed, 232 insertions, 61 deletions
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index d336fa9895..fdefee35a2 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -118,6 +118,7 @@ '<(skia_src_path)/gpu/GrStencilAndCoverPathRenderer.h', '<(skia_src_path)/gpu/GrStencilBuffer.cpp', '<(skia_src_path)/gpu/GrStencilBuffer.h', + '<(skia_src_path)/gpu/GrStrokeInfo.h', '<(skia_src_path)/gpu/GrTBSearch.h', '<(skia_src_path)/gpu/GrTraceMarker.cpp', '<(skia_src_path)/gpu/GrTraceMarker.h', diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 41ee15917f..c909907bfc 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -39,6 +39,7 @@ class GrTestTarget; class GrTextureParams; class GrVertexBuffer; class GrVertexBufferAllocPool; +class GrStrokeInfo; class GrSoftwarePathRenderer; class SkStrokeRec; @@ -452,18 +453,20 @@ public: /** * Draw the rect using a paint. * @param paint describes how to color pixels. - * @param stroke the stroke information (width, join, cap). - * If stroke == NULL, then the rect is filled. + * @param strokeInfo the stroke information (width, join, cap), and. + * the dash information (intervals, count, phase). + * If strokeInfo == NULL, then the rect is filled. * Otherwise, if stroke width == 0, then the stroke * is always a single pixel thick, else the rect is * mitered/beveled stroked based on stroke width. + * If the stroke is dashed the rect is sent to drawPath. * @param matrix Optional matrix applied to the rect. Applied before * context's matrix or the paint's matrix. * The rects coords are used to access the paint (through texture matrix) */ void drawRect(const GrPaint& paint, const SkRect&, - const SkStrokeRec* stroke = NULL, + const GrStrokeInfo* strokeInfo = NULL, const SkMatrix* matrix = NULL); /** @@ -490,9 +493,10 @@ public: * * @param paint describes how to color pixels. * @param rrect the roundrect to draw - * @param stroke the stroke information (width, join, cap) + * @param strokeInfo the stroke information (width, join, cap) and + * the dash information (intervals, count, phase). */ - void drawRRect(const GrPaint& paint, const SkRRect& rrect, const SkStrokeRec& stroke); + void drawRRect(const GrPaint& paint, const SkRRect& rrect, const GrStrokeInfo& strokeInfo); /** * Shortcut for drawing an SkPath consisting of nested rrects using a paint. @@ -511,9 +515,10 @@ public: * * @param paint describes how to color pixels. * @param path the path to draw - * @param stroke the stroke information (width, join, cap) + * @param strokeInfo the stroke information (width, join, cap) and + * the dash information (intervals, count, phase). */ - void drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke); + void drawPath(const GrPaint& paint, const SkPath& path, const GrStrokeInfo& strokeInfo); /** * Draws vertices with a paint. @@ -545,11 +550,12 @@ public: * * @param paint describes how to color pixels. * @param oval the bounding rect of the oval. - * @param stroke the stroke information (width, style) + * @param strokeInfo the stroke information (width, join, cap) and + * the dash information (intervals, count, phase). */ void drawOval(const GrPaint& paint, const SkRect& oval, - const SkStrokeRec& stroke); + const GrStrokeInfo& strokeInfo); /////////////////////////////////////////////////////////////////////////// // Misc. @@ -995,7 +1001,7 @@ private: GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw, AutoRestoreEffects*, AutoCheckFlush*); void internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path, - const SkStrokeRec& stroke); + const GrStrokeInfo& stroke); GrTexture* createResizedTexture(const GrTextureDesc& desc, const GrCacheID& cacheID, diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp index 673cb5ad4a..497b3cfbb8 100644 --- a/src/gpu/GrAARectRenderer.cpp +++ b/src/gpu/GrAARectRenderer.cpp @@ -726,10 +726,10 @@ void GrAARectRenderer::strokeAARect(GrGpu* gpu, const SkRect& rect, const SkMatrix& combinedMatrix, const SkRect& devRect, - const SkStrokeRec* stroke, + const SkStrokeRec& stroke, bool useVertexCoverage) { SkVector devStrokeSize; - SkScalar width = stroke->getWidth(); + SkScalar width = stroke.getWidth(); if (width > 0) { devStrokeSize.set(width, width); combinedMatrix.mapVectors(&devStrokeSize, 1); @@ -763,7 +763,7 @@ void GrAARectRenderer::strokeAARect(GrGpu* gpu, bool miterStroke = true; // small miter limit means right angles show bevel... - if (stroke->getJoin() != SkPaint::kMiter_Join || stroke->getMiter() < SK_ScalarSqrt2) { + if (stroke.getJoin() != SkPaint::kMiter_Join || stroke.getMiter() < SK_ScalarSqrt2) { miterStroke = false; } diff --git a/src/gpu/GrAARectRenderer.h b/src/gpu/GrAARectRenderer.h index 3e7e980e59..faaf7e20be 100644 --- a/src/gpu/GrAARectRenderer.h +++ b/src/gpu/GrAARectRenderer.h @@ -65,7 +65,7 @@ public: const SkRect& rect, const SkMatrix& combinedMatrix, const SkRect& devRect, - const SkStrokeRec* stroke, + const SkStrokeRec& stroke, bool useVertexCoverage); // First rect is outer; second rect is inner diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp index a3e9cb3d79..9747d6a91f 100755 --- a/src/gpu/GrBitmapTextContext.cpp +++ b/src/gpu/GrBitmapTextContext.cpp @@ -10,6 +10,7 @@ #include "GrDrawTarget.h" #include "GrFontScaler.h" #include "GrIndexBuffer.h" +#include "GrStrokeInfo.h" #include "GrTextStrike.h" #include "GrTextStrike_impl.h" #include "SkColorPriv.h" @@ -582,8 +583,8 @@ void GrBitmapTextContext::drawPackedGlyph(GrGlyph::PackedID packed, SkFixedToScalar(vy - SkIntToFixed(glyph->fBounds.fTop))); GrPaint tmpPaint(fPaint); am.setPreConcat(fContext, translate, &tmpPaint); - SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); - fContext->drawPath(tmpPaint, *glyph->fPath, stroke); + GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); + fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo); return; } diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index e8ae18a4e2..b64bf60740 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -25,8 +25,10 @@ #include "GrResourceCache.h" #include "GrSoftwarePathRenderer.h" #include "GrStencilBuffer.h" +#include "GrStrokeInfo.h" #include "GrTextStrike.h" #include "GrTracing.h" +#include "SkDashPathPriv.h" #include "SkGr.h" #include "SkRTConf.h" #include "SkRRect.h" @@ -775,15 +777,22 @@ static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po void GrContext::drawRect(const GrPaint& paint, const SkRect& rect, - const SkStrokeRec* stroke, + const GrStrokeInfo* strokeInfo, const SkMatrix* matrix) { + if (NULL != strokeInfo && strokeInfo->isDashed()) { + SkPath path; + path.addRect(rect); + this->drawPath(paint, path, *strokeInfo); + return; + } + AutoRestoreEffects are; AutoCheckFlush acf(this); GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); GR_CREATE_TRACE_MARKER("GrContext::drawRect", target); - SkScalar width = stroke == NULL ? -1 : stroke->getWidth(); + SkScalar width = NULL == strokeInfo ? -1 : strokeInfo->getStrokeRec().getWidth(); SkMatrix combinedMatrix = target->drawState()->getViewMatrix(); if (NULL != matrix) { combinedMatrix.preConcat(*matrix); @@ -830,6 +839,9 @@ void GrContext::drawRect(const GrPaint& paint, !target->getDrawState().getRenderTarget()->isMultisampled(); bool doAA = needAA && apply_aa_to_rect(target, rect, width, combinedMatrix, &devBoundRect, &useVertexCoverage); + + const SkStrokeRec& strokeRec = strokeInfo->getStrokeRec(); + if (doAA) { GrDrawState::AutoViewMatrixRestore avmr; if (!avmr.setIdentity(target->drawState())) { @@ -838,7 +850,7 @@ void GrContext::drawRect(const GrPaint& paint, if (width >= 0) { fAARectRenderer->strokeAARect(this->getGpu(), target, rect, combinedMatrix, devBoundRect, - stroke, useVertexCoverage); + strokeRec, useVertexCoverage); } else { // filled AA rect fAARectRenderer->fillAARect(this->getGpu(), target, @@ -1006,21 +1018,30 @@ void GrContext::drawVertices(const GrPaint& paint, void GrContext::drawRRect(const GrPaint& paint, const SkRRect& rrect, - const SkStrokeRec& stroke) { + const GrStrokeInfo& strokeInfo) { if (rrect.isEmpty()) { return; } + if (strokeInfo.isDashed()) { + SkPath path; + path.addRRect(rrect); + this->drawPath(paint, path, strokeInfo); + return; + } + AutoRestoreEffects are; AutoCheckFlush acf(this); GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); GR_CREATE_TRACE_MARKER("GrContext::drawRRect", target); - if (!fOvalRenderer->drawRRect(target, this, paint.isAntiAlias(), rrect, stroke)) { + const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); + + if (!fOvalRenderer->drawRRect(target, this, paint.isAntiAlias(), rrect, strokeRec)) { SkPath path; path.addRRect(rrect); - this->internalDrawPath(target, paint.isAntiAlias(), path, stroke); + this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo); } } @@ -1045,7 +1066,7 @@ void GrContext::drawDRRect(const GrPaint& paint, path.addRRect(outer); path.setFillType(SkPath::kEvenOdd_FillType); - SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); + GrStrokeInfo fillRec(SkStrokeRec::kFill_InitStyle); this->internalDrawPath(target, paint.isAntiAlias(), path, fillRec); } } @@ -1054,21 +1075,31 @@ void GrContext::drawDRRect(const GrPaint& paint, void GrContext::drawOval(const GrPaint& paint, const SkRect& oval, - const SkStrokeRec& stroke) { + const GrStrokeInfo& strokeInfo) { if (oval.isEmpty()) { return; } + if (strokeInfo.isDashed()) { + SkPath path; + path.addOval(oval); + this->drawPath(paint, path, strokeInfo); + return; + } + AutoRestoreEffects are; AutoCheckFlush acf(this); GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); GR_CREATE_TRACE_MARKER("GrContext::drawOval", target); - if (!fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), oval, stroke)) { + const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); + + + if (!fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), oval, strokeRec)) { SkPath path; path.addOval(oval); - this->internalDrawPath(target, paint.isAntiAlias(), path, stroke); + this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo); } } @@ -1127,7 +1158,7 @@ static bool is_nested_rects(GrDrawTarget* target, return true; } -void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke) { +void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const GrStrokeInfo& strokeInfo) { if (path.isEmpty()) { if (path.isInverseFillType()) { @@ -1136,6 +1167,20 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrok return; } + if (strokeInfo.isDashed()) { + const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); + SkTLazy<SkPath> effectPath; + GrStrokeInfo newStrokeInfo(strokeInfo, false); + SkStrokeRec* stroke = newStrokeInfo.getStrokeRecPtr(); + if (SkDashPath::FilterDashPath(effectPath.init(), path, stroke, NULL, info)) { + this->drawPath(paint, *effectPath.get(), newStrokeInfo); + return; + } + + this->drawPath(paint, path, newStrokeInfo); + return; + } + // Note that internalDrawPath may sw-rasterize the path into a scratch texture. // Scratch textures can be recycled after they are returned to the texture // cache. This presents a potential hazard for buffered drawing. However, @@ -1148,14 +1193,16 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrok GR_CREATE_TRACE_MARKER("GrContext::drawPath", target); + const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); + bool useCoverageAA = paint.isAntiAlias() && !drawState->getRenderTarget()->isMultisampled(); - if (useCoverageAA && stroke.getWidth() < 0 && !path.isConvex()) { + if (useCoverageAA && strokeRec.getWidth() < 0 && !path.isConvex()) { // Concave AA paths are expensive - try to avoid them for special cases bool useVertexCoverage; SkRect rects[2]; - if (is_nested_rects(target, path, stroke, rects, &useVertexCoverage)) { + if (is_nested_rects(target, path, strokeRec, rects, &useVertexCoverage)) { SkMatrix origViewMatrix = drawState->getViewMatrix(); GrDrawState::AutoViewMatrixRestore avmr; if (!avmr.setIdentity(target->drawState())) { @@ -1174,13 +1221,13 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrok bool isOval = path.isOval(&ovalRect); if (!isOval || path.isInverseFillType() - || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect, stroke)) { - this->internalDrawPath(target, paint.isAntiAlias(), path, stroke); + || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect, strokeRec)) { + this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo); } } void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path, - const SkStrokeRec& origStroke) { + const GrStrokeInfo& strokeInfo) { SkASSERT(!path.isEmpty()); GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target); @@ -1201,7 +1248,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& const SkPath* pathPtr = &path; SkTLazy<SkPath> tmpPath; - SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke); + SkTCopyOnFirstWrite<SkStrokeRec> stroke(strokeInfo.getStrokeRec()); // Try a 1st time without stroking the path and without allowing the SW renderer GrPathRenderer* pr = this->getPathRenderer(*pathPtr, *stroke, target, false, type); diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp index a7299393bd..c79276777d 100755 --- a/src/gpu/GrDistanceFieldTextContext.cpp +++ b/src/gpu/GrDistanceFieldTextContext.cpp @@ -14,6 +14,7 @@ #include "SkGlyphCache.h" #include "GrGpu.h" #include "GrIndexBuffer.h" +#include "GrStrokeInfo.h" #include "GrTextStrike.h" #include "GrTextStrike_impl.h" #include "SkDistanceFieldGen.h" @@ -274,8 +275,8 @@ void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, ctm.postTranslate(sx, sy); GrPaint tmpPaint(fPaint); am.setPreConcat(fContext, ctm, &tmpPaint); - SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); - fContext->drawPath(tmpPaint, *glyph->fPath, stroke); + GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); + fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo); return; } diff --git a/src/gpu/GrStrokeInfo.h b/src/gpu/GrStrokeInfo.h new file mode 100644 index 0000000000..b96ed39096 --- /dev/null +++ b/src/gpu/GrStrokeInfo.h @@ -0,0 +1,88 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrStrokeInfo_DEFINED +#define GrStrokeInfo_DEFINED + +#include "SkStrokeRec.h" +#include "SkPathEffect.h" + +/* + * GrStrokeInfo encapsulates the data objects that hold all the pertinent infomation + * regarding the stroke. The two objects are SkStrokeRec which holds information on fill style, + * width, miter, cap, and join. The second object is DashInfo. This holds information about the + * dash like intervals, count, and phase. + */ +class GrStrokeInfo { +public: + GrStrokeInfo(SkStrokeRec::InitStyle style) : + fStroke(style), fDashType(SkPathEffect::kNone_DashType) {} + + GrStrokeInfo(const GrStrokeInfo& src, bool includeDash = true) : fStroke(src.fStroke) { + if (includeDash) { + fDashInfo = src.fDashInfo; + fDashType = src.fDashType; + fIntervals.reset(src.dashCount()); + memcpy(fIntervals.get(), src.fIntervals.get(), src.dashCount() * sizeof(SkScalar)); + } else { + fDashType = SkPathEffect::kNone_DashType; + } + } + + explicit GrStrokeInfo(const SkPaint& paint) : + fStroke(paint), fDashType(SkPathEffect::kNone_DashType) { + const SkPathEffect* pe = paint.getPathEffect(); + this->setDashInfo(pe); + } + + const SkStrokeRec& getStrokeRec() const { return fStroke; } + + SkStrokeRec* getStrokeRecPtr() { return &fStroke; } + + void setFillStyle() { fStroke.setFillStyle(); } + + /* + * This functions takes in a patheffect and fills in fDashInfo with the various dashing + * information if the path effect is a Dash type. Returns true if the path effect is a + * dashed effect and we are stroking, otherwise it retruns false. + */ + bool setDashInfo(const SkPathEffect* pe) { + if (NULL != pe && !fStroke.isFillStyle()) { + fDashInfo.fIntervals = NULL; + fDashType = pe->asADash(&fDashInfo); + if (SkPathEffect::kDash_DashType == fDashType) { + fIntervals.reset(fDashInfo.fCount); + fDashInfo.fIntervals = fIntervals.get(); + pe->asADash(&fDashInfo); + return true; + } + } + return false; + } + + bool isDashed() const { + return (!fStroke.isFillStyle() && SkPathEffect::kDash_DashType == fDashType); + } + + int32_t dashCount() const { + return fDashInfo.fCount; + } + + void removeDash() { + fDashType = SkPathEffect::kNone_DashType; + } + + const SkPathEffect::DashInfo& getDashInfo() const { return fDashInfo; } + +private: + SkStrokeRec fStroke; + SkPathEffect::DashType fDashType; + SkPathEffect::DashInfo fDashInfo; + SkAutoSTArray<2, SkScalar> fIntervals; +}; + +#endif diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 7c66fa96fa..288ea5ae6d 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -17,6 +17,7 @@ #include "GrDistanceFieldTextContext.h" #include "GrLayerCache.h" #include "GrPictureUtils.h" +#include "GrStrokeInfo.h" #include "SkGrTexturePixelRef.h" @@ -428,9 +429,11 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, (paint.getStrokeJoin() == SkPaint::kRound_Join || (paint.getStrokeJoin() == SkPaint::kBevel_Join && rect.isEmpty())); // another two reasons we might need to call drawPath... - if (paint.getMaskFilter() || paint.getPathEffect()) { + + if (paint.getMaskFilter()) { usePath = true; } + if (!usePath && paint.isAntiAlias() && !fContext->getMatrix().rectStaysRect()) { #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) if (doStroke) { @@ -447,6 +450,13 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, usePath = true; } + GrStrokeInfo strokeInfo(paint); + + const SkPathEffect* pe = paint.getPathEffect(); + if (!usePath && NULL != pe && !strokeInfo.isDashed()) { + usePath = true; + } + if (usePath) { SkPath path; path.addRect(rect); @@ -456,13 +466,8 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, GrPaint grPaint; SkPaint2GrPaintShader(this->context(), paint, true, &grPaint); - - if (!doStroke) { - fContext->drawRect(grPaint, rect); - } else { - SkStrokeRec stroke(paint); - fContext->drawRect(grPaint, rect, &stroke); - } + + fContext->drawRect(grPaint, rect, &strokeInfo); } /////////////////////////////////////////////////////////////////////////////// @@ -474,8 +479,8 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect, GrPaint grPaint; SkPaint2GrPaintShader(this->context(), paint, true, &grPaint); - - SkStrokeRec stroke(paint); + + GrStrokeInfo strokeInfo(paint); if (paint.getMaskFilter()) { // try to hit the fast path for drawing filtered round rects @@ -494,7 +499,8 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect, return; } if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext, &grPaint, - stroke, devRRect)) { + strokeInfo.getStrokeRec(), + devRRect)) { return; } } @@ -504,14 +510,26 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect, } - if (paint.getMaskFilter() || paint.getPathEffect()) { + bool usePath = false; + + if (paint.getMaskFilter()) { + usePath = true; + } else { + const SkPathEffect* pe = paint.getPathEffect(); + if (NULL != pe && !strokeInfo.isDashed()) { + usePath = true; + } + } + + + if (usePath) { SkPath path; path.addRRect(rect); this->drawPath(draw, path, paint, NULL, true); return; } - - fContext->drawRRect(grPaint, rect, stroke); + + fContext->drawRRect(grPaint, rect, strokeInfo); } void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer, @@ -547,10 +565,17 @@ void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, CHECK_FOR_ANNOTATION(paint); CHECK_SHOULD_DRAW(draw, false); + GrStrokeInfo strokeInfo(paint); + bool usePath = false; // some basic reasons we might need to call drawPath... - if (paint.getMaskFilter() || paint.getPathEffect()) { + if (paint.getMaskFilter()) { usePath = true; + } else { + const SkPathEffect* pe = paint.getPathEffect(); + if (NULL != pe && !strokeInfo.isDashed()) { + usePath = true; + } } if (usePath) { @@ -562,9 +587,8 @@ void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, GrPaint grPaint; SkPaint2GrPaintShader(this->context(), paint, true, &grPaint); - SkStrokeRec stroke(paint); - fContext->drawOval(grPaint, oval, stroke); + fContext->drawOval(grPaint, oval, strokeInfo); } #include "SkMaskFilter.h" @@ -640,7 +664,7 @@ bool draw_with_mask_filter(GrContext* context, const SkPath& devPath, bool create_mask_GPU(GrContext* context, const SkRect& maskRect, const SkPath& devPath, - const SkStrokeRec& stroke, + const GrStrokeInfo& strokeInfo, bool doAA, GrAutoScratchTexture* mask) { GrTextureDesc desc; @@ -685,7 +709,7 @@ bool create_mask_GPU(GrContext* context, SkMatrix translate; translate.setTranslate(-maskRect.fLeft, -maskRect.fTop); am.set(context, translate); - context->drawPath(tempPaint, devPath, stroke); + context->drawPath(tempPaint, devPath, strokeInfo); return true; } @@ -729,22 +753,25 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, // at this point we're done with prePathMatrix SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;) - SkStrokeRec stroke(paint); + GrStrokeInfo strokeInfo(paint); SkPathEffect* pathEffect = paint.getPathEffect(); const SkRect* cullRect = NULL; // TODO: what is our bounds? - if (pathEffect && pathEffect->filterPath(effectPath.init(), *pathPtr, &stroke, + SkStrokeRec* strokePtr = strokeInfo.getStrokeRecPtr(); + if (pathEffect && pathEffect->filterPath(effectPath.init(), *pathPtr, strokePtr, cullRect)) { pathPtr = effectPath.get(); pathIsMutable = true; + strokeInfo.removeDash(); } + const SkStrokeRec& stroke = strokeInfo.getStrokeRec(); if (paint.getMaskFilter()) { if (!stroke.isHairlineStyle()) { SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init(); if (stroke.applyToPath(strokedPath, *pathPtr)) { pathPtr = strokedPath; pathIsMutable = true; - stroke.setFillStyle(); + strokeInfo.setFillStyle(); } } @@ -779,7 +806,7 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, GrAutoScratchTexture mask; - if (create_mask_GPU(fContext, maskRect, *devPathPtr, stroke, + if (create_mask_GPU(fContext, maskRect, *devPathPtr, strokeInfo, grPaint.isAntiAlias(), &mask)) { GrTexture* filtered; @@ -808,12 +835,12 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, // GPU path fails SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style : SkPaint::kFill_Style; - draw_with_mask_filter(fContext, *devPathPtr, paint.getMaskFilter(), *draw.fClip, &grPaint, - style); + draw_with_mask_filter(fContext, *devPathPtr, paint.getMaskFilter(), + *draw.fClip, &grPaint, style); return; } - fContext->drawPath(grPaint, *pathPtr, stroke); + fContext->drawPath(grPaint, *pathPtr, strokeInfo); } static const int kBmpSmallTileSize = 1 << 10; |