Index: src/gpu/effects/GrDashingEffect.cpp |
diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp |
index 3b06c3a52312fa77982324c03483260d9a872b73..8d9c08f3f38d943c34fec4698a3caa6886a322cc 100644 |
--- a/src/gpu/effects/GrDashingEffect.cpp |
+++ b/src/gpu/effects/GrDashingEffect.cpp |
@@ -7,17 +7,73 @@ |
#include "GrDashingEffect.h" |
+#include "../GrAARectRenderer.h" |
+ |
+#include "effects/GrVertexEffect.h" |
#include "gl/GrGLEffect.h" |
+#include "gl/GrGLVertexEffect.h" |
#include "gl/GrGLSL.h" |
#include "GrContext.h" |
#include "GrCoordTransform.h" |
+#include "GrDrawTarget.h" |
#include "GrDrawTargetCaps.h" |
#include "GrEffect.h" |
+#include "GrGpu.h" |
+#include "GrStrokeInfo.h" |
#include "GrTBackendEffectFactory.h" |
#include "SkGr.h" |
/////////////////////////////////////////////////////////////////////////////// |
+// Returns whether or not the gpu can fast path the dash line effect. |
+static bool can_fast_path_dash(const SkPoint pts[2], const GrStrokeInfo& strokeInfo, |
+ const GrDrawTarget& target, const SkMatrix& viewMatrix) { |
+ if (target.getDrawState().getRenderTarget()->isMultisampled()) { |
+ return false; |
+ } |
+ |
+ // Pts must be either horizontal or vertical in src space |
+ if (pts[0].fX != pts[1].fX && pts[0].fY != pts[1].fY) { |
+ return false; |
+ } |
+ |
+ // May be able to relax this to include skew. As of now cannot do perspective |
+ // because of the non uniform scaling of bloating a rect |
+ if (!viewMatrix.preservesRightAngles()) { |
+ return false; |
+ } |
+ |
+ if (!strokeInfo.isDashed() || 2 != strokeInfo.dashCount()) { |
+ return false; |
+ } |
+ |
+ const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); |
+ if (0 == info.fIntervals[0] && 0 == info.fIntervals[1]) { |
+ return false; |
+ } |
+ |
+ SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); |
+ // Current we do don't handle Round or Square cap dashes |
+ if (SkPaint::kRound_Cap == cap) { |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+namespace { |
+ |
+struct DashLineVertex { |
+ SkPoint fPos; |
+ SkPoint fDashPos; |
+}; |
+ |
+extern const GrVertexAttrib gDashLineVertexAttribs[] = { |
+ { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, |
+ { kVec2f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding }, |
+}; |
+ |
+}; |
static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale, |
const SkMatrix& viewMatrix, const SkPoint pts[2]) { |
SkVector vecSrc = pts[1] - pts[0]; |
@@ -62,7 +118,8 @@ static SkScalar calc_start_adjustment(const SkPathEffect::DashInfo& info) { |
return 0; |
} |
-static SkScalar calc_end_adjustment(const SkPathEffect::DashInfo& info, const SkPoint pts[2], SkScalar* endingInt) { |
+static SkScalar calc_end_adjustment(const SkPathEffect::DashInfo& info, const SkPoint pts[2], |
+ SkScalar phase, SkScalar* endingInt) { |
if (pts[1].fX <= pts[0].fX) { |
return 0; |
} |
@@ -70,7 +127,7 @@ static SkScalar calc_end_adjustment(const SkPathEffect::DashInfo& info, const Sk |
SkScalar totalLen = pts[1].fX - pts[0].fX; |
SkScalar temp = SkScalarDiv(totalLen, srcIntervalLen); |
SkScalar numFullIntervals = SkScalarFloorToScalar(temp); |
- *endingInt = totalLen - numFullIntervals * srcIntervalLen + info.fPhase; |
+ *endingInt = totalLen - numFullIntervals * srcIntervalLen + phase; |
temp = SkScalarDiv(*endingInt, srcIntervalLen); |
*endingInt = *endingInt - SkScalarFloorToScalar(temp) * srcIntervalLen; |
if (0 == *endingInt) { |
@@ -85,188 +142,263 @@ static SkScalar calc_end_adjustment(const SkPathEffect::DashInfo& info, const Sk |
return 0; |
} |
+static void setup_dashed_rect(const SkRect& rect, DashLineVertex* verts, int idx, const SkMatrix& matrix, |
+ SkScalar offset, SkScalar bloat, SkScalar len, SkScalar stroke) { |
-bool GrDashingEffect::DrawDashLine(const SkPoint pts[2], const SkPaint& paint, GrContext* context) { |
- if (context->getRenderTarget()->isMultisampled()) { |
- return false; |
- } |
+ SkScalar startDashX = offset - bloat; |
+ SkScalar endDashX = offset + len + bloat; |
+ SkScalar startDashY = -stroke - bloat; |
+ SkScalar endDashY = stroke + bloat; |
+ verts[idx].fDashPos = SkPoint::Make(startDashX , startDashY); |
+ verts[idx + 1].fDashPos = SkPoint::Make(startDashX, endDashY); |
+ verts[idx + 2].fDashPos = SkPoint::Make(endDashX, endDashY); |
+ verts[idx + 3].fDashPos = SkPoint::Make(endDashX, startDashY); |
- const SkMatrix& viewMatrix = context->getMatrix(); |
- if (!viewMatrix.preservesRightAngles()) { |
- return false; |
- } |
+ verts[idx].fPos = SkPoint::Make(rect.fLeft, rect.fTop); |
+ verts[idx + 1].fPos = SkPoint::Make(rect.fLeft, rect.fBottom); |
+ verts[idx + 2].fPos = SkPoint::Make(rect.fRight, rect.fBottom); |
+ verts[idx + 3].fPos = SkPoint::Make(rect.fRight, rect.fTop); |
- const SkPathEffect* pe = paint.getPathEffect(); |
- SkPathEffect::DashInfo info; |
- SkPathEffect::DashType dashType = pe->asADash(&info); |
- // Must be a dash effect with 2 intervals (1 on and 1 off) |
- if (SkPathEffect::kDash_DashType != dashType || 2 != info.fCount) { |
- return false; |
- } |
+ matrix.mapPointsWithStride(&verts[idx].fPos, sizeof(DashLineVertex), 4); |
+} |
- SkPaint::Cap cap = paint.getStrokeCap(); |
- // Current we do don't handle Round or Square cap dashes |
- if (SkPaint::kRound_Cap == cap) { |
+ |
+bool GrDashingEffect::DrawDashLine(const SkPoint pts[2], const GrPaint& paint, |
+ const GrStrokeInfo& strokeInfo, GrGpu* gpu, |
+ GrDrawTarget* target, const SkMatrix& vm) { |
+ |
+ if (!can_fast_path_dash(pts, strokeInfo, *target, vm)) { |
return false; |
} |
- SkScalar srcStrokeWidth = paint.getStrokeWidth(); |
+ const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); |
- // Get all info about the dash effect |
- SkAutoTArray<SkScalar> intervals(info.fCount); |
- info.fIntervals = intervals.get(); |
- pe->asADash(&info); |
+ SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); |
+ |
+ SkScalar srcStrokeWidth = strokeInfo.getStrokeRec().getWidth(); |
// the phase should be normalized to be [0, sum of all intervals) |
SkASSERT(info.fPhase >= 0 && info.fPhase < info.fIntervals[0] + info.fIntervals[1]); |
- SkMatrix coordTrans; |
+ SkScalar srcPhase = info.fPhase; |
// Rotate the src pts so they are aligned horizontally with pts[0].fX < pts[1].fX |
SkMatrix srcRotInv; |
SkPoint ptsRot[2]; |
if (pts[0].fY != pts[1].fY || pts[0].fX > pts[1].fX) { |
- align_to_x_axis(pts, &coordTrans, ptsRot); |
- if(!coordTrans.invert(&srcRotInv)) { |
+ SkMatrix rotMatrix; |
+ align_to_x_axis(pts, &rotMatrix, ptsRot); |
+ if(!rotMatrix.invert(&srcRotInv)) { |
+ GrPrintf("Failed to create invertible rotation matrix!\n"); |
return false; |
} |
} else { |
- coordTrans.reset(); |
srcRotInv.reset(); |
memcpy(ptsRot, pts, 2 * sizeof(SkPoint)); |
} |
- GrPaint grPaint; |
- SkPaint2GrPaintShader(context, paint, true, &grPaint); |
- |
bool useAA = paint.isAntiAlias(); |
// Scale corrections of intervals and stroke from view matrix |
SkScalar parallelScale; |
SkScalar perpScale; |
- calc_dash_scaling(¶llelScale, &perpScale, viewMatrix, ptsRot); |
+ calc_dash_scaling(¶llelScale, &perpScale, vm, ptsRot); |
bool hasCap = SkPaint::kSquare_Cap == cap && 0 != srcStrokeWidth; |
// We always want to at least stroke out half a pixel on each side in device space |
// so 0.5f / perpScale gives us this min in src space |
- SkScalar halfStroke = SkMaxScalar(srcStrokeWidth * 0.5f, 0.5f / perpScale); |
+ SkScalar halfSrcStroke = SkMaxScalar(srcStrokeWidth * 0.5f, 0.5f / perpScale); |
- SkScalar xStroke; |
+ SkScalar strokeAdj; |
if (!hasCap) { |
- xStroke = 0.f; |
+ strokeAdj = 0.f; |
} else { |
- xStroke = halfStroke; |
+ strokeAdj = halfSrcStroke; |
} |
+ SkScalar startAdj = 0; |
+ |
+ SkMatrix combinedMatrix = srcRotInv; |
+ combinedMatrix.postConcat(vm); |
+ |
+ bool lineDone = false; |
+ SkRect startRect; |
+ bool hasStartRect = false; |
// If we are using AA, check to see if we are drawing a partial dash at the start. If so |
// draw it separately here and adjust our start point accordingly |
if (useAA) { |
- if (info.fPhase > 0 && info.fPhase < info.fIntervals[0]) { |
+ if (srcPhase > 0 && srcPhase < info.fIntervals[0]) { |
SkPoint startPts[2]; |
startPts[0] = ptsRot[0]; |
startPts[1].fY = startPts[0].fY; |
- startPts[1].fX = SkMinScalar(startPts[0].fX + info.fIntervals[0] - info.fPhase, |
+ startPts[1].fX = SkMinScalar(startPts[0].fX + info.fIntervals[0] - srcPhase, |
ptsRot[1].fX); |
- SkRect startRect; |
startRect.set(startPts, 2); |
- startRect.outset(xStroke, halfStroke); |
- context->drawRect(grPaint, startRect, NULL, &srcRotInv); |
+ startRect.outset(strokeAdj, halfSrcStroke); |
- ptsRot[0].fX += info.fIntervals[0] + info.fIntervals[1] - info.fPhase; |
- info.fPhase = 0; |
+ hasStartRect = true; |
+ startAdj = info.fIntervals[0] + info.fIntervals[1] - srcPhase; |
} |
} |
// adjustments for start and end of bounding rect so we only draw dash intervals |
// contained in the original line segment. |
- SkScalar startAdj = calc_start_adjustment(info); |
+ startAdj += calc_start_adjustment(info); |
+ if (startAdj != 0) { |
+ ptsRot[0].fX += startAdj; |
+ srcPhase = 0; |
+ } |
SkScalar endingInterval = 0; |
- SkScalar endAdj = calc_end_adjustment(info, ptsRot, &endingInterval); |
- if (ptsRot[0].fX + startAdj >= ptsRot[1].fX - endAdj) { |
- // Nothing left to draw so just return |
- return true; |
+ SkScalar endAdj = calc_end_adjustment(info, ptsRot, srcPhase, &endingInterval); |
+ ptsRot[1].fX -= endAdj; |
+ if (ptsRot[0].fX >= ptsRot[1].fX) { |
+ lineDone = true; |
} |
+ SkRect endRect; |
+ bool hasEndRect = false; |
// If we are using AA, check to see if we are drawing a partial dash at then end. If so |
// draw it separately here and adjust our end point accordingly |
- if (useAA) { |
+ if (useAA && !lineDone) { |
// If we adjusted the end then we will not be drawing a partial dash at the end. |
// If we didn't adjust the end point then we just need to make sure the ending |
// dash isn't a full dash |
if (0 == endAdj && endingInterval != info.fIntervals[0]) { |
- |
SkPoint endPts[2]; |
endPts[1] = ptsRot[1]; |
endPts[0].fY = endPts[1].fY; |
endPts[0].fX = endPts[1].fX - endingInterval; |
- SkRect endRect; |
endRect.set(endPts, 2); |
- endRect.outset(xStroke, halfStroke); |
- context->drawRect(grPaint, endRect, NULL, &srcRotInv); |
+ endRect.outset(strokeAdj, halfSrcStroke); |
+ |
+ hasEndRect = true; |
+ endAdj = endingInterval + info.fIntervals[1]; |
- ptsRot[1].fX -= endingInterval + info.fIntervals[1]; |
+ ptsRot[1].fX -= endAdj; |
if (ptsRot[0].fX >= ptsRot[1].fX) { |
- // Nothing left to draw so just return |
- return true; |
+ lineDone = true; |
} |
} |
} |
- coordTrans.postConcat(viewMatrix); |
- SkPoint devicePts[2]; |
- viewMatrix.mapPoints(devicePts, ptsRot, 2); |
+ if (startAdj != 0) { |
+ srcPhase = 0; |
+ } |
- info.fIntervals[0] *= parallelScale; |
- info.fIntervals[1] *= parallelScale; |
- info.fPhase *= parallelScale; |
+ // Change the dashing info from src space into device space |
+ SkScalar devIntervals[2]; |
+ devIntervals[0] = info.fIntervals[0] * parallelScale; |
+ devIntervals[1] = info.fIntervals[1] * parallelScale; |
+ SkScalar devPhase = srcPhase * parallelScale; |
SkScalar strokeWidth = srcStrokeWidth * perpScale; |
if ((strokeWidth < 1.f && !useAA) || 0.f == strokeWidth) { |
strokeWidth = 1.f; |
} |
- // Set up coordTransform for device space transforms |
- // We rotate the dashed line such that it is horizontal with the start point at smaller x |
- // then we translate the start point to the origin |
- if (devicePts[0].fY != devicePts[1].fY || devicePts[0].fX > devicePts[1].fX) { |
- SkMatrix rot; |
- align_to_x_axis(devicePts, &rot); |
- coordTrans.postConcat(rot); |
- } |
- coordTrans.postTranslate(-devicePts[0].fX, -devicePts[0].fY); |
- coordTrans.postTranslate(info.fIntervals[1] * 0.5f + info.fPhase, 0); |
+ SkScalar halfDevStroke = strokeWidth * 0.5f; |
if (SkPaint::kSquare_Cap == cap && 0 != srcStrokeWidth) { |
// add cap to on interveal and remove from off interval |
- info.fIntervals[0] += strokeWidth; |
- info.fIntervals[1] -= strokeWidth; |
+ devIntervals[0] += strokeWidth; |
+ devIntervals[1] -= strokeWidth; |
} |
- |
- if (info.fIntervals[1] > 0.f) { |
+ SkScalar startOffset = devIntervals[1] * 0.5f + devPhase; |
+ |
+ SkScalar bloatX = useAA ? 0.5f / parallelScale : 0.f; |
+ SkScalar bloatY = useAA ? 0.5f / perpScale : 0.f; |
+ |
+ SkScalar devBloat = useAA ? 0.5f : 0.f; |
+ |
+ GrDrawState* drawState = target->drawState(); |
+ if (devIntervals[1] <= 0.f && useAA) { |
+ // Case when we end up drawing a solid AA rect |
+ // Reset the start rect to draw this single solid rect |
+ // but it requires to upload a new intervals uniform so we can mimic |
+ // one giant dash |
+ ptsRot[0].fX -= hasStartRect ? startAdj : 0; |
+ ptsRot[1].fX += hasEndRect ? endAdj : 0; |
+ startRect.set(ptsRot, 2); |
+ startRect.outset(strokeAdj, halfSrcStroke); |
+ hasStartRect = true; |
+ hasEndRect = false; |
+ lineDone = true; |
+ |
+ SkPoint devicePts[2]; |
+ vm.mapPoints(devicePts, ptsRot, 2); |
+ SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); |
+ if (hasCap) { |
+ lineLength += 2.f * halfDevStroke; |
+ } |
+ devIntervals[0] = lineLength; |
+ } |
+ if (devIntervals[1] > 0.f || useAA) { |
+ SkPathEffect::DashInfo devInfo; |
+ devInfo.fPhase = devPhase; |
+ devInfo.fCount = 2; |
+ devInfo.fIntervals = devIntervals; |
GrEffectEdgeType edgeType= useAA ? kFillAA_GrEffectEdgeType : |
kFillBW_GrEffectEdgeType; |
- grPaint.addCoverageEffect( |
- GrDashingEffect::Create(edgeType, info, coordTrans, strokeWidth))->unref(); |
- grPaint.setAntiAlias(false); |
+ drawState->addCoverageEffect( |
+ GrDashingEffect::Create(edgeType, devInfo, strokeWidth), 1)->unref(); |
} |
- SkRect rect; |
- bool bloat = useAA && info.fIntervals[1] > 0.f; |
- SkScalar bloatX = bloat ? 0.5f / parallelScale : 0.f; |
- SkScalar bloatY = bloat ? 0.5f / perpScale : 0.f; |
- ptsRot[0].fX += startAdj; |
- ptsRot[1].fX -= endAdj; |
- if (!hasCap) { |
- xStroke = 0.f; |
- } else { |
- xStroke = halfStroke; |
+ // Set up the vertex data for the line and start/end dashes |
+ drawState->setVertexAttribs<gDashLineVertexAttribs>(SK_ARRAY_COUNT(gDashLineVertexAttribs)); |
+ |
+ int totalRectCnt = 0; |
+ |
+ totalRectCnt += !lineDone ? 1 : 0; |
+ totalRectCnt += hasStartRect ? 1 : 0; |
+ totalRectCnt += hasEndRect ? 1 : 0; |
+ |
+ GrDrawTarget::AutoReleaseGeometry geo(target, totalRectCnt * 4, 0); |
+ if (!geo.succeeded()) { |
+ GrPrintf("Failed to get space for vertices!\n"); |
+ return false; |
} |
- rect.set(ptsRot, 2); |
- rect.outset(bloatX + xStroke, bloatY + halfStroke); |
- context->drawRect(grPaint, rect, NULL, &srcRotInv); |
+ DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertices()); |
+ |
+ int curVIdx = 0; |
+ |
+ // Draw interior part of dashed line |
+ if (!lineDone) { |
+ SkPoint devicePts[2]; |
+ vm.mapPoints(devicePts, ptsRot, 2); |
+ SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); |
+ if (hasCap) { |
+ lineLength += 2.f * halfDevStroke; |
+ } |
+ |
+ SkRect bounds; |
+ bounds.set(ptsRot[0].fX, ptsRot[0].fY, ptsRot[1].fX, ptsRot[1].fY); |
+ bounds.outset(bloatX + strokeAdj, bloatY + halfSrcStroke); |
+ setup_dashed_rect(bounds, verts, curVIdx, combinedMatrix, startOffset, devBloat, |
+ lineLength, halfDevStroke); |
+ curVIdx += 4; |
+ } |
+ |
+ if (hasStartRect) { |
+ SkASSERT(useAA); // so that we know bloatX and bloatY have been set |
+ startRect.outset(bloatX, bloatY); |
+ setup_dashed_rect(startRect, verts, curVIdx, combinedMatrix, startOffset, devBloat, |
+ devIntervals[0], halfDevStroke); |
+ curVIdx += 4; |
+ } |
+ |
+ if (hasEndRect) { |
+ SkASSERT(useAA); // so that we know bloatX and bloatY have been set |
+ endRect.outset(bloatX, bloatY); |
+ setup_dashed_rect(endRect, verts, curVIdx, combinedMatrix, startOffset, devBloat, |
+ devIntervals[0], halfDevStroke); |
+ } |
+ |
+ target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer()); |
+ target->drawIndexedInstances(kTriangles_GrPrimitiveType, totalRectCnt, 4, 6); |
+ target->resetIndexSource(); |
return true; |
} |
@@ -274,7 +406,7 @@ bool GrDashingEffect::DrawDashLine(const SkPoint pts[2], const SkPaint& paint, G |
class GLDashingLineEffect; |
-class DashingLineEffect : public GrEffect { |
+class DashingLineEffect : public GrVertexEffect { |
public: |
typedef SkPathEffect::DashInfo DashInfo; |
@@ -286,7 +418,7 @@ public: |
* and half the off interval. |
*/ |
static GrEffectRef* Create(GrEffectEdgeType edgeType, const DashInfo& info, |
- const SkMatrix& matrix, SkScalar strokeWidth); |
+ SkScalar strokeWidth); |
virtual ~DashingLineEffect(); |
@@ -305,13 +437,11 @@ public: |
virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
private: |
- DashingLineEffect(GrEffectEdgeType edgeType, const DashInfo& info, const SkMatrix& matrix, |
- SkScalar strokeWidth); |
+ DashingLineEffect(GrEffectEdgeType edgeType, const DashInfo& info, SkScalar strokeWidth); |
virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; |
GrEffectEdgeType fEdgeType; |
- GrCoordTransform fCoordTransform; |
SkRect fRect; |
SkScalar fIntervalLength; |
@@ -322,11 +452,11 @@ private: |
////////////////////////////////////////////////////////////////////////////// |
-class GLDashingLineEffect : public GrGLEffect { |
+class GLDashingLineEffect : public GrGLVertexEffect { |
public: |
GLDashingLineEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
- virtual void emitCode(GrGLShaderBuilder* builder, |
+ virtual void emitCode(GrGLFullShaderBuilder* builder, |
const GrDrawEffect& drawEffect, |
EffectKey key, |
const char* outputColor, |
@@ -343,7 +473,7 @@ private: |
GrGLUniformManager::UniformHandle fIntervalUniform; |
SkRect fPrevRect; |
SkScalar fPrevIntervalLength; |
- typedef GrGLEffect INHERITED; |
+ typedef GrGLVertexEffect INHERITED; |
}; |
GLDashingLineEffect::GLDashingLineEffect(const GrBackendEffectFactory& factory, |
@@ -354,12 +484,12 @@ GLDashingLineEffect::GLDashingLineEffect(const GrBackendEffectFactory& factory, |
} |
-void GLDashingLineEffect::emitCode(GrGLShaderBuilder* builder, |
+void GLDashingLineEffect::emitCode(GrGLFullShaderBuilder* builder, |
const GrDrawEffect& drawEffect, |
EffectKey key, |
const char* outputColor, |
const char* inputColor, |
- const TransformedCoordsArray& coords, |
+ const TransformedCoordsArray&, |
const TextureSamplerArray& samplers) { |
const DashingLineEffect& de = drawEffect.castEffect<DashingLineEffect>(); |
const char *rectName; |
@@ -375,10 +505,17 @@ void GLDashingLineEffect::emitCode(GrGLShaderBuilder* builder, |
kFloat_GrSLType, |
"interval", |
&intervalName); |
+ |
+ const char *vsCoordName, *fsCoordName; |
+ builder->addVarying(kVec2f_GrSLType, "Coord", &vsCoordName, &fsCoordName); |
+ const SkString* attr0Name = |
+ builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); |
+ builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attr0Name->c_str()); |
+ |
// transforms all points so that we can compare them to our test rect |
builder->fsCodeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n", |
- coords[0].c_str(), coords[0].c_str(), intervalName, intervalName); |
- builder->fsCodeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", coords[0].c_str()); |
+ fsCoordName, fsCoordName, intervalName, intervalName); |
+ builder->fsCodeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName); |
if (GrEffectEdgeTypeIsAA(de.getEdgeType())) { |
// The amount of coverage removed in x and y by the edges is computed as a pair of negative |
// numbers, xSub and ySub. |
@@ -422,13 +559,13 @@ GrGLEffect::EffectKey GLDashingLineEffect::GenKey(const GrDrawEffect& drawEffect |
////////////////////////////////////////////////////////////////////////////// |
GrEffectRef* DashingLineEffect::Create(GrEffectEdgeType edgeType, const DashInfo& info, |
- const SkMatrix& matrix, SkScalar strokeWidth) { |
+ SkScalar strokeWidth) { |
if (info.fCount != 2) { |
return NULL; |
} |
return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(DashingLineEffect, |
- (edgeType, info, matrix, strokeWidth)))); |
+ (edgeType, info, strokeWidth)))); |
} |
DashingLineEffect::~DashingLineEffect() {} |
@@ -442,9 +579,8 @@ const GrBackendEffectFactory& DashingLineEffect::getFactory() const { |
} |
DashingLineEffect::DashingLineEffect(GrEffectEdgeType edgeType, const DashInfo& info, |
- const SkMatrix& matrix, SkScalar strokeWidth) |
- : fEdgeType(edgeType) |
- , fCoordTransform(kLocal_GrCoordSet, matrix) { |
+ SkScalar strokeWidth) |
+ : fEdgeType(edgeType) { |
SkScalar onLen = info.fIntervals[0]; |
SkScalar offLen = info.fIntervals[1]; |
SkScalar halfOffLen = SkScalarHalf(offLen); |
@@ -452,13 +588,12 @@ DashingLineEffect::DashingLineEffect(GrEffectEdgeType edgeType, const DashInfo& |
fIntervalLength = onLen + offLen; |
fRect.set(halfOffLen, -halfStroke, halfOffLen + onLen, halfStroke); |
- addCoordTransform(&fCoordTransform); |
+ this->addVertexAttrib(kVec2f_GrSLType); |
} |
bool DashingLineEffect::onIsEqual(const GrEffect& other) const { |
const DashingLineEffect& de = CastEffect<DashingLineEffect>(other); |
return (fEdgeType == de.fEdgeType && |
- fCoordTransform == de.fCoordTransform && |
fRect == de.fRect && |
fIntervalLength == de.fIntervalLength); |
} |
@@ -470,8 +605,6 @@ GrEffectRef* DashingLineEffect::TestCreate(SkRandom* random, |
const GrDrawTargetCaps& caps, |
GrTexture*[]) { |
GrEffectRef* effect; |
- SkMatrix m; |
- m.reset(); |
GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(random->nextULessThan( |
kGrEffectEdgeTypeCnt)); |
SkScalar strokeWidth = random->nextRangeScalar(0, 100.f); |
@@ -483,13 +616,13 @@ GrEffectRef* DashingLineEffect::TestCreate(SkRandom* random, |
info.fIntervals[1] = random->nextRangeScalar(0, 10.f); |
info.fPhase = random->nextRangeScalar(0, info.fIntervals[0] + info.fIntervals[1]); |
- effect = DashingLineEffect::Create(edgeType, info, m, strokeWidth); |
+ effect = DashingLineEffect::Create(edgeType, info, strokeWidth); |
return effect; |
} |
////////////////////////////////////////////////////////////////////////////// |
GrEffectRef* GrDashingEffect::Create(GrEffectEdgeType edgeType, const SkPathEffect::DashInfo& info, |
- const SkMatrix& matrix, SkScalar strokeWidth) { |
- return DashingLineEffect::Create(edgeType, info, matrix, strokeWidth); |
+ SkScalar strokeWidth) { |
+ return DashingLineEffect::Create(edgeType, info, strokeWidth); |
} |