Index: src/gpu/gl/GrGLPath.cpp |
diff --git a/src/gpu/gl/GrGLPath.cpp b/src/gpu/gl/GrGLPath.cpp |
index 07fdfd687a2d900a98c6b6b3d18c13d6258195f2..abbd12798de180470d3446d524faf8ec8c4fa8ad 100644 |
--- a/src/gpu/gl/GrGLPath.cpp |
+++ b/src/gpu/gl/GrGLPath.cpp |
@@ -16,13 +16,14 @@ inline GrGLubyte verb_to_gl_path_cmd(SkPath::Verb verb) { |
GR_GL_MOVE_TO, |
GR_GL_LINE_TO, |
GR_GL_QUADRATIC_CURVE_TO, |
- 0xFF, // conic |
+ GR_GL_CONIC_CURVE_TO, |
GR_GL_CUBIC_CURVE_TO, |
GR_GL_CLOSE_PATH, |
}; |
GR_STATIC_ASSERT(0 == SkPath::kMove_Verb); |
GR_STATIC_ASSERT(1 == SkPath::kLine_Verb); |
GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb); |
+ GR_STATIC_ASSERT(3 == SkPath::kConic_Verb); |
GR_STATIC_ASSERT(4 == SkPath::kCubic_Verb); |
GR_STATIC_ASSERT(5 == SkPath::kClose_Verb); |
@@ -31,18 +32,19 @@ inline GrGLubyte verb_to_gl_path_cmd(SkPath::Verb verb) { |
} |
#ifdef SK_DEBUG |
-inline int num_pts(SkPath::Verb verb) { |
+inline int num_coords(SkPath::Verb verb) { |
static const int gTable[] = { |
- 1, // move |
- 1, // line |
- 2, // quad |
- 2, // conic |
- 3, // cubic |
+ 2, // move |
+ 2, // line |
+ 4, // quad |
+ 5, // conic |
+ 6, // cubic |
0, // close |
}; |
GR_STATIC_ASSERT(0 == SkPath::kMove_Verb); |
GR_STATIC_ASSERT(1 == SkPath::kLine_Verb); |
GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb); |
+ GR_STATIC_ASSERT(3 == SkPath::kConic_Verb); |
GR_STATIC_ASSERT(4 == SkPath::kCubic_Verb); |
GR_STATIC_ASSERT(5 == SkPath::kClose_Verb); |
@@ -77,6 +79,13 @@ inline GrGLenum cap_to_gl_cap(SkPaint::Cap cap) { |
GR_STATIC_ASSERT(SK_ARRAY_COUNT(gSkCapsToGrGLCaps) == SkPaint::kCapCount); |
} |
+inline void points_to_coords(const SkPoint points[], size_t first_point, size_t amount, |
+ GrGLfloat coords[]) { |
+ for (size_t i = 0; i < amount; ++i) { |
+ coords[i * 2] = SkScalarToFloat(points[first_point + i].fX); |
+ coords[i * 2 + 1] = SkScalarToFloat(points[first_point + i].fY); |
+ } |
+} |
} |
static const bool kIsWrapped = false; // The constructor creates the GL path object. |
@@ -86,29 +95,77 @@ void GrGLPath::InitPathObject(GrGpuGL* gpu, |
const SkPath& skPath, |
const SkStrokeRec& stroke) { |
if (!skPath.isEmpty()) { |
- SkSTArray<16, GrGLubyte, true> pathCommands; |
- SkSTArray<16, SkPoint, true> pathPoints; |
- |
int verbCnt = skPath.countVerbs(); |
int pointCnt = skPath.countPoints(); |
- pathCommands.resize_back(verbCnt); |
- pathPoints.resize_back(pointCnt); |
- |
- // TODO: Direct access to path points since we could pass them on directly. |
- skPath.getPoints(&pathPoints[0], pointCnt); |
- skPath.getVerbs(&pathCommands[0], verbCnt); |
- |
- SkDEBUGCODE(int numPts = 0); |
- for (int i = 0; i < verbCnt; ++i) { |
- SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]); |
- pathCommands[i] = verb_to_gl_path_cmd(v); |
- SkDEBUGCODE(numPts += num_pts(v)); |
+ int minCoordCnt = pointCnt * 2; |
+ |
+ SkSTArray<16, GrGLubyte, true> pathCommands(verbCnt); |
+ SkSTArray<16, GrGLfloat, true> pathCoords(minCoordCnt); |
+ |
+ SkDEBUGCODE(int numCoords = 0); |
+ |
+ if ((skPath.getSegmentMasks() & SkPath::kConic_SegmentMask) == 0) { |
+ // This branch does type punning, converting SkPoint* to GrGLfloat*. |
+ SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(GrGLfloat) * 2, sk_point_not_two_floats); |
+ // This branch does not convert with SkScalarToFloat. |
+#ifndef SK_SCALAR_IS_FLOAT |
bsalomon
2014/11/19 16:53:33
There is some interest in scalar=double. I suppose
|
+#error Need SK_SCALAR_IS_FLOAT. |
+#endif |
+ pathCommands.resize_back(verbCnt); |
+ pathCoords.resize_back(minCoordCnt); |
+ skPath.getPoints(reinterpret_cast<SkPoint*>(&pathCoords[0]), pointCnt); |
+ skPath.getVerbs(&pathCommands[0], verbCnt); |
+ for (int i = 0; i < verbCnt; ++i) { |
+ SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]); |
+ pathCommands[i] = verb_to_gl_path_cmd(v); |
+ SkDEBUGCODE(numCoords += num_coords(v)); |
+ } |
+ } else { |
+ SkPoint points[4]; |
+ SkPath::RawIter iter(skPath); |
+ SkPath::Verb verb; |
+ while ((verb = iter.next(points)) != SkPath::kDone_Verb) { |
+ pathCommands.push_back(verb_to_gl_path_cmd(verb)); |
+ GrGLfloat coords[6]; |
+ int coordsForVerb; |
+ switch (verb) { |
+ case SkPath::kMove_Verb: |
+ points_to_coords(points, 0, 1, coords); |
+ coordsForVerb = 2; |
+ break; |
+ case SkPath::kLine_Verb: |
+ points_to_coords(points, 1, 1, coords); |
+ coordsForVerb = 2; |
+ break; |
+ case SkPath::kConic_Verb: |
+ points_to_coords(points, 1, 2, coords); |
+ coords[4] = SkScalarToFloat(iter.conicWeight()); |
+ coordsForVerb = 5; |
+ break; |
+ case SkPath::kQuad_Verb: |
+ points_to_coords(points, 1, 2, coords); |
+ coordsForVerb = 4; |
+ break; |
+ case SkPath::kCubic_Verb: |
+ points_to_coords(points, 1, 3, coords); |
+ coordsForVerb = 6; |
+ break; |
+ case SkPath::kClose_Verb: |
+ continue; |
+ default: |
+ SkASSERT(false); // Not reached. |
+ continue; |
+ } |
+ SkDEBUGCODE(numCoords += num_coords(verb)); |
+ pathCoords.push_back_n(coordsForVerb, coords); |
+ } |
} |
- SkASSERT(pathPoints.count() == numPts); |
- GR_GL_CALL(gpu->glInterface(), |
- PathCommands(pathID, verbCnt, &pathCommands[0], |
- 2 * pointCnt, GR_GL_FLOAT, &pathPoints[0])); |
+ SkASSERT(verbCnt == pathCommands.count()); |
+ SkASSERT(numCoords == pathCoords.count()); |
+ |
+ GR_GL_CALL(gpu->glInterface(), PathCommands(pathID, pathCommands.count(), &pathCommands[0], |
+ pathCoords.count(), GR_GL_FLOAT, &pathCoords[0])); |
} else { |
GR_GL_CALL(gpu->glInterface(), PathCommands(pathID, 0, NULL, 0, GR_GL_FLOAT, NULL)); |
} |