diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 549edd2..4a7f318 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -21,10 +21,10 @@
 		LayerRenderer.cpp \
 		Matrix.cpp \
 		OpenGLRenderer.cpp \
-		PathRenderer.cpp \
 		Patch.cpp \
 		PatchCache.cpp \
 		PathCache.cpp \
+		PathTessellator.cpp \
 		Program.cpp \
 		ProgramCache.cpp \
 		ResourceCache.cpp \
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index ae188be..5cea495 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -66,7 +66,6 @@
 static const GLsizei gMeshStride = sizeof(TextureVertex);
 static const GLsizei gVertexStride = sizeof(Vertex);
 static const GLsizei gAlphaVertexStride = sizeof(AlphaVertex);
-static const GLsizei gAAVertexStride = sizeof(AAVertex);
 static const GLsizei gMeshTextureOffset = 2 * sizeof(float);
 static const GLsizei gVertexAlphaOffset = 2 * sizeof(float);
 static const GLsizei gVertexAAWidthOffset = 2 * sizeof(float);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 7772f3a..06d1784 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -33,7 +33,7 @@
 
 #include "OpenGLRenderer.h"
 #include "DisplayListRenderer.h"
-#include "PathRenderer.h"
+#include "PathTessellator.h"
 #include "Properties.h"
 #include "Vector.h"
 
@@ -1469,10 +1469,6 @@
     mDescription.isAA = true;
 }
 
-void OpenGLRenderer::setupDrawVertexShape() {
-    mDescription.isVertexShape = true;
-}
-
 void OpenGLRenderer::setupDrawPoint(float pointSize) {
     mDescription.isPoint = true;
     mDescription.pointSize = pointSize;
@@ -1688,41 +1684,6 @@
     mCaches.unbindIndicesBuffer();
 }
 
-/**
- * Sets up the shader to draw an AA line. We draw AA lines with quads, where there is an
- * outer boundary that fades out to 0. The variables set in the shader define the proportion of
- * the width and length of the primitive occupied by the AA region. The vtxWidth and vtxLength
- * attributes (one per vertex) are values from zero to one that tells the fragment
- * shader where the fragment is in relation to the line width/length overall; these values are
- * then used to compute the proper color, based on whether the fragment lies in the fading AA
- * region of the line.
- * Note that we only pass down the width values in this setup function. The length coordinates
- * are set up for each individual segment.
- */
-void OpenGLRenderer::setupDrawAALine(GLvoid* vertices, GLvoid* widthCoords,
-        GLvoid* lengthCoords, float boundaryWidthProportion, int& widthSlot, int& lengthSlot) {
-    bool force = mCaches.unbindMeshBuffer();
-    mCaches.bindPositionVertexPointer(force, vertices, gAAVertexStride);
-    mCaches.resetTexCoordsVertexPointer();
-    mCaches.unbindIndicesBuffer();
-
-    widthSlot = mCaches.currentProgram->getAttrib("vtxWidth");
-    glEnableVertexAttribArray(widthSlot);
-    glVertexAttribPointer(widthSlot, 1, GL_FLOAT, GL_FALSE, gAAVertexStride, widthCoords);
-
-    lengthSlot = mCaches.currentProgram->getAttrib("vtxLength");
-    glEnableVertexAttribArray(lengthSlot);
-    glVertexAttribPointer(lengthSlot, 1, GL_FLOAT, GL_FALSE, gAAVertexStride, lengthCoords);
-
-    int boundaryWidthSlot = mCaches.currentProgram->getUniform("boundaryWidth");
-    glUniform1f(boundaryWidthSlot, boundaryWidthProportion);
-}
-
-void OpenGLRenderer::finishDrawAALine(const int widthSlot, const int lengthSlot) {
-    glDisableVertexAttribArray(widthSlot);
-    glDisableVertexAttribArray(lengthSlot);
-}
-
 void OpenGLRenderer::finishDrawTexture() {
 }
 
@@ -2083,39 +2044,26 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-/**
- * Renders a convex path via tessellation. For AA paths, this function uses a similar approach to
- * that of AA lines in the drawLines() function.  We expand the convex path by a half pixel in
- * screen space in all directions. However, instead of using a fragment shader to compute the
- * translucency of the color from its position, we simply use a varying parameter to define how far
- * a given pixel is from the edge. For non-AA paths, the expansion and alpha varying are not used.
- *
- * Doesn't yet support joins, caps, or path effects.
- */
-void OpenGLRenderer::drawConvexPath(const SkPath& path, SkPaint* paint) {
+status_t OpenGLRenderer::drawVertexBuffer(const VertexBuffer& vertexBuffer, SkPaint* paint,
+        bool useOffset) {
+    if (!vertexBuffer.getSize()) {
+        // no vertices to draw
+        return DrawGlInfo::kStatusDone;
+    }
+
     int color = paint->getColor();
     SkXfermode::Mode mode = getXfermode(paint->getXfermode());
     bool isAA = paint->isAntiAlias();
 
-    VertexBuffer vertexBuffer;
-    // TODO: try clipping large paths to viewport
-    PathRenderer::convexPathVertices(path, paint, mSnapshot->transform, vertexBuffer);
-
-    if (!vertexBuffer.getSize()) {
-        // no vertices to draw
-        return;
-    }
-
     setupDraw();
     setupDrawNoTexture();
     if (isAA) setupDrawAA();
-    setupDrawVertexShape();
     setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha);
     setupDrawColorFilter();
     setupDrawShader();
     setupDrawBlending(isAA, mode);
     setupDrawProgram();
-    setupDrawModelViewIdentity();
+    setupDrawModelViewIdentity(useOffset);
     setupDrawColorUniforms();
     setupDrawColorFilterUniforms();
     setupDrawShaderIdentityUniforms();
@@ -2136,286 +2084,59 @@
         glVertexAttribPointer(alphaSlot, 1, GL_FLOAT, GL_FALSE, gAlphaVertexStride, alphaCoords);
     }
 
-    SkRect bounds = PathRenderer::computePathBounds(path, paint);
-    dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *mSnapshot->transform);
-
     glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getSize());
 
     if (isAA) {
         glDisableVertexAttribArray(alphaSlot);
     }
+
+    return DrawGlInfo::kStatusDrew;
 }
 
 /**
- * We draw lines as quads (tristrips). Using GL_LINES can be difficult because the rasterization
- * rules for those lines produces some unexpected results, and may vary between hardware devices.
- * The basics of lines-as-quads is easy; we simply find the normal to the line and position the
- * corners of the quads on either side of each line endpoint, separated by the strokeWidth
- * of the line. Hairlines are more involved because we need to account for transform scaling
- * to end up with a one-pixel-wide line in screen space..
- * Anti-aliased lines add another factor to the approach. We use a specialized fragment shader
- * in combination with values that we calculate and pass down in this method. The basic approach
- * is that the quad we create contains both the core line area plus a bounding area in which
- * the translucent/AA pixels are drawn. The values we calculate tell the shader what
- * proportion of the width and the length of a given segment is represented by the boundary
- * region. The quad ends up being exactly .5 pixel larger in all directions than the non-AA quad.
- * The bounding region is actually 1 pixel wide on all sides (half pixel on the outside, half pixel
- * on the inside). This ends up giving the result we want, with pixels that are completely
- * 'inside' the line area being filled opaquely and the other pixels being filled according to
- * how far into the boundary region they are, which is determined by shader interpolation.
+ * Renders a convex path via tessellation. For AA paths, this function uses a similar approach to
+ * that of AA lines in the drawLines() function.  We expand the convex path by a half pixel in
+ * screen space in all directions. However, instead of using a fragment shader to compute the
+ * translucency of the color from its position, we simply use a varying parameter to define how far
+ * a given pixel is from the edge. For non-AA paths, the expansion and alpha varying are not used.
+ *
+ * Doesn't yet support joins, caps, or path effects.
+ */
+status_t OpenGLRenderer::drawConvexPath(const SkPath& path, SkPaint* paint) {
+    VertexBuffer vertexBuffer;
+    // TODO: try clipping large paths to viewport
+    PathTessellator::tessellatePath(path, paint, mSnapshot->transform, vertexBuffer);
+
+    SkRect bounds = path.getBounds();
+    PathTessellator::expandBoundsForStroke(bounds, paint, false);
+    dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *mSnapshot->transform);
+
+    return drawVertexBuffer(vertexBuffer, paint);
+}
+
+/**
+ * We create tristrips for the lines much like shape stroke tessellation, using a per-vertex alpha
+ * and additional geometry for defining an alpha slope perimeter.
+ *
+ * Using GL_LINES can be difficult because the rasterization rules for those lines produces some
+ * unexpected results, and may vary between hardware devices. Previously we used a varying-base
+ * in-shader alpha region, but found it to be taxing on some GPUs.
+ *
+ * TODO: try using a fixed input buffer for non-capped lines as in text rendering. this may reduce
+ * memory transfer by removing need for degenerate vertices.
  */
 status_t OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
+    if (mSnapshot->isIgnored() || count < 4) return DrawGlInfo::kStatusDone;
 
-    const bool isAA = paint->isAntiAlias();
-    // We use half the stroke width here because we're going to position the quad
-    // corner vertices half of the width away from the line endpoints
-    float halfStrokeWidth = paint->getStrokeWidth() * 0.5f;
-    // A stroke width of 0 has a special meaning in Skia:
-    // it draws a line 1 px wide regardless of current transform
-    bool isHairLine = paint->getStrokeWidth() == 0.0f;
+    count &= ~0x3; // round down to nearest four
 
-    float inverseScaleX = 1.0f;
-    float inverseScaleY = 1.0f;
-    bool scaled = false;
+    VertexBuffer buffer;
+    SkRect bounds;
+    PathTessellator::tessellateLines(points, count, paint, mSnapshot->transform, bounds, buffer);
+    dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *mSnapshot->transform);
 
-    int alpha;
-    SkXfermode::Mode mode;
-
-    int generatedVerticesCount = 0;
-    int verticesCount = count;
-    if (count > 4) {
-        // Polyline: account for extra vertices needed for continuous tri-strip
-        verticesCount += (count - 4);
-    }
-
-    if (isHairLine || isAA) {
-        // The quad that we use for AA and hairlines needs to account for scaling. For hairlines
-        // the line on the screen should always be one pixel wide regardless of scale. For
-        // AA lines, we only want one pixel of translucent boundary around the quad.
-        if (CC_UNLIKELY(!mSnapshot->transform->isPureTranslate())) {
-            Matrix4 *mat = mSnapshot->transform;
-            float m00 = mat->data[Matrix4::kScaleX];
-            float m01 = mat->data[Matrix4::kSkewY];
-            float m10 = mat->data[Matrix4::kSkewX];
-            float m11 = mat->data[Matrix4::kScaleY];
-
-            float scaleX = sqrtf(m00 * m00 + m01 * m01);
-            float scaleY = sqrtf(m10 * m10 + m11 * m11);
-
-            inverseScaleX = (scaleX != 0) ? (inverseScaleX / scaleX) : 0;
-            inverseScaleY = (scaleY != 0) ? (inverseScaleY / scaleY) : 0;
-
-            if (inverseScaleX != 1.0f || inverseScaleY != 1.0f) {
-                scaled = true;
-            }
-        }
-    }
-
-    getAlphaAndMode(paint, &alpha, &mode);
-
-    mCaches.enableScissor();
-
-    setupDraw();
-    setupDrawNoTexture();
-    if (isAA) {
-        setupDrawAA();
-    }
-    setupDrawColor(paint->getColor(), alpha);
-    setupDrawColorFilter();
-    setupDrawShader();
-    setupDrawBlending(isAA, mode);
-    setupDrawProgram();
-    setupDrawModelViewIdentity(true);
-    setupDrawColorUniforms();
-    setupDrawColorFilterUniforms();
-    setupDrawShaderIdentityUniforms();
-
-    if (isHairLine) {
-        // Set a real stroke width to be used in quad construction
-        halfStrokeWidth = isAA? 1 : .5;
-    } else if (isAA && !scaled) {
-        // Expand boundary to enable AA calculations on the quad border
-        halfStrokeWidth += .5f;
-    }
-
-    int widthSlot;
-    int lengthSlot;
-
-    Vertex lines[verticesCount];
-    Vertex* vertices = &lines[0];
-
-    AAVertex wLines[verticesCount];
-    AAVertex* aaVertices = &wLines[0];
-
-    if (CC_UNLIKELY(!isAA)) {
-        setupDrawVertices(vertices);
-    } else {
-        void* widthCoords = ((GLbyte*) aaVertices) + gVertexAAWidthOffset;
-        void* lengthCoords = ((GLbyte*) aaVertices) + gVertexAALengthOffset;
-        // innerProportion is the ratio of the inner (non-AA) part of the line to the total
-        // AA stroke width (the base stroke width expanded by a half pixel on either side).
-        // This value is used in the fragment shader to determine how to fill fragments.
-        // We will need to calculate the actual width proportion on each segment for
-        // scaled non-hairlines, since the boundary proportion may differ per-axis when scaled.
-        float boundaryWidthProportion = .5 - 1 / (2 * halfStrokeWidth);
-        setupDrawAALine((void*) aaVertices, widthCoords, lengthCoords,
-                boundaryWidthProportion, widthSlot, lengthSlot);
-    }
-
-    AAVertex* prevAAVertex = NULL;
-    Vertex* prevVertex = NULL;
-
-    int boundaryLengthSlot = -1;
-    int boundaryWidthSlot = -1;
-
-    for (int i = 0; i < count; i += 4) {
-        // a = start point, b = end point
-        vec2 a(points[i], points[i + 1]);
-        vec2 b(points[i + 2], points[i + 3]);
-
-        float length = 0;
-        float boundaryLengthProportion = 0;
-        float boundaryWidthProportion = 0;
-
-        // Find the normal to the line
-        vec2 n = (b - a).copyNormalized() * halfStrokeWidth;
-        float x = n.x;
-        n.x = -n.y;
-        n.y = x;
-
-        if (isHairLine) {
-            if (isAA) {
-                float wideningFactor;
-                if (fabs(n.x) >= fabs(n.y)) {
-                    wideningFactor = fabs(1.0f / n.x);
-                } else {
-                    wideningFactor = fabs(1.0f / n.y);
-                }
-                n *= wideningFactor;
-            }
-
-            if (scaled) {
-                n.x *= inverseScaleX;
-                n.y *= inverseScaleY;
-            }
-        } else if (scaled) {
-            // Extend n by .5 pixel on each side, post-transform
-            vec2 extendedN = n.copyNormalized();
-            extendedN /= 2;
-            extendedN.x *= inverseScaleX;
-            extendedN.y *= inverseScaleY;
-
-            float extendedNLength = extendedN.length();
-            // We need to set this value on the shader prior to drawing
-            boundaryWidthProportion = .5 - extendedNLength / (halfStrokeWidth + extendedNLength);
-            n += extendedN;
-        }
-
-        // aa lines expand the endpoint vertices to encompass the AA boundary
-        if (isAA) {
-            vec2 abVector = (b - a);
-            length = abVector.length();
-            abVector.normalize();
-
-            if (scaled) {
-                abVector.x *= inverseScaleX;
-                abVector.y *= inverseScaleY;
-                float abLength = abVector.length();
-                boundaryLengthProportion = .5 - abLength / (length + abLength);
-            } else {
-                boundaryLengthProportion = .5 - .5 / (length + 1);
-            }
-
-            abVector /= 2;
-            a -= abVector;
-            b += abVector;
-        }
-
-        // Four corners of the rectangle defining a thick line
-        vec2 p1 = a - n;
-        vec2 p2 = a + n;
-        vec2 p3 = b + n;
-        vec2 p4 = b - n;
-
-
-        const float left = fmin(p1.x, fmin(p2.x, fmin(p3.x, p4.x)));
-        const float right = fmax(p1.x, fmax(p2.x, fmax(p3.x, p4.x)));
-        const float top = fmin(p1.y, fmin(p2.y, fmin(p3.y, p4.y)));
-        const float bottom = fmax(p1.y, fmax(p2.y, fmax(p3.y, p4.y)));
-
-        if (!quickRejectNoScissor(left, top, right, bottom)) {
-            if (!isAA) {
-                if (prevVertex != NULL) {
-                    // Issue two repeat vertices to create degenerate triangles to bridge
-                    // between the previous line and the new one. This is necessary because
-                    // we are creating a single triangle_strip which will contain
-                    // potentially discontinuous line segments.
-                    Vertex::set(vertices++, prevVertex->position[0], prevVertex->position[1]);
-                    Vertex::set(vertices++, p1.x, p1.y);
-                    generatedVerticesCount += 2;
-                }
-
-                Vertex::set(vertices++, p1.x, p1.y);
-                Vertex::set(vertices++, p2.x, p2.y);
-                Vertex::set(vertices++, p4.x, p4.y);
-                Vertex::set(vertices++, p3.x, p3.y);
-
-                prevVertex = vertices - 1;
-                generatedVerticesCount += 4;
-            } else {
-                if (!isHairLine && scaled) {
-                    // Must set width proportions per-segment for scaled non-hairlines to use the
-                    // correct AA boundary dimensions
-                    if (boundaryWidthSlot < 0) {
-                        boundaryWidthSlot =
-                                mCaches.currentProgram->getUniform("boundaryWidth");
-                    }
-
-                    glUniform1f(boundaryWidthSlot, boundaryWidthProportion);
-                }
-
-                if (boundaryLengthSlot < 0) {
-                    boundaryLengthSlot = mCaches.currentProgram->getUniform("boundaryLength");
-                }
-
-                glUniform1f(boundaryLengthSlot, boundaryLengthProportion);
-
-                if (prevAAVertex != NULL) {
-                    // Issue two repeat vertices to create degenerate triangles to bridge
-                    // between the previous line and the new one. This is necessary because
-                    // we are creating a single triangle_strip which will contain
-                    // potentially discontinuous line segments.
-                    AAVertex::set(aaVertices++,prevAAVertex->position[0],
-                            prevAAVertex->position[1], prevAAVertex->width, prevAAVertex->length);
-                    AAVertex::set(aaVertices++, p4.x, p4.y, 1, 1);
-                    generatedVerticesCount += 2;
-                }
-
-                AAVertex::set(aaVertices++, p4.x, p4.y, 1, 1);
-                AAVertex::set(aaVertices++, p1.x, p1.y, 1, 0);
-                AAVertex::set(aaVertices++, p3.x, p3.y, 0, 1);
-                AAVertex::set(aaVertices++, p2.x, p2.y, 0, 0);
-
-                prevAAVertex = aaVertices - 1;
-                generatedVerticesCount += 4;
-            }
-
-            dirtyLayer(a.x == b.x ? left - 1 : left, a.y == b.y ? top - 1 : top,
-                    a.x == b.x ? right: right, a.y == b.y ? bottom: bottom,
-                    *mSnapshot->transform);
-        }
-    }
-
-    if (generatedVerticesCount > 0) {
-       glDrawArrays(GL_TRIANGLE_STRIP, 0, generatedVerticesCount);
-    }
-
-    if (isAA) {
-        finishDrawAALine(widthSlot, lengthSlot);
-    }
-
-    return DrawGlInfo::kStatusDrew;
+    bool useOffset = !paint->isAntiAlias();
+    return drawVertexBuffer(buffer, paint, useOffset);
 }
 
 status_t OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
@@ -2526,9 +2247,7 @@
         ry += outset;
     }
     path.addRoundRect(rect, rx, ry);
-    drawConvexPath(path, p);
-
-    return DrawGlInfo::kStatusDrew;
+    return drawConvexPath(path, p);
 }
 
 status_t OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* p) {
@@ -2548,9 +2267,7 @@
     } else {
         path.addCircle(x, y, radius);
     }
-    drawConvexPath(path, p);
-
-    return DrawGlInfo::kStatusDrew;
+    return drawConvexPath(path, p);
 }
 
 status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom,
@@ -2571,9 +2288,7 @@
         rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2);
     }
     path.addOval(rect);
-    drawConvexPath(path, p);
-
-    return DrawGlInfo::kStatusDrew;
+    return drawConvexPath(path, p);
 }
 
 status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
@@ -2587,8 +2302,7 @@
     }
 
     // TODO: support fills (accounting for concavity if useCenter && sweepAngle > 180)
-    if (p->getStyle() != SkPaint::kStroke_Style || p->getPathEffect() != 0 ||
-            p->getStrokeCap() != SkPaint::kButt_Cap || useCenter) {
+    if (p->getStyle() != SkPaint::kStroke_Style || p->getPathEffect() != 0 || useCenter) {
         mCaches.activeTexture(0);
         const PathTexture* texture = mCaches.arcShapeCache.getArc(right - left, bottom - top,
                 startAngle, sweepAngle, useCenter, p);
@@ -2608,9 +2322,7 @@
     if (useCenter) {
         path.close();
     }
-    drawConvexPath(path, p);
-
-    return DrawGlInfo::kStatusDrew;
+    return drawConvexPath(path, p);
 }
 
 // See SkPaintDefaults.h
@@ -2637,20 +2349,17 @@
             rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2);
         }
         path.addRect(rect);
-        drawConvexPath(path, p);
-
-        return DrawGlInfo::kStatusDrew;
+        return drawConvexPath(path, p);
     }
 
     if (p->isAntiAlias() && !mSnapshot->transform->isSimple()) {
         SkPath path;
         path.addRect(left, top, right, bottom);
-        drawConvexPath(path, p);
+        return drawConvexPath(path, p);
     } else {
         drawColorRect(left, top, right, bottom, p->getColor(), getXfermode(p->getXfermode()));
+        return DrawGlInfo::kStatusDrew;
     }
-
-    return DrawGlInfo::kStatusDrew;
 }
 
 void OpenGLRenderer::drawTextShadow(SkPaint* paint, const char* text, int bytesCount, int count,
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 594580e..22dc718 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -53,6 +53,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 class DisplayList;
+class VertexBuffer;
 
 /**
  * OpenGL renderer used to draw accelerated 2D graphics. The API is a
@@ -582,12 +583,22 @@
     void drawAlphaBitmap(Texture* texture, float left, float top, SkPaint* paint);
 
     /**
+     * Renders a strip of polygons with the specified paint, used for tessellated geometry.
+     *
+     * @param vertexBuffer The VertexBuffer to be drawn
+     * @param paint The paint to render with
+     * @param useOffset Offset the vertexBuffer (used in drawing non-AA lines)
+     */
+    status_t drawVertexBuffer(const VertexBuffer& vertexBuffer, SkPaint* paint,
+            bool useOffset = false);
+
+    /**
      * Renders the convex hull defined by the specified path as a strip of polygons.
      *
      * @param path The hull of the path to draw
      * @param paint The paint to render with
      */
-    void drawConvexPath(const SkPath& path, SkPaint* paint);
+    status_t drawConvexPath(const SkPath& path, SkPaint* paint);
 
     /**
      * Draws a textured rectangle with the specified texture. The specified coordinates
@@ -754,7 +765,6 @@
     void setupDrawWithExternalTexture();
     void setupDrawNoTexture();
     void setupDrawAA();
-    void setupDrawVertexShape();
     void setupDrawPoint(float pointSize);
     void setupDrawColor(int color, int alpha);
     void setupDrawColor(float r, float g, float b, float a);
@@ -788,9 +798,6 @@
     void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0);
     void setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords);
     void setupDrawVertices(GLvoid* vertices);
-    void setupDrawAALine(GLvoid* vertices, GLvoid* distanceCoords, GLvoid* lengthCoords,
-            float strokeWidth, int& widthSlot, int& lengthSlot);
-    void finishDrawAALine(const int widthSlot, const int lengthSlot);
     void finishDrawTexture();
     void accountForClear(SkXfermode::Mode mode);
 
diff --git a/libs/hwui/PathRenderer.cpp b/libs/hwui/PathRenderer.cpp
deleted file mode 100644
index d59e36f..0000000
--- a/libs/hwui/PathRenderer.cpp
+++ /dev/null
@@ -1,720 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "PathRenderer"
-#define LOG_NDEBUG 1
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-
-#define VERTEX_DEBUG 0
-
-#include <SkPath.h>
-#include <SkPaint.h>
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Log.h>
-#include <utils/Trace.h>
-
-#include "PathRenderer.h"
-#include "Matrix.h"
-#include "Vector.h"
-#include "Vertex.h"
-
-namespace android {
-namespace uirenderer {
-
-#define THRESHOLD 0.5f
-
-SkRect PathRenderer::computePathBounds(const SkPath& path, const SkPaint* paint) {
-    SkRect bounds = path.getBounds();
-    if (paint->getStyle() != SkPaint::kFill_Style) {
-        float outset = paint->getStrokeWidth() * 0.5f;
-        bounds.outset(outset, outset);
-    }
-    return bounds;
-}
-
-void computeInverseScales(const mat4 *transform, float &inverseScaleX, float& inverseScaleY) {
-    if (CC_UNLIKELY(!transform->isPureTranslate())) {
-        float m00 = transform->data[Matrix4::kScaleX];
-        float m01 = transform->data[Matrix4::kSkewY];
-        float m10 = transform->data[Matrix4::kSkewX];
-        float m11 = transform->data[Matrix4::kScaleY];
-        float scaleX = sqrt(m00 * m00 + m01 * m01);
-        float scaleY = sqrt(m10 * m10 + m11 * m11);
-        inverseScaleX = (scaleX != 0) ? (1.0f / scaleX) : 1.0f;
-        inverseScaleY = (scaleY != 0) ? (1.0f / scaleY) : 1.0f;
-    } else {
-        inverseScaleX = 1.0f;
-        inverseScaleY = 1.0f;
-    }
-}
-
-inline void copyVertex(Vertex* destPtr, const Vertex* srcPtr) {
-    Vertex::set(destPtr, srcPtr->position[0], srcPtr->position[1]);
-}
-
-inline void copyAlphaVertex(AlphaVertex* destPtr, const AlphaVertex* srcPtr) {
-    AlphaVertex::set(destPtr, srcPtr->position[0], srcPtr->position[1], srcPtr->alpha);
-}
-
-/**
- * Produces a pseudo-normal for a vertex, given the normals of the two incoming lines. If the offset
- * from each vertex in a perimeter is calculated, the resultant lines connecting the offset vertices
- * will be offset by 1.0
- *
- * Note that we can't add and normalize the two vectors, that would result in a rectangle having an
- * offset of (sqrt(2)/2, sqrt(2)/2) at each corner, instead of (1, 1)
- *
- * NOTE: assumes angles between normals 90 degrees or less
- */
-inline vec2 totalOffsetFromNormals(const vec2& normalA, const vec2& normalB) {
-    return (normalA + normalB) / (1 + fabs(normalA.dot(normalB)));
-}
-
-inline void scaleOffsetForStrokeWidth(vec2& offset, float halfStrokeWidth,
-        float inverseScaleX, float inverseScaleY) {
-    if (halfStrokeWidth == 0.0f) {
-        // hairline - compensate for scale
-        offset.x *= 0.5f * inverseScaleX;
-        offset.y *= 0.5f * inverseScaleY;
-    } else {
-        offset *= halfStrokeWidth;
-    }
-}
-
-void getFillVerticesFromPerimeter(const Vector<Vertex>& perimeter, VertexBuffer& vertexBuffer) {
-    Vertex* buffer = vertexBuffer.alloc<Vertex>(perimeter.size());
-
-    int currentIndex = 0;
-    // zig zag between all previous points on the inside of the hull to create a
-    // triangle strip that fills the hull
-    int srcAindex = 0;
-    int srcBindex = perimeter.size() - 1;
-    while (srcAindex <= srcBindex) {
-        copyVertex(&buffer[currentIndex++], &perimeter[srcAindex]);
-        if (srcAindex == srcBindex) break;
-        copyVertex(&buffer[currentIndex++], &perimeter[srcBindex]);
-        srcAindex++;
-        srcBindex--;
-    }
-}
-
-void getStrokeVerticesFromPerimeter(const Vector<Vertex>& perimeter, float halfStrokeWidth,
-        VertexBuffer& vertexBuffer, float inverseScaleX, float inverseScaleY) {
-    Vertex* buffer = vertexBuffer.alloc<Vertex>(perimeter.size() * 2 + 2);
-
-    int currentIndex = 0;
-    const Vertex* last = &(perimeter[perimeter.size() - 1]);
-    const Vertex* current = &(perimeter[0]);
-    vec2 lastNormal(current->position[1] - last->position[1],
-            last->position[0] - current->position[0]);
-    lastNormal.normalize();
-    for (unsigned int i = 0; i < perimeter.size(); i++) {
-        const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
-        vec2 nextNormal(next->position[1] - current->position[1],
-                current->position[0] - next->position[0]);
-        nextNormal.normalize();
-
-        vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
-        scaleOffsetForStrokeWidth(totalOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
-
-        Vertex::set(&buffer[currentIndex++],
-                current->position[0] + totalOffset.x,
-                current->position[1] + totalOffset.y);
-
-        Vertex::set(&buffer[currentIndex++],
-                current->position[0] - totalOffset.x,
-                current->position[1] - totalOffset.y);
-
-        last = current;
-        current = next;
-        lastNormal = nextNormal;
-    }
-
-    // wrap around to beginning
-    copyVertex(&buffer[currentIndex++], &buffer[0]);
-    copyVertex(&buffer[currentIndex++], &buffer[1]);
-}
-
-void getStrokeVerticesFromUnclosedVertices(const Vector<Vertex>& vertices, float halfStrokeWidth,
-        VertexBuffer& vertexBuffer, float inverseScaleX, float inverseScaleY) {
-    Vertex* buffer = vertexBuffer.alloc<Vertex>(vertices.size() * 2);
-
-    int currentIndex = 0;
-    const Vertex* current = &(vertices[0]);
-    vec2 lastNormal;
-    for (unsigned int i = 0; i < vertices.size() - 1; i++) {
-        const Vertex* next = &(vertices[i + 1]);
-        vec2 nextNormal(next->position[1] - current->position[1],
-                current->position[0] - next->position[0]);
-        nextNormal.normalize();
-
-        vec2 totalOffset;
-        if (i == 0) {
-            totalOffset = nextNormal;
-        } else {
-            totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
-        }
-        scaleOffsetForStrokeWidth(totalOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
-
-        Vertex::set(&buffer[currentIndex++],
-                current->position[0] + totalOffset.x,
-                current->position[1] + totalOffset.y);
-
-        Vertex::set(&buffer[currentIndex++],
-                current->position[0] - totalOffset.x,
-                current->position[1] - totalOffset.y);
-
-        current = next;
-        lastNormal = nextNormal;
-    }
-
-    vec2 totalOffset = lastNormal;
-    scaleOffsetForStrokeWidth(totalOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
-
-    Vertex::set(&buffer[currentIndex++],
-            current->position[0] + totalOffset.x,
-            current->position[1] + totalOffset.y);
-    Vertex::set(&buffer[currentIndex++],
-            current->position[0] - totalOffset.x,
-            current->position[1] - totalOffset.y);
-#if VERTEX_DEBUG
-    for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) {
-        ALOGD("point at %f %f", buffer[i].position[0], buffer[i].position[1]);
-    }
-#endif
-}
-
-void getFillVerticesFromPerimeterAA(const Vector<Vertex>& perimeter, VertexBuffer& vertexBuffer,
-         float inverseScaleX, float inverseScaleY) {
-    AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(perimeter.size() * 3 + 2);
-
-    // generate alpha points - fill Alpha vertex gaps in between each point with
-    // alpha 0 vertex, offset by a scaled normal.
-    int currentIndex = 0;
-    const Vertex* last = &(perimeter[perimeter.size() - 1]);
-    const Vertex* current = &(perimeter[0]);
-    vec2 lastNormal(current->position[1] - last->position[1],
-            last->position[0] - current->position[0]);
-    lastNormal.normalize();
-    for (unsigned int i = 0; i < perimeter.size(); i++) {
-        const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
-        vec2 nextNormal(next->position[1] - current->position[1],
-                current->position[0] - next->position[0]);
-        nextNormal.normalize();
-
-        // AA point offset from original point is that point's normal, such that each side is offset
-        // by .5 pixels
-        vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
-        totalOffset.x *= 0.5f * inverseScaleX;
-        totalOffset.y *= 0.5f * inverseScaleY;
-
-        AlphaVertex::set(&buffer[currentIndex++],
-                current->position[0] + totalOffset.x,
-                current->position[1] + totalOffset.y,
-                0.0f);
-        AlphaVertex::set(&buffer[currentIndex++],
-                current->position[0] - totalOffset.x,
-                current->position[1] - totalOffset.y,
-                1.0f);
-
-        last = current;
-        current = next;
-        lastNormal = nextNormal;
-    }
-
-    // wrap around to beginning
-    copyAlphaVertex(&buffer[currentIndex++], &buffer[0]);
-    copyAlphaVertex(&buffer[currentIndex++], &buffer[1]);
-
-    // zig zag between all previous points on the inside of the hull to create a
-    // triangle strip that fills the hull, repeating the first inner point to
-    // create degenerate tris to start inside path
-    int srcAindex = 0;
-    int srcBindex = perimeter.size() - 1;
-    while (srcAindex <= srcBindex) {
-        copyAlphaVertex(&buffer[currentIndex++], &buffer[srcAindex * 2 + 1]);
-        if (srcAindex == srcBindex) break;
-        copyAlphaVertex(&buffer[currentIndex++], &buffer[srcBindex * 2 + 1]);
-        srcAindex++;
-        srcBindex--;
-    }
-
-#if VERTEX_DEBUG
-    for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) {
-        ALOGD("point at %f %f, alpha %f", buffer[i].position[0], buffer[i].position[1], buffer[i].alpha);
-    }
-#endif
-}
-
-
-void getStrokeVerticesFromUnclosedVerticesAA(const Vector<Vertex>& vertices, float halfStrokeWidth,
-        VertexBuffer& vertexBuffer, float inverseScaleX, float inverseScaleY) {
-    AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(6 * vertices.size() + 2);
-
-    // avoid lines smaller than hairline since they break triangle based sampling. instead reducing
-    // alpha value (TODO: support different X/Y scale)
-    float maxAlpha = 1.0f;
-    if (halfStrokeWidth != 0 && inverseScaleX == inverseScaleY &&
-            halfStrokeWidth * inverseScaleX < 0.5f) {
-        maxAlpha *= (2 * halfStrokeWidth) / inverseScaleX;
-        halfStrokeWidth = 0.0f;
-    }
-
-    // there is no outer/inner here, using them for consistency with below approach
-    int offset = 2 * (vertices.size() - 2);
-    int currentAAOuterIndex = 2;
-    int currentAAInnerIndex = 2 * offset + 5; // reversed
-    int currentStrokeIndex = currentAAInnerIndex + 7;
-
-    const Vertex* last = &(vertices[0]);
-    const Vertex* current = &(vertices[1]);
-    vec2 lastNormal(current->position[1] - last->position[1],
-            last->position[0] - current->position[0]);
-    lastNormal.normalize();
-
-    {
-        // start cap
-        vec2 totalOffset = lastNormal;
-        vec2 AAOffset = totalOffset;
-        AAOffset.x *= 0.5f * inverseScaleX;
-        AAOffset.y *= 0.5f * inverseScaleY;
-
-        vec2 innerOffset = totalOffset;
-        scaleOffsetForStrokeWidth(innerOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
-        vec2 outerOffset = innerOffset + AAOffset;
-        innerOffset -= AAOffset;
-
-        // TODO: support square cap by changing this offset to incorporate halfStrokeWidth
-        vec2 capAAOffset(AAOffset.y, -AAOffset.x);
-        AlphaVertex::set(&buffer[0],
-                last->position[0] + outerOffset.x + capAAOffset.x,
-                last->position[1] + outerOffset.y + capAAOffset.y,
-                0.0f);
-        AlphaVertex::set(&buffer[1],
-                last->position[0] + innerOffset.x - capAAOffset.x,
-                last->position[1] + innerOffset.y - capAAOffset.y,
-                maxAlpha);
-
-        AlphaVertex::set(&buffer[2 * offset + 6],
-                last->position[0] - outerOffset.x + capAAOffset.x,
-                last->position[1] - outerOffset.y + capAAOffset.y,
-                0.0f);
-        AlphaVertex::set(&buffer[2 * offset + 7],
-                last->position[0] - innerOffset.x - capAAOffset.x,
-                last->position[1] - innerOffset.y - capAAOffset.y,
-                maxAlpha);
-        copyAlphaVertex(&buffer[2 * offset + 8], &buffer[0]);
-        copyAlphaVertex(&buffer[2 * offset + 9], &buffer[1]);
-        copyAlphaVertex(&buffer[2 * offset + 10], &buffer[1]); // degenerate tris (the only two!)
-        copyAlphaVertex(&buffer[2 * offset + 11], &buffer[2 * offset + 7]);
-    }
-
-    for (unsigned int i = 1; i < vertices.size() - 1; i++) {
-        const Vertex* next = &(vertices[i + 1]);
-        vec2 nextNormal(next->position[1] - current->position[1],
-                current->position[0] - next->position[0]);
-        nextNormal.normalize();
-
-        vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
-        vec2 AAOffset = totalOffset;
-        AAOffset.x *= 0.5f * inverseScaleX;
-        AAOffset.y *= 0.5f * inverseScaleY;
-
-        vec2 innerOffset = totalOffset;
-        scaleOffsetForStrokeWidth(innerOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
-        vec2 outerOffset = innerOffset + AAOffset;
-        innerOffset -= AAOffset;
-
-        AlphaVertex::set(&buffer[currentAAOuterIndex++],
-                current->position[0] + outerOffset.x,
-                current->position[1] + outerOffset.y,
-                0.0f);
-        AlphaVertex::set(&buffer[currentAAOuterIndex++],
-                current->position[0] + innerOffset.x,
-                current->position[1] + innerOffset.y,
-                maxAlpha);
-
-        AlphaVertex::set(&buffer[currentStrokeIndex++],
-                current->position[0] + innerOffset.x,
-                current->position[1] + innerOffset.y,
-                maxAlpha);
-        AlphaVertex::set(&buffer[currentStrokeIndex++],
-                current->position[0] - innerOffset.x,
-                current->position[1] - innerOffset.y,
-                maxAlpha);
-
-        AlphaVertex::set(&buffer[currentAAInnerIndex--],
-                current->position[0] - innerOffset.x,
-                current->position[1] - innerOffset.y,
-                maxAlpha);
-        AlphaVertex::set(&buffer[currentAAInnerIndex--],
-                current->position[0] - outerOffset.x,
-                current->position[1] - outerOffset.y,
-                0.0f);
-
-        last = current;
-        current = next;
-        lastNormal = nextNormal;
-    }
-
-    {
-        // end cap
-        vec2 totalOffset = lastNormal;
-        vec2 AAOffset = totalOffset;
-        AAOffset.x *= 0.5f * inverseScaleX;
-        AAOffset.y *= 0.5f * inverseScaleY;
-
-        vec2 innerOffset = totalOffset;
-        scaleOffsetForStrokeWidth(innerOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
-        vec2 outerOffset = innerOffset + AAOffset;
-        innerOffset -= AAOffset;
-
-        // TODO: support square cap by changing this offset to incorporate halfStrokeWidth
-        vec2 capAAOffset(-AAOffset.y, AAOffset.x);
-
-        AlphaVertex::set(&buffer[offset + 2],
-                current->position[0] + outerOffset.x + capAAOffset.x,
-                current->position[1] + outerOffset.y + capAAOffset.y,
-                0.0f);
-        AlphaVertex::set(&buffer[offset + 3],
-                current->position[0] + innerOffset.x - capAAOffset.x,
-                current->position[1] + innerOffset.y - capAAOffset.y,
-                maxAlpha);
-
-        AlphaVertex::set(&buffer[offset + 4],
-                current->position[0] - outerOffset.x + capAAOffset.x,
-                current->position[1] - outerOffset.y + capAAOffset.y,
-                0.0f);
-        AlphaVertex::set(&buffer[offset + 5],
-                current->position[0] - innerOffset.x - capAAOffset.x,
-                current->position[1] - innerOffset.y - capAAOffset.y,
-                maxAlpha);
-
-        copyAlphaVertex(&buffer[vertexBuffer.getSize() - 2], &buffer[offset + 3]);
-        copyAlphaVertex(&buffer[vertexBuffer.getSize() - 1], &buffer[offset + 5]);
-    }
-
-#if VERTEX_DEBUG
-    for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) {
-        ALOGD("point at %f %f, alpha %f", buffer[i].position[0], buffer[i].position[1], buffer[i].alpha);
-    }
-#endif
-}
-
-
-void getStrokeVerticesFromPerimeterAA(const Vector<Vertex>& perimeter, float halfStrokeWidth,
-        VertexBuffer& vertexBuffer, float inverseScaleX, float inverseScaleY) {
-    AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(6 * perimeter.size() + 8);
-
-    // avoid lines smaller than hairline since they break triangle based sampling. instead reducing
-    // alpha value (TODO: support different X/Y scale)
-    float maxAlpha = 1.0f;
-    if (halfStrokeWidth != 0 && inverseScaleX == inverseScaleY &&
-            halfStrokeWidth * inverseScaleX < 0.5f) {
-        maxAlpha *= (2 * halfStrokeWidth) / inverseScaleX;
-        halfStrokeWidth = 0.0f;
-    }
-
-    int offset = 2 * perimeter.size() + 3;
-    int currentAAOuterIndex = 0;
-    int currentStrokeIndex = offset;
-    int currentAAInnerIndex = offset * 2;
-
-    const Vertex* last = &(perimeter[perimeter.size() - 1]);
-    const Vertex* current = &(perimeter[0]);
-    vec2 lastNormal(current->position[1] - last->position[1],
-            last->position[0] - current->position[0]);
-    lastNormal.normalize();
-    for (unsigned int i = 0; i < perimeter.size(); i++) {
-        const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
-        vec2 nextNormal(next->position[1] - current->position[1],
-                current->position[0] - next->position[0]);
-        nextNormal.normalize();
-
-        vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
-        vec2 AAOffset = totalOffset;
-        AAOffset.x *= 0.5f * inverseScaleX;
-        AAOffset.y *= 0.5f * inverseScaleY;
-
-        vec2 innerOffset = totalOffset;
-        scaleOffsetForStrokeWidth(innerOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
-        vec2 outerOffset = innerOffset + AAOffset;
-        innerOffset -= AAOffset;
-
-        AlphaVertex::set(&buffer[currentAAOuterIndex++],
-                current->position[0] + outerOffset.x,
-                current->position[1] + outerOffset.y,
-                0.0f);
-        AlphaVertex::set(&buffer[currentAAOuterIndex++],
-                current->position[0] + innerOffset.x,
-                current->position[1] + innerOffset.y,
-                maxAlpha);
-
-        AlphaVertex::set(&buffer[currentStrokeIndex++],
-                current->position[0] + innerOffset.x,
-                current->position[1] + innerOffset.y,
-                maxAlpha);
-        AlphaVertex::set(&buffer[currentStrokeIndex++],
-                current->position[0] - innerOffset.x,
-                current->position[1] - innerOffset.y,
-                maxAlpha);
-
-        AlphaVertex::set(&buffer[currentAAInnerIndex++],
-                current->position[0] - innerOffset.x,
-                current->position[1] - innerOffset.y,
-                maxAlpha);
-        AlphaVertex::set(&buffer[currentAAInnerIndex++],
-                current->position[0] - outerOffset.x,
-                current->position[1] - outerOffset.y,
-                0.0f);
-
-        last = current;
-        current = next;
-        lastNormal = nextNormal;
-    }
-
-    // wrap each strip around to beginning, creating degenerate tris to bridge strips
-    copyAlphaVertex(&buffer[currentAAOuterIndex++], &buffer[0]);
-    copyAlphaVertex(&buffer[currentAAOuterIndex++], &buffer[1]);
-    copyAlphaVertex(&buffer[currentAAOuterIndex++], &buffer[1]);
-
-    copyAlphaVertex(&buffer[currentStrokeIndex++], &buffer[offset]);
-    copyAlphaVertex(&buffer[currentStrokeIndex++], &buffer[offset + 1]);
-    copyAlphaVertex(&buffer[currentStrokeIndex++], &buffer[offset + 1]);
-
-    copyAlphaVertex(&buffer[currentAAInnerIndex++], &buffer[2 * offset]);
-    copyAlphaVertex(&buffer[currentAAInnerIndex++], &buffer[2 * offset + 1]);
-    // don't need to create last degenerate tri
-
-#if VERTEX_DEBUG
-    for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) {
-        ALOGD("point at %f %f, alpha %f", buffer[i].position[0], buffer[i].position[1], buffer[i].alpha);
-    }
-#endif
-}
-
-void PathRenderer::convexPathVertices(const SkPath &path, const SkPaint* paint,
-        const mat4 *transform, VertexBuffer& vertexBuffer) {
-    ATRACE_CALL();
-
-    SkPaint::Style style = paint->getStyle();
-    bool isAA = paint->isAntiAlias();
-
-    float inverseScaleX, inverseScaleY;
-    computeInverseScales(transform, inverseScaleX, inverseScaleY);
-
-    Vector<Vertex> tempVertices;
-    float threshInvScaleX = inverseScaleX;
-    float threshInvScaleY = inverseScaleY;
-    if (style == SkPaint::kStroke_Style) {
-        // alter the bezier recursion threshold values we calculate in order to compensate for
-        // expansion done after the path vertices are found
-        SkRect bounds = path.getBounds();
-        if (!bounds.isEmpty()) {
-            threshInvScaleX *= bounds.width() / (bounds.width() + paint->getStrokeWidth());
-            threshInvScaleY *= bounds.height() / (bounds.height() + paint->getStrokeWidth());
-        }
-    }
-
-    // force close if we're filling the path, since fill path expects closed perimeter.
-    bool forceClose = style != SkPaint::kStroke_Style;
-    bool wasClosed = convexPathPerimeterVertices(path, forceClose, threshInvScaleX * threshInvScaleX,
-            threshInvScaleY * threshInvScaleY, tempVertices);
-
-    if (!tempVertices.size()) {
-        // path was empty, return without allocating vertex buffer
-        return;
-    }
-
-#if VERTEX_DEBUG
-    for (unsigned int i = 0; i < tempVertices.size(); i++) {
-        ALOGD("orig path: point at %f %f", tempVertices[i].position[0], tempVertices[i].position[1]);
-    }
-#endif
-
-    if (style == SkPaint::kStroke_Style) {
-        float halfStrokeWidth = paint->getStrokeWidth() * 0.5f;
-        if (!isAA) {
-            if (wasClosed) {
-                getStrokeVerticesFromPerimeter(tempVertices, halfStrokeWidth, vertexBuffer,
-                        inverseScaleX, inverseScaleY);
-            } else {
-                getStrokeVerticesFromUnclosedVertices(tempVertices, halfStrokeWidth, vertexBuffer,
-                        inverseScaleX, inverseScaleY);
-            }
-
-        } else {
-            if (wasClosed) {
-                getStrokeVerticesFromPerimeterAA(tempVertices, halfStrokeWidth, vertexBuffer,
-                        inverseScaleX, inverseScaleY);
-            } else {
-                getStrokeVerticesFromUnclosedVerticesAA(tempVertices, halfStrokeWidth, vertexBuffer,
-                        inverseScaleX, inverseScaleY);
-            }
-        }
-    } else {
-        // For kStrokeAndFill style, the path should be adjusted externally, as it will be treated as a fill here.
-        if (!isAA) {
-            getFillVerticesFromPerimeter(tempVertices, vertexBuffer);
-        } else {
-            getFillVerticesFromPerimeterAA(tempVertices, vertexBuffer, inverseScaleX, inverseScaleY);
-        }
-    }
-}
-
-
-void pushToVector(Vector<Vertex>& vertices, float x, float y) {
-    // TODO: make this not yuck
-    vertices.push();
-    Vertex* newVertex = &(vertices.editArray()[vertices.size() - 1]);
-    Vertex::set(newVertex, x, y);
-}
-
-bool PathRenderer::convexPathPerimeterVertices(const SkPath& path, bool forceClose,
-        float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex>& outputVertices) {
-    ATRACE_CALL();
-
-    // TODO: to support joins other than sharp miter, join vertices should be labelled in the
-    // perimeter, or resolved into more vertices. Reconsider forceClose-ing in that case.
-    SkPath::Iter iter(path, forceClose);
-    SkPoint pts[4];
-    SkPath::Verb v;
-    while (SkPath::kDone_Verb != (v = iter.next(pts))) {
-            switch (v) {
-                case SkPath::kMove_Verb:
-                    pushToVector(outputVertices, pts[0].x(), pts[0].y());
-                    ALOGV("Move to pos %f %f", pts[0].x(), pts[0].y());
-                    break;
-                case SkPath::kClose_Verb:
-                    ALOGV("Close at pos %f %f", pts[0].x(), pts[0].y());
-                    break;
-                case SkPath::kLine_Verb:
-                    ALOGV("kLine_Verb %f %f -> %f %f",
-                            pts[0].x(), pts[0].y(),
-                            pts[1].x(), pts[1].y());
-
-                    pushToVector(outputVertices, pts[1].x(), pts[1].y());
-                    break;
-                case SkPath::kQuad_Verb:
-                    ALOGV("kQuad_Verb");
-                    recursiveQuadraticBezierVertices(
-                            pts[0].x(), pts[0].y(),
-                            pts[2].x(), pts[2].y(),
-                            pts[1].x(), pts[1].y(),
-                            sqrInvScaleX, sqrInvScaleY, outputVertices);
-                    break;
-                case SkPath::kCubic_Verb:
-                    ALOGV("kCubic_Verb");
-                    recursiveCubicBezierVertices(
-                            pts[0].x(), pts[0].y(),
-                            pts[1].x(), pts[1].y(),
-                            pts[3].x(), pts[3].y(),
-                            pts[2].x(), pts[2].y(),
-                        sqrInvScaleX, sqrInvScaleY, outputVertices);
-                    break;
-                default:
-                    break;
-            }
-    }
-
-    int size = outputVertices.size();
-    if (size >= 2 && outputVertices[0].position[0] == outputVertices[size - 1].position[0] &&
-            outputVertices[0].position[1] == outputVertices[size - 1].position[1]) {
-        outputVertices.pop();
-        return true;
-    }
-    return false;
-}
-
-void PathRenderer::recursiveCubicBezierVertices(
-        float p1x, float p1y, float c1x, float c1y,
-        float p2x, float p2y, float c2x, float c2y,
-        float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex>& outputVertices) {
-    float dx = p2x - p1x;
-    float dy = p2y - p1y;
-    float d1 = fabs((c1x - p2x) * dy - (c1y - p2y) * dx);
-    float d2 = fabs((c2x - p2x) * dy - (c2y - p2y) * dx);
-    float d = d1 + d2;
-
-    // multiplying by sqrInvScaleY/X equivalent to multiplying in dimensional scale factors
-
-    if (d * d < THRESHOLD * THRESHOLD * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
-        // below thresh, draw line by adding endpoint
-        pushToVector(outputVertices, p2x, p2y);
-    } else {
-        float p1c1x = (p1x + c1x) * 0.5f;
-        float p1c1y = (p1y + c1y) * 0.5f;
-        float p2c2x = (p2x + c2x) * 0.5f;
-        float p2c2y = (p2y + c2y) * 0.5f;
-
-        float c1c2x = (c1x + c2x) * 0.5f;
-        float c1c2y = (c1y + c2y) * 0.5f;
-
-        float p1c1c2x = (p1c1x + c1c2x) * 0.5f;
-        float p1c1c2y = (p1c1y + c1c2y) * 0.5f;
-
-        float p2c1c2x = (p2c2x + c1c2x) * 0.5f;
-        float p2c1c2y = (p2c2y + c1c2y) * 0.5f;
-
-        float mx = (p1c1c2x + p2c1c2x) * 0.5f;
-        float my = (p1c1c2y + p2c1c2y) * 0.5f;
-
-        recursiveCubicBezierVertices(
-                p1x, p1y, p1c1x, p1c1y,
-                mx, my, p1c1c2x, p1c1c2y,
-                sqrInvScaleX, sqrInvScaleY, outputVertices);
-        recursiveCubicBezierVertices(
-                mx, my, p2c1c2x, p2c1c2y,
-                p2x, p2y, p2c2x, p2c2y,
-                sqrInvScaleX, sqrInvScaleY, outputVertices);
-    }
-}
-
-void PathRenderer::recursiveQuadraticBezierVertices(
-        float ax, float ay,
-        float bx, float by,
-        float cx, float cy,
-        float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex>& outputVertices) {
-    float dx = bx - ax;
-    float dy = by - ay;
-    float d = (cx - bx) * dy - (cy - by) * dx;
-
-    if (d * d < THRESHOLD * THRESHOLD * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
-        // below thresh, draw line by adding endpoint
-        pushToVector(outputVertices, bx, by);
-    } else {
-        float acx = (ax + cx) * 0.5f;
-        float bcx = (bx + cx) * 0.5f;
-        float acy = (ay + cy) * 0.5f;
-        float bcy = (by + cy) * 0.5f;
-
-        // midpoint
-        float mx = (acx + bcx) * 0.5f;
-        float my = (acy + bcy) * 0.5f;
-
-        recursiveQuadraticBezierVertices(ax, ay, mx, my, acx, acy,
-                sqrInvScaleX, sqrInvScaleY, outputVertices);
-        recursiveQuadraticBezierVertices(mx, my, bx, by, bcx, bcy,
-                sqrInvScaleX, sqrInvScaleY, outputVertices);
-    }
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/PathRenderer.h b/libs/hwui/PathRenderer.h
deleted file mode 100644
index e9f347b..0000000
--- a/libs/hwui/PathRenderer.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HWUI_PATH_RENDERER_H
-#define ANDROID_HWUI_PATH_RENDERER_H
-
-#include <utils/Vector.h>
-
-#include "Vertex.h"
-
-namespace android {
-namespace uirenderer {
-
-class Matrix4;
-typedef Matrix4 mat4;
-
-class VertexBuffer {
-public:
-    VertexBuffer():
-        mBuffer(0),
-        mSize(0),
-        mCleanupMethod(0)
-    {}
-
-    ~VertexBuffer() {
-        if (mCleanupMethod)
-            mCleanupMethod(mBuffer);
-    }
-
-    template <class TYPE>
-    TYPE* alloc(int size) {
-        mSize = size;
-        mBuffer = (void*)new TYPE[size];
-        mCleanupMethod = &(cleanup<TYPE>);
-
-        return (TYPE*)mBuffer;
-    }
-
-    void* getBuffer() { return mBuffer; }
-    unsigned int getSize() { return mSize; }
-
-private:
-    template <class TYPE>
-    static void cleanup(void* buffer) {
-        delete[] (TYPE*)buffer;
-    }
-
-    void* mBuffer;
-    unsigned int mSize;
-    void (*mCleanupMethod)(void*);
-};
-
-class PathRenderer {
-public:
-    static SkRect computePathBounds(const SkPath& path, const SkPaint* paint);
-
-    static void convexPathVertices(const SkPath& path, const SkPaint* paint,
-            const mat4 *transform, VertexBuffer& vertexBuffer);
-
-private:
-    static bool convexPathPerimeterVertices(const SkPath &path, bool forceClose,
-        float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex> &outputVertices);
-
-/*
-  endpoints a & b,
-  control c
- */
-    static void recursiveQuadraticBezierVertices(
-            float ax, float ay,
-            float bx, float by,
-            float cx, float cy,
-            float sqrInvScaleX, float sqrInvScaleY,
-            Vector<Vertex> &outputVertices);
-
-/*
-  endpoints p1, p2
-  control c1, c2
- */
-    static void recursiveCubicBezierVertices(
-            float p1x, float p1y,
-            float c1x, float c1y,
-            float p2x, float p2y,
-            float c2x, float c2y,
-            float sqrInvScaleX, float sqrInvScaleY,
-            Vector<Vertex> &outputVertices);
-};
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_PATH_RENDERER_H
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
new file mode 100644
index 0000000..69ccdfa
--- /dev/null
+++ b/libs/hwui/PathTessellator.cpp
@@ -0,0 +1,970 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "PathTessellator"
+#define LOG_NDEBUG 1
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#define VERTEX_DEBUG 0
+
+#if VERTEX_DEBUG
+#define DEBUG_DUMP_ALPHA_BUFFER() \
+    for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) { \
+        ALOGD("point %d at %f %f, alpha %f", \
+        i, buffer[i].position[0], buffer[i].position[1], buffer[i].alpha); \
+    }
+#define DEBUG_DUMP_BUFFER() \
+    for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) { \
+        ALOGD("point %d at %f %f", i, buffer[i].position[0], buffer[i].position[1]); \
+    }
+#else
+#define DEBUG_DUMP_ALPHA_BUFFER()
+#define DEBUG_DUMP_BUFFER()
+#endif
+
+#include <SkPath.h>
+#include <SkPaint.h>
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Log.h>
+#include <utils/Trace.h>
+
+#include "PathTessellator.h"
+#include "Matrix.h"
+#include "Vector.h"
+#include "Vertex.h"
+
+namespace android {
+namespace uirenderer {
+
+#define THRESHOLD 0.5f
+#define ROUND_CAP_THRESH 0.25f
+#define PI 3.1415926535897932f
+
+void PathTessellator::expandBoundsForStroke(SkRect& bounds, const SkPaint* paint,
+        bool forceExpand) {
+    if (forceExpand || paint->getStyle() != SkPaint::kFill_Style) {
+        float outset = paint->getStrokeWidth() * 0.5f;
+        bounds.outset(outset, outset);
+    }
+}
+
+inline void copyVertex(Vertex* destPtr, const Vertex* srcPtr) {
+    Vertex::set(destPtr, srcPtr->position[0], srcPtr->position[1]);
+}
+
+inline void copyAlphaVertex(AlphaVertex* destPtr, const AlphaVertex* srcPtr) {
+    AlphaVertex::set(destPtr, srcPtr->position[0], srcPtr->position[1], srcPtr->alpha);
+}
+
+/**
+ * Produces a pseudo-normal for a vertex, given the normals of the two incoming lines. If the offset
+ * from each vertex in a perimeter is calculated, the resultant lines connecting the offset vertices
+ * will be offset by 1.0
+ *
+ * Note that we can't add and normalize the two vectors, that would result in a rectangle having an
+ * offset of (sqrt(2)/2, sqrt(2)/2) at each corner, instead of (1, 1)
+ *
+ * NOTE: assumes angles between normals 90 degrees or less
+ */
+inline vec2 totalOffsetFromNormals(const vec2& normalA, const vec2& normalB) {
+    return (normalA + normalB) / (1 + fabs(normalA.dot(normalB)));
+}
+
+/**
+ * Structure used for storing useful information about the SkPaint and scale used for tessellating
+ */
+struct PaintInfo {
+public:
+    PaintInfo(const SkPaint* paint, const mat4 *transform) :
+            style(paint->getStyle()), cap(paint->getStrokeCap()), isAA(paint->isAntiAlias()),
+            inverseScaleX(1.0f), inverseScaleY(1.0f),
+            halfStrokeWidth(paint->getStrokeWidth() * 0.5f), maxAlpha(1.0f) {
+        // compute inverse scales
+        if (CC_UNLIKELY(!transform->isPureTranslate())) {
+            float m00 = transform->data[Matrix4::kScaleX];
+            float m01 = transform->data[Matrix4::kSkewY];
+            float m10 = transform->data[Matrix4::kSkewX];
+            float m11 = transform->data[Matrix4::kScaleY];
+            float scaleX = sqrt(m00 * m00 + m01 * m01);
+            float scaleY = sqrt(m10 * m10 + m11 * m11);
+            inverseScaleX = (scaleX != 0) ? (1.0f / scaleX) : 1.0f;
+            inverseScaleY = (scaleY != 0) ? (1.0f / scaleY) : 1.0f;
+        }
+
+        if (isAA && halfStrokeWidth != 0 && inverseScaleX == inverseScaleY &&
+                halfStrokeWidth * inverseScaleX < 0.5f) {
+            maxAlpha *= (2 * halfStrokeWidth) / inverseScaleX;
+            halfStrokeWidth = 0.0f;
+        }
+    }
+
+    SkPaint::Style style;
+    SkPaint::Cap cap;
+    bool isAA;
+    float inverseScaleX;
+    float inverseScaleY;
+    float halfStrokeWidth;
+    float maxAlpha;
+
+    inline void scaleOffsetForStrokeWidth(vec2& offset) const {
+        if (halfStrokeWidth == 0.0f) {
+            // hairline - compensate for scale
+            offset.x *= 0.5f * inverseScaleX;
+            offset.y *= 0.5f * inverseScaleY;
+        } else {
+            offset *= halfStrokeWidth;
+        }
+    }
+
+    /**
+     * NOTE: the input will not always be a normal, especially for sharp edges - it should be the
+     * result of totalOffsetFromNormals (see documentation there)
+     */
+    inline vec2 deriveAAOffset(const vec2& offset) const {
+        return vec2(offset.x * 0.5f * inverseScaleX,
+            offset.y * 0.5f * inverseScaleY);
+    }
+
+    /**
+     * Returns the number of cap divisions beyond the minimum 2 (kButt_Cap/kSquareCap will return 0)
+     * Should only be used when stroking and drawing caps
+     */
+    inline int capExtraDivisions() const {
+        if (cap == SkPaint::kRound_Cap) {
+            if (halfStrokeWidth == 0.0f) return 2;
+
+            // ROUND_CAP_THRESH is the maximum error for polygonal approximation of the round cap
+            const float errConst = (-ROUND_CAP_THRESH / halfStrokeWidth + 1);
+            const float targetCosVal = 2 * errConst * errConst - 1;
+            int neededDivisions = (int)(ceilf(PI / acos(targetCosVal)/2)) * 2;
+            return neededDivisions;
+        }
+        return 0;
+    }
+};
+
+void getFillVerticesFromPerimeter(const Vector<Vertex>& perimeter, VertexBuffer& vertexBuffer) {
+    Vertex* buffer = vertexBuffer.alloc<Vertex>(perimeter.size());
+
+    int currentIndex = 0;
+    // zig zag between all previous points on the inside of the hull to create a
+    // triangle strip that fills the hull
+    int srcAindex = 0;
+    int srcBindex = perimeter.size() - 1;
+    while (srcAindex <= srcBindex) {
+        copyVertex(&buffer[currentIndex++], &perimeter[srcAindex]);
+        if (srcAindex == srcBindex) break;
+        copyVertex(&buffer[currentIndex++], &perimeter[srcBindex]);
+        srcAindex++;
+        srcBindex--;
+    }
+}
+
+/*
+ * Fills a vertexBuffer with non-alpha vertices, zig-zagging at each perimeter point to create a
+ * tri-strip as wide as the stroke.
+ *
+ * Uses an additional 2 vertices at the end to wrap around, closing the tri-strip
+ * (for a total of perimeter.size() * 2 + 2 vertices)
+ */
+void getStrokeVerticesFromPerimeter(const PaintInfo& paintInfo, const Vector<Vertex>& perimeter,
+        VertexBuffer& vertexBuffer) {
+    Vertex* buffer = vertexBuffer.alloc<Vertex>(perimeter.size() * 2 + 2);
+
+    int currentIndex = 0;
+    const Vertex* last = &(perimeter[perimeter.size() - 1]);
+    const Vertex* current = &(perimeter[0]);
+    vec2 lastNormal(current->position[1] - last->position[1],
+            last->position[0] - current->position[0]);
+    lastNormal.normalize();
+    for (unsigned int i = 0; i < perimeter.size(); i++) {
+        const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
+        vec2 nextNormal(next->position[1] - current->position[1],
+                current->position[0] - next->position[0]);
+        nextNormal.normalize();
+
+        vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
+        paintInfo.scaleOffsetForStrokeWidth(totalOffset);
+
+        Vertex::set(&buffer[currentIndex++],
+                current->position[0] + totalOffset.x,
+                current->position[1] + totalOffset.y);
+
+        Vertex::set(&buffer[currentIndex++],
+                current->position[0] - totalOffset.x,
+                current->position[1] - totalOffset.y);
+
+        last = current;
+        current = next;
+        lastNormal = nextNormal;
+    }
+
+    // wrap around to beginning
+    copyVertex(&buffer[currentIndex++], &buffer[0]);
+    copyVertex(&buffer[currentIndex++], &buffer[1]);
+
+    DEBUG_DUMP_BUFFER();
+}
+
+/**
+ * Fills a vertexBuffer with non-alpha vertices similar to getStrokeVerticesFromPerimeter, except:
+ *
+ * 1 - Doesn't need to wrap around, since the input vertices are unclosed
+ *
+ * 2 - can zig-zag across 'extra' vertices at either end, to create round caps
+ */
+void getStrokeVerticesFromUnclosedVertices(const PaintInfo& paintInfo,
+        const Vector<Vertex>& vertices, VertexBuffer& vertexBuffer) {
+    const int extra = paintInfo.capExtraDivisions();
+    const int allocSize = (vertices.size() + extra) * 2;
+
+    Vertex* buffer = vertexBuffer.alloc<Vertex>(allocSize);
+
+    if (extra > 0) {
+        // tessellate both round caps
+        const int last = vertices.size() - 1;
+        float beginTheta = atan2(
+                - (vertices[0].position[0] - vertices[1].position[0]),
+                vertices[0].position[1] - vertices[1].position[1]);
+        float endTheta = atan2(
+                - (vertices[last].position[0] - vertices[last - 1].position[0]),
+                vertices[last].position[1] - vertices[last - 1].position[1]);
+
+        const float dTheta = PI / (extra + 1);
+        const float radialScale = 2.0f / (1 + cos(dTheta));
+
+        int capOffset;
+        for (int i = 0; i < extra; i++) {
+            if (i < extra / 2) {
+                capOffset = extra - 2 * i - 1;
+            } else {
+                capOffset = 2 * i - extra;
+            }
+
+            beginTheta += dTheta;
+            vec2 beginRadialOffset(cos(beginTheta), sin(beginTheta));
+            paintInfo.scaleOffsetForStrokeWidth(beginRadialOffset);
+            Vertex::set(&buffer[capOffset],
+                    vertices[0].position[0] + beginRadialOffset.x,
+                    vertices[0].position[1] + beginRadialOffset.y);
+
+            endTheta += dTheta;
+            vec2 endRadialOffset(cos(endTheta), sin(endTheta));
+            paintInfo.scaleOffsetForStrokeWidth(endRadialOffset);
+            Vertex::set(&buffer[allocSize - 1 - capOffset],
+                    vertices[last].position[0] + endRadialOffset.x,
+                    vertices[last].position[1] + endRadialOffset.y);
+        }
+    }
+
+    int currentIndex = extra;
+    const Vertex* current = &(vertices[0]);
+    vec2 lastNormal;
+    for (unsigned int i = 0; i < vertices.size() - 1; i++) {
+        const Vertex* next = &(vertices[i + 1]);
+        vec2 nextNormal(next->position[1] - current->position[1],
+                current->position[0] - next->position[0]);
+        nextNormal.normalize();
+
+        vec2 totalOffset;
+        if (i == 0) {
+            totalOffset = nextNormal;
+        } else {
+            totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
+        }
+        paintInfo.scaleOffsetForStrokeWidth(totalOffset);
+
+        Vertex::set(&buffer[currentIndex++],
+                current->position[0] + totalOffset.x,
+                current->position[1] + totalOffset.y);
+
+        Vertex::set(&buffer[currentIndex++],
+                current->position[0] - totalOffset.x,
+                current->position[1] - totalOffset.y);
+
+        current = next;
+        lastNormal = nextNormal;
+    }
+
+    vec2 totalOffset = lastNormal;
+    paintInfo.scaleOffsetForStrokeWidth(totalOffset);
+
+    Vertex::set(&buffer[currentIndex++],
+            current->position[0] + totalOffset.x,
+            current->position[1] + totalOffset.y);
+    Vertex::set(&buffer[currentIndex++],
+            current->position[0] - totalOffset.x,
+            current->position[1] - totalOffset.y);
+
+    DEBUG_DUMP_BUFFER();
+}
+
+/**
+ * Populates a vertexBuffer with AlphaVertices to create an anti-aliased fill shape tessellation
+ * 
+ * 1 - create the AA perimeter of unit width, by zig-zagging at each point around the perimeter of
+ * the shape (using 2 * perimeter.size() vertices)
+ *
+ * 2 - wrap around to the beginning to complete the perimeter (2 vertices)
+ *
+ * 3 - zig zag back and forth inside the shape to fill it (using perimeter.size() vertices)
+ */
+void getFillVerticesFromPerimeterAA(const PaintInfo& paintInfo, const Vector<Vertex>& perimeter,
+        VertexBuffer& vertexBuffer) {
+    AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(perimeter.size() * 3 + 2);
+
+    // generate alpha points - fill Alpha vertex gaps in between each point with
+    // alpha 0 vertex, offset by a scaled normal.
+    int currentIndex = 0;
+    const Vertex* last = &(perimeter[perimeter.size() - 1]);
+    const Vertex* current = &(perimeter[0]);
+    vec2 lastNormal(current->position[1] - last->position[1],
+            last->position[0] - current->position[0]);
+    lastNormal.normalize();
+    for (unsigned int i = 0; i < perimeter.size(); i++) {
+        const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
+        vec2 nextNormal(next->position[1] - current->position[1],
+                current->position[0] - next->position[0]);
+        nextNormal.normalize();
+
+        // AA point offset from original point is that point's normal, such that each side is offset
+        // by .5 pixels
+        vec2 totalOffset = paintInfo.deriveAAOffset(totalOffsetFromNormals(lastNormal, nextNormal));
+
+        AlphaVertex::set(&buffer[currentIndex++],
+                current->position[0] + totalOffset.x,
+                current->position[1] + totalOffset.y,
+                0.0f);
+        AlphaVertex::set(&buffer[currentIndex++],
+                current->position[0] - totalOffset.x,
+                current->position[1] - totalOffset.y,
+                1.0f);
+
+        last = current;
+        current = next;
+        lastNormal = nextNormal;
+    }
+
+    // wrap around to beginning
+    copyAlphaVertex(&buffer[currentIndex++], &buffer[0]);
+    copyAlphaVertex(&buffer[currentIndex++], &buffer[1]);
+
+    // zig zag between all previous points on the inside of the hull to create a
+    // triangle strip that fills the hull, repeating the first inner point to
+    // create degenerate tris to start inside path
+    int srcAindex = 0;
+    int srcBindex = perimeter.size() - 1;
+    while (srcAindex <= srcBindex) {
+        copyAlphaVertex(&buffer[currentIndex++], &buffer[srcAindex * 2 + 1]);
+        if (srcAindex == srcBindex) break;
+        copyAlphaVertex(&buffer[currentIndex++], &buffer[srcBindex * 2 + 1]);
+        srcAindex++;
+        srcBindex--;
+    }
+
+    DEBUG_DUMP_BUFFER();
+}
+
+/**
+ * Stores geometry for a single, AA-perimeter (potentially rounded) cap
+ *
+ * For explanation of constants and general methodoloyg, see comments for
+ * getStrokeVerticesFromUnclosedVerticesAA() below.
+ */
+inline void storeCapAA(const PaintInfo& paintInfo, const Vector<Vertex>& vertices,
+        AlphaVertex* buffer, bool isFirst, vec2 normal, int offset) {
+    const int extra = paintInfo.capExtraDivisions();
+    const int extraOffset = (extra + 1) / 2;
+    const int capIndex = isFirst
+            ? 2 * offset + 6 + 2 * (extra + extraOffset)
+            : offset + 2 + 2 * extraOffset;
+    if (isFirst) normal *= -1;
+
+    // TODO: this normal should be scaled by radialScale if extra != 0, see totalOffsetFromNormals()
+    vec2 AAOffset = paintInfo.deriveAAOffset(normal);
+
+    vec2 strokeOffset = normal;
+    paintInfo.scaleOffsetForStrokeWidth(strokeOffset);
+    vec2 outerOffset = strokeOffset + AAOffset;
+    vec2 innerOffset = strokeOffset - AAOffset;
+
+    vec2 capAAOffset;
+    if (paintInfo.cap != SkPaint::kRound_Cap) {
+        // if the cap is square or butt, the inside primary cap vertices will be inset in two
+        // directions - both normal to the stroke, and parallel to it.
+        capAAOffset = vec2(-AAOffset.y, AAOffset.x);
+    }
+
+    // determine referencePoint, the center point for the 4 primary cap vertices
+    const Vertex* point = isFirst ? vertices.begin() : (vertices.end() - 1);
+    vec2 referencePoint(point->position[0], point->position[1]);
+    if (paintInfo.cap == SkPaint::kSquare_Cap) {
+        // To account for square cap, move the primary cap vertices (that create the AA edge) by the
+        // stroke offset vector (rotated to be parallel to the stroke)
+        referencePoint += vec2(-strokeOffset.y, strokeOffset.x);
+    }
+
+    AlphaVertex::set(&buffer[capIndex + 0],
+            referencePoint.x + outerOffset.x + capAAOffset.x,
+            referencePoint.y + outerOffset.y + capAAOffset.y,
+            0.0f);
+    AlphaVertex::set(&buffer[capIndex + 1],
+            referencePoint.x + innerOffset.x - capAAOffset.x,
+            referencePoint.y + innerOffset.y - capAAOffset.y,
+            paintInfo.maxAlpha);
+
+    bool isRound = paintInfo.cap == SkPaint::kRound_Cap;
+
+    const int postCapIndex = (isRound && isFirst) ? (2 * extraOffset - 2) : capIndex + (2 * extra);
+    AlphaVertex::set(&buffer[postCapIndex + 2],
+            referencePoint.x - outerOffset.x + capAAOffset.x,
+            referencePoint.y - outerOffset.y + capAAOffset.y,
+            0.0f);
+    AlphaVertex::set(&buffer[postCapIndex + 3],
+            referencePoint.x - innerOffset.x - capAAOffset.x,
+            referencePoint.y - innerOffset.y - capAAOffset.y,
+            paintInfo.maxAlpha);
+
+    if (isRound) {
+        const float dTheta = PI / (extra + 1);
+        const float radialScale = 2.0f / (1 + cos(dTheta));
+        float theta = atan2(normal.y, normal.x);
+        int capPerimIndex = capIndex + 2;
+
+        for (int i = 0; i < extra; i++) {
+            theta += dTheta;
+
+            vec2 radialOffset(cos(theta), sin(theta));
+
+            // scale to compensate for pinching at sharp angles, see totalOffsetFromNormals()
+            radialOffset *= radialScale;
+
+            AAOffset = paintInfo.deriveAAOffset(radialOffset);
+            paintInfo.scaleOffsetForStrokeWidth(radialOffset);
+            AlphaVertex::set(&buffer[capPerimIndex++],
+                    referencePoint.x + radialOffset.x + AAOffset.x,
+                    referencePoint.y + radialOffset.y + AAOffset.y,
+                    0.0f);
+            AlphaVertex::set(&buffer[capPerimIndex++],
+                    referencePoint.x + radialOffset.x - AAOffset.x,
+                    referencePoint.y + radialOffset.y - AAOffset.y,
+                    paintInfo.maxAlpha);
+
+            if (isFirst && i == extra - extraOffset) {
+                //copy most recent two points to first two points
+                copyAlphaVertex(&buffer[0], &buffer[capPerimIndex - 2]);
+                copyAlphaVertex(&buffer[1], &buffer[capPerimIndex - 1]);
+
+                capPerimIndex = 2; // start writing the rest of the round cap at index 2
+            }
+        }
+
+        if (isFirst) {
+            const int startCapFillIndex = capIndex + 2 * (extra - extraOffset) + 4;
+            int capFillIndex = startCapFillIndex;
+            for (int i = 0; i < extra + 2; i += 2) {
+                copyAlphaVertex(&buffer[capFillIndex++], &buffer[1 + i]);
+                // TODO: to support odd numbers of divisions, break here on the last iteration
+                copyAlphaVertex(&buffer[capFillIndex++], &buffer[startCapFillIndex - 3 - i]);
+            }
+        } else {
+            int capFillIndex = 6 * vertices.size() + 2 + 6 * extra - (extra + 2);
+            for (int i = 0; i < extra + 2; i += 2) {
+                copyAlphaVertex(&buffer[capFillIndex++], &buffer[capIndex + 1 + i]);
+                // TODO: to support odd numbers of divisions, break here on the last iteration
+                copyAlphaVertex(&buffer[capFillIndex++], &buffer[capIndex + 3 + 2 * extra - i]);
+            }
+        }
+        return;
+    }
+    if (isFirst) {
+        copyAlphaVertex(&buffer[0], &buffer[postCapIndex + 2]);
+        copyAlphaVertex(&buffer[1], &buffer[postCapIndex + 3]);
+        copyAlphaVertex(&buffer[postCapIndex + 4], &buffer[1]); // degenerate tris (the only two!)
+        copyAlphaVertex(&buffer[postCapIndex + 5], &buffer[postCapIndex + 1]);
+    } else {
+        copyAlphaVertex(&buffer[6 * vertices.size()], &buffer[postCapIndex + 1]);
+        copyAlphaVertex(&buffer[6 * vertices.size() + 1], &buffer[postCapIndex + 3]);
+    }
+}
+
+/*
+the geometry for an aa, capped stroke consists of the following:
+
+       # vertices       |    function
+----------------------------------------------------------------------
+a) 2                    | Start AA perimeter
+b) 2, 2 * roundDivOff   | First half of begin cap's perimeter
+                        |
+   2 * middlePts        | 'Outer' or 'Top' AA perimeter half (between caps)
+                        |
+a) 4                    | End cap's
+b) 2, 2 * roundDivs, 2  |    AA perimeter
+                        |
+   2 * middlePts        | 'Inner' or 'bottom' AA perimeter half
+                        |
+a) 6                    | Begin cap's perimeter
+b) 2, 2*(rD - rDO + 1), | Last half of begin cap's perimeter
+       roundDivs, 2     |
+                        |
+   2 * middlePts        | Stroke's full opacity center strip
+                        |
+a) 2                    | end stroke
+b) 2, roundDivs         |    (and end cap fill, for round)
+
+Notes:
+* rows starting with 'a)' denote the Butt or Square cap vertex use, 'b)' denote Round
+
+* 'middlePts' is (number of points in the unclosed input vertex list, minus 2) times two
+
+* 'roundDivs' or 'rD' is the number of extra vertices (beyond the minimum of 2) that define the
+        round cap's shape, and is at least two. This will increase with cap size to sufficiently
+        define the cap's level of tessellation.
+
+* 'roundDivOffset' or 'rDO' is the point about halfway along the start cap's round perimeter, where
+        the stream of vertices for the AA perimeter starts. By starting and ending the perimeter at
+        this offset, the fill of the stroke is drawn from this point with minimal extra vertices.
+
+This means the outer perimeter starts at:
+    outerIndex = (2) OR (2 + 2 * roundDivOff)
+the inner perimeter (since it is filled in reverse) starts at:
+    innerIndex = outerIndex + (4 * middlePts) + ((4) OR (4 + 2 * roundDivs)) - 1
+the stroke starts at:
+    strokeIndex = innerIndex + 1 + ((6) OR (6 + 3 * roundDivs - 2 * roundDivOffset))
+
+The total needed allocated space is either:
+    2 + 4 + 6 + 2 + 3 * (2 * middlePts) = 14 + 6 * middlePts = 2 + 6 * pts
+or, for rounded caps:
+    (2 + 2 * rDO) + (4 + 2 * rD) + (2 * (rD - rDO + 1)
+            + roundDivs + 4) + (2 + roundDivs) + 3 * (2 * middlePts)
+    = 14 + 6 * middlePts + 6 * roundDivs
+    = 2 + 6 * pts + 6 * roundDivs
+ */
+void getStrokeVerticesFromUnclosedVerticesAA(const PaintInfo& paintInfo,
+        const Vector<Vertex>& vertices, VertexBuffer& vertexBuffer) {
+
+    const int extra = paintInfo.capExtraDivisions();
+    const int allocSize = 6 * vertices.size() + 2 + 6 * extra;
+
+    AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(allocSize);
+
+    const int extraOffset = (extra + 1) / 2;
+    int offset = 2 * (vertices.size() - 2);
+    // there is no outer/inner here, using them for consistency with below approach
+    int currentAAOuterIndex = 2 + 2 * extraOffset;
+    int currentAAInnerIndex = currentAAOuterIndex + (2 * offset) + 3 + (2 * extra);
+    int currentStrokeIndex = currentAAInnerIndex + 7 + (3 * extra - 2 * extraOffset);
+
+    const Vertex* last = &(vertices[0]);
+    const Vertex* current = &(vertices[1]);
+    vec2 lastNormal(current->position[1] - last->position[1],
+            last->position[0] - current->position[0]);
+    lastNormal.normalize();
+
+    // TODO: use normal from bezier traversal for cap, instead of from vertices
+    storeCapAA(paintInfo, vertices, buffer, true, lastNormal, offset);
+
+    for (unsigned int i = 1; i < vertices.size() - 1; i++) {
+        const Vertex* next = &(vertices[i + 1]);
+        vec2 nextNormal(next->position[1] - current->position[1],
+                current->position[0] - next->position[0]);
+        nextNormal.normalize();
+
+        vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
+        vec2 AAOffset = paintInfo.deriveAAOffset(totalOffset);
+
+        vec2 innerOffset = totalOffset;
+        paintInfo.scaleOffsetForStrokeWidth(innerOffset);
+        vec2 outerOffset = innerOffset + AAOffset;
+        innerOffset -= AAOffset;
+
+        AlphaVertex::set(&buffer[currentAAOuterIndex++],
+                current->position[0] + outerOffset.x,
+                current->position[1] + outerOffset.y,
+                0.0f);
+        AlphaVertex::set(&buffer[currentAAOuterIndex++],
+                current->position[0] + innerOffset.x,
+                current->position[1] + innerOffset.y,
+                paintInfo.maxAlpha);
+
+        AlphaVertex::set(&buffer[currentStrokeIndex++],
+                current->position[0] + innerOffset.x,
+                current->position[1] + innerOffset.y,
+                paintInfo.maxAlpha);
+        AlphaVertex::set(&buffer[currentStrokeIndex++],
+                current->position[0] - innerOffset.x,
+                current->position[1] - innerOffset.y,
+                paintInfo.maxAlpha);
+
+        AlphaVertex::set(&buffer[currentAAInnerIndex--],
+                current->position[0] - innerOffset.x,
+                current->position[1] - innerOffset.y,
+                paintInfo.maxAlpha);
+        AlphaVertex::set(&buffer[currentAAInnerIndex--],
+                current->position[0] - outerOffset.x,
+                current->position[1] - outerOffset.y,
+                0.0f);
+
+        current = next;
+        lastNormal = nextNormal;
+    }
+
+    // TODO: use normal from bezier traversal for cap, instead of from vertices
+    storeCapAA(paintInfo, vertices, buffer, false, lastNormal, offset);
+
+    DEBUG_DUMP_ALPHA_BUFFER();
+}
+
+
+void getStrokeVerticesFromPerimeterAA(const PaintInfo& paintInfo, const Vector<Vertex>& perimeter,
+        VertexBuffer& vertexBuffer) {
+    AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(6 * perimeter.size() + 8);
+
+    int offset = 2 * perimeter.size() + 3;
+    int currentAAOuterIndex = 0;
+    int currentStrokeIndex = offset;
+    int currentAAInnerIndex = offset * 2;
+
+    const Vertex* last = &(perimeter[perimeter.size() - 1]);
+    const Vertex* current = &(perimeter[0]);
+    vec2 lastNormal(current->position[1] - last->position[1],
+            last->position[0] - current->position[0]);
+    lastNormal.normalize();
+    for (unsigned int i = 0; i < perimeter.size(); i++) {
+        const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
+        vec2 nextNormal(next->position[1] - current->position[1],
+                current->position[0] - next->position[0]);
+        nextNormal.normalize();
+
+        vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
+        vec2 AAOffset = paintInfo.deriveAAOffset(totalOffset);
+
+        vec2 innerOffset = totalOffset;
+        paintInfo.scaleOffsetForStrokeWidth(innerOffset);
+        vec2 outerOffset = innerOffset + AAOffset;
+        innerOffset -= AAOffset;
+
+        AlphaVertex::set(&buffer[currentAAOuterIndex++],
+                current->position[0] + outerOffset.x,
+                current->position[1] + outerOffset.y,
+                0.0f);
+        AlphaVertex::set(&buffer[currentAAOuterIndex++],
+                current->position[0] + innerOffset.x,
+                current->position[1] + innerOffset.y,
+                paintInfo.maxAlpha);
+
+        AlphaVertex::set(&buffer[currentStrokeIndex++],
+                current->position[0] + innerOffset.x,
+                current->position[1] + innerOffset.y,
+                paintInfo.maxAlpha);
+        AlphaVertex::set(&buffer[currentStrokeIndex++],
+                current->position[0] - innerOffset.x,
+                current->position[1] - innerOffset.y,
+                paintInfo.maxAlpha);
+
+        AlphaVertex::set(&buffer[currentAAInnerIndex++],
+                current->position[0] - innerOffset.x,
+                current->position[1] - innerOffset.y,
+                paintInfo.maxAlpha);
+        AlphaVertex::set(&buffer[currentAAInnerIndex++],
+                current->position[0] - outerOffset.x,
+                current->position[1] - outerOffset.y,
+                0.0f);
+
+        last = current;
+        current = next;
+        lastNormal = nextNormal;
+    }
+
+    // wrap each strip around to beginning, creating degenerate tris to bridge strips
+    copyAlphaVertex(&buffer[currentAAOuterIndex++], &buffer[0]);
+    copyAlphaVertex(&buffer[currentAAOuterIndex++], &buffer[1]);
+    copyAlphaVertex(&buffer[currentAAOuterIndex++], &buffer[1]);
+
+    copyAlphaVertex(&buffer[currentStrokeIndex++], &buffer[offset]);
+    copyAlphaVertex(&buffer[currentStrokeIndex++], &buffer[offset + 1]);
+    copyAlphaVertex(&buffer[currentStrokeIndex++], &buffer[offset + 1]);
+
+    copyAlphaVertex(&buffer[currentAAInnerIndex++], &buffer[2 * offset]);
+    copyAlphaVertex(&buffer[currentAAInnerIndex++], &buffer[2 * offset + 1]);
+    // don't need to create last degenerate tri
+
+    DEBUG_DUMP_ALPHA_BUFFER();
+}
+
+void PathTessellator::tessellatePath(const SkPath &path, const SkPaint* paint,
+        const mat4 *transform, VertexBuffer& vertexBuffer) {
+    ATRACE_CALL();
+
+    const PaintInfo paintInfo(paint, transform);
+
+    Vector<Vertex> tempVertices;
+    float threshInvScaleX = paintInfo.inverseScaleX;
+    float threshInvScaleY = paintInfo.inverseScaleY;
+    if (paintInfo.style == SkPaint::kStroke_Style) {
+        // alter the bezier recursion threshold values we calculate in order to compensate for
+        // expansion done after the path vertices are found
+        SkRect bounds = path.getBounds();
+        if (!bounds.isEmpty()) {
+            threshInvScaleX *= bounds.width() / (bounds.width() + paint->getStrokeWidth());
+            threshInvScaleY *= bounds.height() / (bounds.height() + paint->getStrokeWidth());
+        }
+    }
+
+    // force close if we're filling the path, since fill path expects closed perimeter.
+    bool forceClose = paintInfo.style != SkPaint::kStroke_Style;
+    bool wasClosed = approximatePathOutlineVertices(path, forceClose,
+            threshInvScaleX * threshInvScaleX, threshInvScaleY * threshInvScaleY, tempVertices);
+
+    if (!tempVertices.size()) {
+        // path was empty, return without allocating vertex buffer
+        return;
+    }
+
+#if VERTEX_DEBUG
+    for (unsigned int i = 0; i < tempVertices.size(); i++) {
+        ALOGD("orig path: point at %f %f",
+                tempVertices[i].position[0], tempVertices[i].position[1]);
+    }
+#endif
+
+    if (paintInfo.style == SkPaint::kStroke_Style) {
+        if (!paintInfo.isAA) {
+            if (wasClosed) {
+                getStrokeVerticesFromPerimeter(paintInfo, tempVertices, vertexBuffer);
+            } else {
+                getStrokeVerticesFromUnclosedVertices(paintInfo, tempVertices, vertexBuffer);
+            }
+
+        } else {
+            if (wasClosed) {
+                getStrokeVerticesFromPerimeterAA(paintInfo, tempVertices, vertexBuffer);
+            } else {
+                getStrokeVerticesFromUnclosedVerticesAA(paintInfo, tempVertices, vertexBuffer);
+            }
+        }
+    } else {
+        // For kStrokeAndFill style, the path should be adjusted externally.
+        // It will be treated as a fill here.
+        if (!paintInfo.isAA) {
+            getFillVerticesFromPerimeter(tempVertices, vertexBuffer);
+        } else {
+            getFillVerticesFromPerimeterAA(paintInfo, tempVertices, vertexBuffer);
+        }
+    }
+}
+
+static void expandRectToCoverVertex(SkRect& rect, const Vertex& vertex) {
+    rect.fLeft = fminf(rect.fLeft, vertex.position[0]);
+    rect.fTop = fminf(rect.fTop, vertex.position[1]);
+    rect.fRight = fmaxf(rect.fRight, vertex.position[0]);
+    rect.fBottom = fmaxf(rect.fBottom, vertex.position[1]);
+}
+
+void PathTessellator::tessellateLines(const float* points, int count, SkPaint* paint,
+        const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer) {
+    ATRACE_CALL();
+    const PaintInfo paintInfo(paint, transform);
+
+    const int extra = paintInfo.capExtraDivisions();
+    int numLines = count / 4;
+    int lineAllocSize;
+    // pre-allocate space for lines in the buffer, and degenerate tris in between
+    if (paintInfo.isAA) {
+        lineAllocSize = 6 * (2) + 2 + 6 * extra;
+        vertexBuffer.alloc<AlphaVertex>(numLines * lineAllocSize + (numLines - 1) * 2);
+    } else {
+        lineAllocSize = 2 * ((2) + extra);
+        vertexBuffer.alloc<Vertex>(numLines * lineAllocSize + (numLines - 1) * 2);
+    }
+
+    Vector<Vertex> tempVertices;
+    tempVertices.push();
+    tempVertices.push();
+    Vertex* tempVerticesData = tempVertices.editArray();
+    bounds.set(points[0], points[1], points[0], points[1]);
+    for (int i = 0; i < count; i += 4) {
+        Vertex::set(&(tempVerticesData[0]), points[i + 0], points[i + 1]);
+        Vertex::set(&(tempVerticesData[1]), points[i + 2], points[i + 3]);
+
+        if (paintInfo.isAA) {
+            getStrokeVerticesFromUnclosedVerticesAA(paintInfo, tempVertices, vertexBuffer);
+        } else {
+            getStrokeVerticesFromUnclosedVertices(paintInfo, tempVertices, vertexBuffer);
+        }
+
+        // calculate bounds
+        expandRectToCoverVertex(bounds, tempVerticesData[0]);
+        expandRectToCoverVertex(bounds, tempVerticesData[1]);
+    }
+
+    expandBoundsForStroke(bounds, paint, true); // force-expand bounds to incorporate stroke
+
+    // since multiple objects tessellated into buffer, separate them with degen tris
+    if (paintInfo.isAA) {
+        vertexBuffer.createDegenerateSeparators<AlphaVertex>(lineAllocSize);
+    } else {
+        vertexBuffer.createDegenerateSeparators<Vertex>(lineAllocSize);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Simple path line approximation
+///////////////////////////////////////////////////////////////////////////////
+
+void pushToVector(Vector<Vertex>& vertices, float x, float y) {
+    // TODO: make this not yuck
+    vertices.push();
+    Vertex* newVertex = &(vertices.editArray()[vertices.size() - 1]);
+    Vertex::set(newVertex, x, y);
+}
+
+bool PathTessellator::approximatePathOutlineVertices(const SkPath& path, bool forceClose,
+        float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex>& outputVertices) {
+    ATRACE_CALL();
+
+    // TODO: to support joins other than sharp miter, join vertices should be labelled in the
+    // perimeter, or resolved into more vertices. Reconsider forceClose-ing in that case.
+    SkPath::Iter iter(path, forceClose);
+    SkPoint pts[4];
+    SkPath::Verb v;
+    while (SkPath::kDone_Verb != (v = iter.next(pts))) {
+            switch (v) {
+            case SkPath::kMove_Verb:
+                pushToVector(outputVertices, pts[0].x(), pts[0].y());
+                ALOGV("Move to pos %f %f", pts[0].x(), pts[0].y());
+                break;
+            case SkPath::kClose_Verb:
+                ALOGV("Close at pos %f %f", pts[0].x(), pts[0].y());
+                break;
+            case SkPath::kLine_Verb:
+                ALOGV("kLine_Verb %f %f -> %f %f", pts[0].x(), pts[0].y(), pts[1].x(), pts[1].y());
+                pushToVector(outputVertices, pts[1].x(), pts[1].y());
+                break;
+            case SkPath::kQuad_Verb:
+                ALOGV("kQuad_Verb");
+                recursiveQuadraticBezierVertices(
+                        pts[0].x(), pts[0].y(),
+                        pts[2].x(), pts[2].y(),
+                        pts[1].x(), pts[1].y(),
+                        sqrInvScaleX, sqrInvScaleY, outputVertices);
+                break;
+            case SkPath::kCubic_Verb:
+                ALOGV("kCubic_Verb");
+                recursiveCubicBezierVertices(
+                        pts[0].x(), pts[0].y(),
+                        pts[1].x(), pts[1].y(),
+                        pts[3].x(), pts[3].y(),
+                        pts[2].x(), pts[2].y(),
+                        sqrInvScaleX, sqrInvScaleY, outputVertices);
+                break;
+            default:
+                break;
+            }
+    }
+
+    int size = outputVertices.size();
+    if (size >= 2 && outputVertices[0].position[0] == outputVertices[size - 1].position[0] &&
+            outputVertices[0].position[1] == outputVertices[size - 1].position[1]) {
+        outputVertices.pop();
+        return true;
+    }
+    return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Bezier approximation
+///////////////////////////////////////////////////////////////////////////////
+
+void PathTessellator::recursiveCubicBezierVertices(
+        float p1x, float p1y, float c1x, float c1y,
+        float p2x, float p2y, float c2x, float c2y,
+        float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex>& outputVertices) {
+    float dx = p2x - p1x;
+    float dy = p2y - p1y;
+    float d1 = fabs((c1x - p2x) * dy - (c1y - p2y) * dx);
+    float d2 = fabs((c2x - p2x) * dy - (c2y - p2y) * dx);
+    float d = d1 + d2;
+
+    // multiplying by sqrInvScaleY/X equivalent to multiplying in dimensional scale factors
+
+    if (d * d < THRESHOLD * THRESHOLD * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
+        // below thresh, draw line by adding endpoint
+        pushToVector(outputVertices, p2x, p2y);
+    } else {
+        float p1c1x = (p1x + c1x) * 0.5f;
+        float p1c1y = (p1y + c1y) * 0.5f;
+        float p2c2x = (p2x + c2x) * 0.5f;
+        float p2c2y = (p2y + c2y) * 0.5f;
+
+        float c1c2x = (c1x + c2x) * 0.5f;
+        float c1c2y = (c1y + c2y) * 0.5f;
+
+        float p1c1c2x = (p1c1x + c1c2x) * 0.5f;
+        float p1c1c2y = (p1c1y + c1c2y) * 0.5f;
+
+        float p2c1c2x = (p2c2x + c1c2x) * 0.5f;
+        float p2c1c2y = (p2c2y + c1c2y) * 0.5f;
+
+        float mx = (p1c1c2x + p2c1c2x) * 0.5f;
+        float my = (p1c1c2y + p2c1c2y) * 0.5f;
+
+        recursiveCubicBezierVertices(
+                p1x, p1y, p1c1x, p1c1y,
+                mx, my, p1c1c2x, p1c1c2y,
+                sqrInvScaleX, sqrInvScaleY, outputVertices);
+        recursiveCubicBezierVertices(
+                mx, my, p2c1c2x, p2c1c2y,
+                p2x, p2y, p2c2x, p2c2y,
+                sqrInvScaleX, sqrInvScaleY, outputVertices);
+    }
+}
+
+void PathTessellator::recursiveQuadraticBezierVertices(
+        float ax, float ay,
+        float bx, float by,
+        float cx, float cy,
+        float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex>& outputVertices) {
+    float dx = bx - ax;
+    float dy = by - ay;
+    float d = (cx - bx) * dy - (cy - by) * dx;
+
+    if (d * d < THRESHOLD * THRESHOLD * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
+        // below thresh, draw line by adding endpoint
+        pushToVector(outputVertices, bx, by);
+    } else {
+        float acx = (ax + cx) * 0.5f;
+        float bcx = (bx + cx) * 0.5f;
+        float acy = (ay + cy) * 0.5f;
+        float bcy = (by + cy) * 0.5f;
+
+        // midpoint
+        float mx = (acx + bcx) * 0.5f;
+        float my = (acy + bcy) * 0.5f;
+
+        recursiveQuadraticBezierVertices(ax, ay, mx, my, acx, acy,
+                sqrInvScaleX, sqrInvScaleY, outputVertices);
+        recursiveQuadraticBezierVertices(mx, my, bx, by, bcx, bcy,
+                sqrInvScaleX, sqrInvScaleY, outputVertices);
+    }
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/PathTessellator.h b/libs/hwui/PathTessellator.h
new file mode 100644
index 0000000..596d49d
--- /dev/null
+++ b/libs/hwui/PathTessellator.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HWUI_PATH_TESSELLATOR_H
+#define ANDROID_HWUI_PATH_TESSELLATOR_H
+
+#include <utils/Vector.h>
+
+#include "Matrix.h"
+#include "Rect.h"
+#include "Vertex.h"
+
+namespace android {
+namespace uirenderer {
+
+class VertexBuffer {
+public:
+    VertexBuffer():
+        mBuffer(0),
+        mSize(0),
+        mCleanupMethod(NULL)
+    {}
+
+    ~VertexBuffer() {
+        if (mCleanupMethod) mCleanupMethod(mBuffer);
+    }
+
+    /**
+       This should be the only method used by the PathTessellator. Subsequent calls to alloc will
+       allocate space within the first allocation (useful if you want to eventually allocate
+       multiple regions within a single VertexBuffer, such as with PathTessellator::tesselateLines()
+     */
+    template <class TYPE>
+    TYPE* alloc(int size) {
+        if (mSize) {
+            TYPE* reallocBuffer = (TYPE*)mReallocBuffer;
+            // already have allocated the buffer, re-allocate space within
+            if (mReallocBuffer != mBuffer) {
+                // not first re-allocation, leave space for degenerate triangles to separate strips
+                reallocBuffer += 2;
+            }
+            mReallocBuffer = reallocBuffer + size;
+            return reallocBuffer;
+        }
+        mSize = size;
+        mReallocBuffer = mBuffer = (void*)new TYPE[size];
+        mCleanupMethod = &(cleanup<TYPE>);
+
+        return (TYPE*)mBuffer;
+    }
+
+    void* getBuffer() const { return mBuffer; }
+    unsigned int getSize() const { return mSize; }
+
+    template <class TYPE>
+    void createDegenerateSeparators(int allocSize) {
+        TYPE* end = (TYPE*)mBuffer + mSize;
+        for (TYPE* degen = (TYPE*)mBuffer + allocSize; degen < end; degen += 2 + allocSize) {
+            memcpy(degen, degen - 1, sizeof(TYPE));
+            memcpy(degen + 1, degen + 2, sizeof(TYPE));
+        }
+    }
+
+private:
+    template <class TYPE>
+    static void cleanup(void* buffer) {
+        delete[] (TYPE*)buffer;
+    }
+
+    void* mBuffer;
+    unsigned int mSize;
+
+    void* mReallocBuffer; // used for multi-allocation
+
+    void (*mCleanupMethod)(void*);
+};
+
+class PathTessellator {
+public:
+    static void expandBoundsForStroke(SkRect& bounds, const SkPaint* paint, bool forceExpand);
+
+    static void tessellatePath(const SkPath& path, const SkPaint* paint,
+            const mat4 *transform, VertexBuffer& vertexBuffer);
+
+    static void tessellateLines(const float* points, int count, SkPaint* paint,
+            const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer);
+
+private:
+    static bool approximatePathOutlineVertices(const SkPath &path, bool forceClose,
+        float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex> &outputVertices);
+
+/*
+  endpoints a & b,
+  control c
+ */
+    static void recursiveQuadraticBezierVertices(
+            float ax, float ay,
+            float bx, float by,
+            float cx, float cy,
+            float sqrInvScaleX, float sqrInvScaleY,
+            Vector<Vertex> &outputVertices);
+
+/*
+  endpoints p1, p2
+  control c1, c2
+ */
+    static void recursiveCubicBezierVertices(
+            float p1x, float p1y,
+            float c1x, float c1y,
+            float p2x, float p2y,
+            float c2x, float c2y,
+            float sqrInvScaleX, float sqrInvScaleY,
+            Vector<Vertex> &outputVertices);
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_PATH_TESSELLATOR_H
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index 7e3aacf..b1df980 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -81,8 +81,6 @@
 
 #define PROGRAM_IS_SIMPLE_GRADIENT 41
 
-#define PROGRAM_IS_VERTEX_SHAPE_SHIFT 42
-
 ///////////////////////////////////////////////////////////////////////////////
 // Types
 ///////////////////////////////////////////////////////////////////////////////
@@ -129,8 +127,7 @@
     bool hasBitmap;
     bool isBitmapNpot;
 
-    bool isAA;
-    bool isVertexShape;
+    bool isAA; // drawing with a per-vertex alpha
 
     bool hasGradient;
     Gradient gradientType;
@@ -168,7 +165,6 @@
         hasTextureTransform = false;
 
         isAA = false;
-        isVertexShape = false;
 
         modulate = false;
 
@@ -263,7 +259,6 @@
         if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT;
         if (hasGammaCorrection) key |= programid(0x1) << PROGRAM_HAS_GAMMA_CORRECTION;
         if (isSimpleGradient) key |= programid(0x1) << PROGRAM_IS_SIMPLE_GRADIENT;
-        if (isVertexShape) key |= programid(0x1) << PROGRAM_IS_VERTEX_SHAPE_SHIFT;
         return key;
     }
 
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index f536ade..fb00335 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -40,9 +40,6 @@
         "attribute vec4 position;\n";
 const char* gVS_Header_Attributes_TexCoords =
         "attribute vec2 texCoords;\n";
-const char* gVS_Header_Attributes_AALineParameters =
-        "attribute float vtxWidth;\n"
-        "attribute float vtxLength;\n";
 const char* gVS_Header_Attributes_AAVertexShapeParameters =
         "attribute float vtxAlpha;\n";
 const char* gVS_Header_Uniforms_TextureTransform =
@@ -68,9 +65,6 @@
         "uniform mediump vec2 textureDimension;\n";
 const char* gVS_Header_Varyings_HasTexture =
         "varying vec2 outTexCoords;\n";
-const char* gVS_Header_Varyings_IsAALine =
-        "varying float widthProportion;\n"
-        "varying float lengthProportion;\n";
 const char* gVS_Header_Varyings_IsAAVertexShape =
         "varying float alpha;\n";
 const char* gVS_Header_Varyings_HasBitmap =
@@ -129,9 +123,6 @@
         "    gl_Position = projection * transform * position;\n";
 const char* gVS_Main_PointSize =
         "    gl_PointSize = pointSize;\n";
-const char* gVS_Main_AALine =
-        "    widthProportion = vtxWidth;\n"
-        "    lengthProportion = vtxLength;\n";
 const char* gVS_Main_AAVertexShape =
         "    alpha = vtxAlpha;\n";
 const char* gVS_Footer =
@@ -149,9 +140,6 @@
         "precision mediump float;\n\n";
 const char* gFS_Uniforms_Color =
         "uniform vec4 color;\n";
-const char* gFS_Uniforms_AALine =
-        "uniform float boundaryWidth;\n"
-        "uniform float boundaryLength;\n";
 const char* gFS_Header_Uniforms_PointHasBitmap =
         "uniform vec2 textureDimension;\n"
         "uniform float pointSize;\n";
@@ -259,9 +247,6 @@
         "    fragColor = color;\n";
 const char* gFS_Main_ModulateColor =
         "    fragColor *= color.a;\n";
-const char* gFS_Main_AccountForAALine =
-        "    fragColor *= (1.0 - smoothstep(boundaryWidth, 0.5, abs(0.5 - widthProportion)))\n"
-        "               * (1.0 - smoothstep(boundaryLength, 0.5, abs(0.5 - lengthProportion)));\n";
 const char* gFS_Main_AccountForAAVertexShape =
         "    fragColor *= alpha;\n";
 
@@ -472,11 +457,7 @@
         shader.append(gVS_Header_Attributes_TexCoords);
     }
     if (description.isAA) {
-        if (description.isVertexShape) {
-            shader.append(gVS_Header_Attributes_AAVertexShapeParameters);
-        } else {
-            shader.append(gVS_Header_Attributes_AALineParameters);
-        }
+        shader.append(gVS_Header_Attributes_AAVertexShapeParameters);
     }
     // Uniforms
     shader.append(gVS_Header_Uniforms);
@@ -497,11 +478,7 @@
         shader.append(gVS_Header_Varyings_HasTexture);
     }
     if (description.isAA) {
-        if (description.isVertexShape) {
-            shader.append(gVS_Header_Varyings_IsAAVertexShape);
-        } else {
-            shader.append(gVS_Header_Varyings_IsAALine);
-        }
+        shader.append(gVS_Header_Varyings_IsAAVertexShape);
     }
     if (description.hasGradient) {
         shader.append(gVS_Header_Varyings_HasGradient[gradientIndex(description)]);
@@ -520,11 +497,7 @@
             shader.append(gVS_Main_OutTexCoords);
         }
         if (description.isAA) {
-            if (description.isVertexShape) {
-                shader.append(gVS_Main_AAVertexShape);
-            } else {
-                shader.append(gVS_Main_AALine);
-            }
+            shader.append(gVS_Main_AAVertexShape);
         }
         if (description.hasBitmap) {
             shader.append(description.isPoint ?
@@ -574,11 +547,7 @@
         shader.append(gVS_Header_Varyings_HasTexture);
     }
     if (description.isAA) {
-        if (description.isVertexShape) {
-            shader.append(gVS_Header_Varyings_IsAAVertexShape);
-        } else {
-            shader.append(gVS_Header_Varyings_IsAALine);
-        }
+        shader.append(gVS_Header_Varyings_IsAAVertexShape);
     }
     if (description.hasGradient) {
         shader.append(gVS_Header_Varyings_HasGradient[gradientIndex(description)]);
@@ -603,9 +572,6 @@
     } else if (description.hasExternalTexture) {
         shader.append(gFS_Uniforms_ExternalTextureSampler);
     }
-    if (description.isAA && !description.isVertexShape) {
-        shader.append(gFS_Uniforms_AALine);
-    }
     if (description.hasGradient) {
         shader.append(gFS_Uniforms_GradientSampler[gradientIndex(description)]);
     }
@@ -618,8 +584,7 @@
 
     // Optimization for common cases
     if (!description.isAA && !blendFramebuffer &&
-            description.colorOp == ProgramDescription::kColorNone &&
-            !description.isPoint && !description.isVertexShape) {
+            description.colorOp == ProgramDescription::kColorNone && !description.isPoint) {
         bool fast = false;
 
         const bool noShader = !description.hasGradient && !description.hasBitmap;
@@ -754,11 +719,7 @@
         shader.append(gFS_Main_ApplyColorOp[description.colorOp]);
 
         if (description.isAA) {
-            if (description.isVertexShape) {
-                shader.append(gFS_Main_AccountForAAVertexShape);
-            } else {
-                shader.append(gFS_Main_AccountForAALine);
-            }
+            shader.append(gFS_Main_AccountForAAVertexShape);
         }
 
         // Output the fragment
diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h
index 38455dc..c120428 100644
--- a/libs/hwui/Vertex.h
+++ b/libs/hwui/Vertex.h
@@ -68,25 +68,6 @@
     }
 }; // struct AlphaVertex
 
-/**
- * Simple structure to describe a vertex with a position and an alpha value.
- */
-struct AAVertex : Vertex {
-    float width;
-    float length;
-
-    static inline void set(AAVertex* vertex, float x, float y, float width, float length) {
-        Vertex::set(vertex, x, y);
-        vertex[0].width = width;
-        vertex[0].length = length;
-    }
-
-    static inline void setColor(AAVertex* vertex, float width, float length) {
-        vertex[0].width = width;
-        vertex[0].length = length;
-    }
-}; // struct AlphaVertex
-
 }; // namespace uirenderer
 }; // namespace android
 
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java
index 6022141..fb818d4 100644
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java
+++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java
@@ -122,6 +122,12 @@
                             paint.setStrokeWidth(5);
                         }
                     });
+                    put("30", new DisplayModifier() {
+                        @Override
+                        public void modifyDrawing(Paint paint, Canvas canvas) {
+                            paint.setStrokeWidth(30);
+                        }
+                    });
                 }
             });
             put("strokeCap", new LinkedHashMap<String, DisplayModifier>() {
