| Index: src/gpu/GrContext.cpp
|
| diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
|
| index e8ae18a4e225594c8da0dccf84ede68b454f3a3e..b64bf60740326d66effed290171df04a4588c7e0 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);
|
|
|