Index: src/gpu/effects/GrDashingEffect.cpp |
diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp |
index 77d29cba26f99b64113dca6d1553dec7cabd65f5..e62ede0a33c1e9cc9b01f6ea459c211542aff47d 100644 |
--- a/src/gpu/effects/GrDashingEffect.cpp |
+++ b/src/gpu/effects/GrDashingEffect.cpp |
@@ -316,6 +316,14 @@ private: |
} |
struct DashDraw { |
+ DashDraw(const Geometry& geo) { |
+ memcpy(fPtsRot, geo.fPtsRot, sizeof(geo.fPtsRot)); |
+ memcpy(fIntervals, geo.fIntervals, sizeof(geo.fIntervals)); |
+ fPhase = geo.fPhase; |
+ } |
+ SkPoint fPtsRot[2]; |
+ SkScalar fIntervals[2]; |
+ SkScalar fPhase; |
SkScalar fStartOffset; |
SkScalar fStrokeWidth; |
SkScalar fLineLength; |
@@ -327,7 +335,7 @@ private: |
bool fHasEndRect; |
}; |
- void onPrepareDraws(Target* target) override { |
+ void onPrepareDraws(Target* target) const override { |
int instanceCount = fGeoData.count(); |
SkPaint::Cap cap = this->cap(); |
bool isRoundCap = SkPaint::kRound_Cap == cap; |
@@ -362,14 +370,17 @@ private: |
// We do two passes over all of the dashes. First we setup the start, end, and bounds, |
// rectangles. We preserve all of this work in the rects / draws arrays below. Then we |
// iterate again over these decomposed dashes to generate vertices |
- SkSTArray<128, SkRect, true> rects; |
- SkSTArray<128, DashDraw, true> draws; |
+ static const int kNumStackDashes = 128; |
+ SkSTArray<kNumStackDashes, SkRect, true> rects; |
+ SkSTArray<kNumStackDashes, DashDraw, true> draws; |
int totalRectCount = 0; |
int rectOffset = 0; |
rects.push_back_n(3 * instanceCount); |
for (int i = 0; i < instanceCount; i++) { |
- Geometry& args = fGeoData[i]; |
+ const Geometry& args = fGeoData[i]; |
+ |
+ DashDraw& draw = draws.push_back(args); |
bool hasCap = SkPaint::kButt_Cap != cap && 0 != args.fSrcStrokeWidth; |
@@ -399,32 +410,32 @@ private: |
// 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 (args.fPhase > 0 && args.fPhase < args.fIntervals[0]) { |
+ if (draw.fPhase > 0 && draw.fPhase < draw.fIntervals[0]) { |
SkPoint startPts[2]; |
- startPts[0] = args.fPtsRot[0]; |
+ startPts[0] = draw.fPtsRot[0]; |
startPts[1].fY = startPts[0].fY; |
- startPts[1].fX = SkMinScalar(startPts[0].fX + args.fIntervals[0] - args.fPhase, |
- args.fPtsRot[1].fX); |
+ startPts[1].fX = SkMinScalar(startPts[0].fX + draw.fIntervals[0] - draw.fPhase, |
+ draw.fPtsRot[1].fX); |
startRect.set(startPts, 2); |
startRect.outset(strokeAdj, halfSrcStroke); |
hasStartRect = true; |
- startAdj = args.fIntervals[0] + args.fIntervals[1] - args.fPhase; |
+ startAdj = draw.fIntervals[0] + draw.fIntervals[1] - draw.fPhase; |
} |
} |
// adjustments for start and end of bounding rect so we only draw dash intervals |
// contained in the original line segment. |
- startAdj += calc_start_adjustment(args.fIntervals, args.fPhase); |
+ startAdj += calc_start_adjustment(draw.fIntervals, draw.fPhase); |
if (startAdj != 0) { |
- args.fPtsRot[0].fX += startAdj; |
- args.fPhase = 0; |
+ draw.fPtsRot[0].fX += startAdj; |
+ draw.fPhase = 0; |
} |
SkScalar endingInterval = 0; |
- SkScalar endAdj = calc_end_adjustment(args.fIntervals, args.fPtsRot, args.fPhase, |
+ SkScalar endAdj = calc_end_adjustment(draw.fIntervals, draw.fPtsRot, draw.fPhase, |
&endingInterval); |
- args.fPtsRot[1].fX -= endAdj; |
- if (args.fPtsRot[0].fX >= args.fPtsRot[1].fX) { |
+ draw.fPtsRot[1].fX -= endAdj; |
+ if (draw.fPtsRot[0].fX >= draw.fPtsRot[1].fX) { |
lineDone = true; |
} |
@@ -435,9 +446,9 @@ private: |
// 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 != args.fIntervals[0]) { |
+ if (0 == endAdj && endingInterval != draw.fIntervals[0]) { |
SkPoint endPts[2]; |
- endPts[1] = args.fPtsRot[1]; |
+ endPts[1] = draw.fPtsRot[1]; |
endPts[0].fY = endPts[1].fY; |
endPts[0].fX = endPts[1].fX - endingInterval; |
@@ -445,24 +456,24 @@ private: |
endRect.outset(strokeAdj, halfSrcStroke); |
hasEndRect = true; |
- endAdj = endingInterval + args.fIntervals[1]; |
+ endAdj = endingInterval + draw.fIntervals[1]; |
- args.fPtsRot[1].fX -= endAdj; |
- if (args.fPtsRot[0].fX >= args.fPtsRot[1].fX) { |
+ draw.fPtsRot[1].fX -= endAdj; |
+ if (draw.fPtsRot[0].fX >= draw.fPtsRot[1].fX) { |
lineDone = true; |
} |
} |
} |
if (startAdj != 0) { |
- args.fPhase = 0; |
+ draw.fPhase = 0; |
} |
// Change the dashing info from src space into device space |
- SkScalar* devIntervals = args.fIntervals; |
- devIntervals[0] = args.fIntervals[0] * args.fParallelScale; |
- devIntervals[1] = args.fIntervals[1] * args.fParallelScale; |
- SkScalar devPhase = args.fPhase * args.fParallelScale; |
+ SkScalar* devIntervals = draw.fIntervals; |
+ devIntervals[0] = draw.fIntervals[0] * args.fParallelScale; |
+ devIntervals[1] = draw.fIntervals[1] * args.fParallelScale; |
+ SkScalar devPhase = draw.fPhase * args.fParallelScale; |
SkScalar strokeWidth = args.fSrcStrokeWidth * args.fPerpendicularScale; |
if ((strokeWidth < 1.f && useAA) || 0.f == strokeWidth) { |
@@ -492,16 +503,16 @@ private: |
// 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 |
- args.fPtsRot[0].fX -= hasStartRect ? startAdj : 0; |
- args.fPtsRot[1].fX += hasEndRect ? endAdj : 0; |
- startRect.set(args.fPtsRot, 2); |
+ draw.fPtsRot[0].fX -= hasStartRect ? startAdj : 0; |
+ draw.fPtsRot[1].fX += hasEndRect ? endAdj : 0; |
+ startRect.set(draw.fPtsRot, 2); |
startRect.outset(strokeAdj, halfSrcStroke); |
hasStartRect = true; |
hasEndRect = false; |
lineDone = true; |
SkPoint devicePts[2]; |
- args.fViewMatrix.mapPoints(devicePts, args.fPtsRot, 2); |
+ args.fViewMatrix.mapPoints(devicePts, draw.fPtsRot, 2); |
SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); |
if (hasCap) { |
lineLength += 2.f * halfDevStroke; |
@@ -519,17 +530,16 @@ private: |
startOffset -= halfDevStroke; |
} |
- DashDraw& draw = draws.push_back(); |
if (!lineDone) { |
SkPoint devicePts[2]; |
- args.fViewMatrix.mapPoints(devicePts, args.fPtsRot, 2); |
+ args.fViewMatrix.mapPoints(devicePts, draw.fPtsRot, 2); |
draw.fLineLength = SkPoint::Distance(devicePts[0], devicePts[1]); |
if (hasCap) { |
draw.fLineLength += 2.f * halfDevStroke; |
} |
- bounds.set(args.fPtsRot[0].fX, args.fPtsRot[0].fY, |
- args.fPtsRot[1].fX, args.fPtsRot[1].fY); |
+ bounds.set(draw.fPtsRot[0].fX, draw.fPtsRot[0].fY, |
+ draw.fPtsRot[1].fX, draw.fPtsRot[1].fY); |
bounds.outset(bloatX + strokeAdj, bloatY + halfSrcStroke); |
} |
@@ -566,15 +576,15 @@ private: |
int curVIdx = 0; |
int rectIndex = 0; |
for (int i = 0; i < instanceCount; i++) { |
- Geometry& geom = fGeoData[i]; |
+ const Geometry& geom = fGeoData[i]; |
if (!draws[i].fLineDone) { |
if (fullDash) { |
setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv, |
draws[i].fStartOffset, draws[i].fDevBloatX, |
draws[i].fDevBloatY, draws[i].fLineLength, |
- draws[i].fHalfDevStroke, geom.fIntervals[0], |
- geom.fIntervals[1], draws[i].fStrokeWidth, |
+ draws[i].fHalfDevStroke, draws[i].fIntervals[0], |
+ draws[i].fIntervals[1], draws[i].fStrokeWidth, |
capType, gp->getVertexStride()); |
} else { |
SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); |
@@ -589,9 +599,9 @@ private: |
if (fullDash) { |
setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv, |
draws[i].fStartOffset, draws[i].fDevBloatX, |
- draws[i].fDevBloatY, geom.fIntervals[0], |
- draws[i].fHalfDevStroke, geom.fIntervals[0], |
- geom.fIntervals[1], draws[i].fStrokeWidth, capType, |
+ draws[i].fDevBloatY, draws[i].fIntervals[0], |
+ draws[i].fHalfDevStroke, draws[i].fIntervals[0], |
+ draws[i].fIntervals[1], draws[i].fStrokeWidth, capType, |
gp->getVertexStride()); |
} else { |
SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); |
@@ -606,9 +616,9 @@ private: |
if (fullDash) { |
setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv, |
draws[i].fStartOffset, draws[i].fDevBloatX, |
- draws[i].fDevBloatY, geom.fIntervals[0], |
- draws[i].fHalfDevStroke, geom.fIntervals[0], |
- geom.fIntervals[1], draws[i].fStrokeWidth, capType, |
+ draws[i].fDevBloatY, draws[i].fIntervals[0], |
+ draws[i].fHalfDevStroke, draws[i].fIntervals[0], |
+ draws[i].fIntervals[1], draws[i].fStrokeWidth, capType, |
gp->getVertexStride()); |
} else { |
SkPoint* verts = reinterpret_cast<SkPoint*>(vertices); |