aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar egdaniel <egdaniel@google.com>2014-06-11 10:30:05 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-06-11 10:30:05 -0700
commitd58a0ba9cff9fcefe5047e88ccb4a6e76c591c40 (patch)
tree76bf2e32924ec9a1988e68c226eb0c22d017848b
parent9b7906672eb6794497d560761aa8bab824a13a90 (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.gypi1
-rw-r--r--include/gpu/GrContext.h26
-rw-r--r--src/gpu/GrAARectRenderer.cpp6
-rw-r--r--src/gpu/GrAARectRenderer.h2
-rwxr-xr-xsrc/gpu/GrBitmapTextContext.cpp5
-rw-r--r--src/gpu/GrContext.cpp81
-rwxr-xr-xsrc/gpu/GrDistanceFieldTextContext.cpp5
-rw-r--r--src/gpu/GrStrokeInfo.h88
-rw-r--r--src/gpu/SkGpuDevice.cpp79
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;