Add cap tessellation support

bug:7117155
bug:8114304

Currently used for lines (with and without AA) and arcs with useCenter=false

Also removes 0.375, 0.375 offset for AA lines

Change-Id: Ic8ace418739344db1e2814edf65253fe7448b0b0
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