/*
 * 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 "OpenGLRenderer"
#define LOG_NDEBUG 1
#define ATRACE_TAG ATRACE_TAG_VIEW

#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].x, buffer[i].y, 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].x, buffer[i].y); \
    }
#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"
#include "utils/MathUtils.h"

namespace android {
namespace uirenderer {

#define OUTLINE_REFINE_THRESHOLD_SQUARED (0.5f * 0.5f)
#define ROUND_CAP_THRESH 0.25f
#define PI 3.1415926535897932f
#define MAX_DEPTH 15

/**
 * Extracts the x and y scale from the transform as positive values, and clamps them
 */
void PathTessellator::extractTessellationScales(const Matrix4& transform,
        float* scaleX, float* scaleY) {
    if (CC_LIKELY(transform.isPureTranslate())) {
        *scaleX = 1.0f;
        *scaleY = 1.0f;
    } else {
        float m00 = transform.data[Matrix4::kScaleX];
        float m01 = transform.data[Matrix4::kSkewY];
        float m10 = transform.data[Matrix4::kSkewX];
        float m11 = transform.data[Matrix4::kScaleY];
        *scaleX = MathUtils::clampTessellationScale(sqrt(m00 * m00 + m01 * m01));
        *scaleY = MathUtils::clampTessellationScale(sqrt(m10 * m10 + m11 * m11));
    }
}

/**
 * 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 static Vector2 totalOffsetFromNormals(const Vector2& normalA, const Vector2& 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()),
            halfStrokeWidth(paint->getStrokeWidth() * 0.5f), maxAlpha(1.0f) {
        // compute inverse scales
        if (CC_LIKELY(transform.isPureTranslate())) {
            inverseScaleX = 1.0f;
            inverseScaleY = 1.0f;
        } else {
            float scaleX, scaleY;
            PathTessellator::extractTessellationScales(transform, &scaleX, &scaleY);
            inverseScaleX = 1.0f / scaleX;
            inverseScaleY = 1.0f / scaleY;
        }

        if (isAA && halfStrokeWidth != 0 && inverseScaleX == inverseScaleY &&
                2 * halfStrokeWidth < inverseScaleX) {
            // AA, with non-hairline stroke, width < 1 pixel. Scale alpha and treat as hairline.
            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(Vector2& 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 Vector2 deriveAAOffset(const Vector2& offset) const {
        return (Vector2){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;
    }

    /**
     * Outset the bounds of point data (for line endpoints or points) to account for stroke
     * geometry.
     *
     * bounds are in pre-scaled space.
     */
    void expandBoundsForStroke(Rect* bounds) const {
        if (halfStrokeWidth == 0) {
            // hairline, outset by (0.5f + fudge factor) in post-scaling space
            bounds->outset(fabs(inverseScaleX) * (0.5f + Vertex::GeometryFudgeFactor()),
                    fabs(inverseScaleY) * (0.5f + Vertex::GeometryFudgeFactor()));
        } else {
            // non hairline, outset by half stroke width pre-scaled, and fudge factor post scaled
            bounds->outset(halfStrokeWidth + fabs(inverseScaleX) * Vertex::GeometryFudgeFactor(),
                    halfStrokeWidth + fabs(inverseScaleY) * Vertex::GeometryFudgeFactor());
        }
    }
};

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) {
        buffer[currentIndex++] = perimeter[srcAindex];
        if (srcAindex == srcBindex) break;
        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]);
    Vector2 lastNormal = {current->y - last->y, last->x - current->x};
    lastNormal.normalize();
    for (unsigned int i = 0; i < perimeter.size(); i++) {
        const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
        Vector2 nextNormal = {next->y - current->y, current->x - next->x};
        nextNormal.normalize();

        Vector2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
        paintInfo.scaleOffsetForStrokeWidth(totalOffset);

        Vertex::set(&buffer[currentIndex++],
                current->x + totalOffset.x,
                current->y + totalOffset.y);

        Vertex::set(&buffer[currentIndex++],
                current->x - totalOffset.x,
                current->y - totalOffset.y);

        current = next;
        lastNormal = nextNormal;
    }

    // wrap around to beginning
    buffer[currentIndex++] = buffer[0];
    buffer[currentIndex++] = buffer[1];

    DEBUG_DUMP_BUFFER();
}

static inline void storeBeginEnd(const PaintInfo& paintInfo, const Vertex& center,
        const Vector2& normal, Vertex* buffer, int& currentIndex, bool begin) {
    Vector2 strokeOffset = normal;
    paintInfo.scaleOffsetForStrokeWidth(strokeOffset);

    Vector2 referencePoint = {center.x, center.y};
    if (paintInfo.cap == SkPaint::kSquare_Cap) {
        Vector2 rotated = {-strokeOffset.y, strokeOffset.x};
        referencePoint += rotated * (begin ? -1 : 1);
    }

    Vertex::set(&buffer[currentIndex++], referencePoint + strokeOffset);
    Vertex::set(&buffer[currentIndex++], referencePoint - strokeOffset);
}

/**
 * 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);

    const int lastIndex = vertices.size() - 1;
    if (extra > 0) {
        // tessellate both round caps
        float beginTheta = atan2(
                    - (vertices[0].x - vertices[1].x),
                    vertices[0].y - vertices[1].y);
        float endTheta = atan2(
                    - (vertices[lastIndex].x - vertices[lastIndex - 1].x),
                    vertices[lastIndex].y - vertices[lastIndex - 1].y);
        const float dTheta = PI / (extra + 1);

        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;
            Vector2 beginRadialOffset = {cosf(beginTheta), sinf(beginTheta)};
            paintInfo.scaleOffsetForStrokeWidth(beginRadialOffset);
            Vertex::set(&buffer[capOffset],
                    vertices[0].x + beginRadialOffset.x,
                    vertices[0].y + beginRadialOffset.y);

            endTheta += dTheta;
            Vector2 endRadialOffset = {cosf(endTheta), sinf(endTheta)};
            paintInfo.scaleOffsetForStrokeWidth(endRadialOffset);
            Vertex::set(&buffer[allocSize - 1 - capOffset],
                    vertices[lastIndex].x + endRadialOffset.x,
                    vertices[lastIndex].y + endRadialOffset.y);
        }
    }

    int currentIndex = extra;
    const Vertex* last = &(vertices[0]);
    const Vertex* current = &(vertices[1]);
    Vector2 lastNormal = {current->y - last->y, last->x - current->x};
    lastNormal.normalize();

    storeBeginEnd(paintInfo, vertices[0], lastNormal, buffer, currentIndex, true);

    for (unsigned int i = 1; i < vertices.size() - 1; i++) {
        const Vertex* next = &(vertices[i + 1]);
        Vector2 nextNormal = {next->y - current->y, current->x - next->x};
        nextNormal.normalize();

        Vector2 strokeOffset  = totalOffsetFromNormals(lastNormal, nextNormal);
        paintInfo.scaleOffsetForStrokeWidth(strokeOffset);

        Vector2 center = {current->x, current->y};
        Vertex::set(&buffer[currentIndex++], center + strokeOffset);
        Vertex::set(&buffer[currentIndex++], center - strokeOffset);

        current = next;
        lastNormal = nextNormal;
    }

    storeBeginEnd(paintInfo, vertices[lastIndex], lastNormal, buffer, currentIndex, false);

    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, float maxAlpha = 1.0f) {
    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]);
    Vector2 lastNormal = {current->y - last->y, last->x - current->x};
    lastNormal.normalize();
    for (unsigned int i = 0; i < perimeter.size(); i++) {
        const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
        Vector2 nextNormal = {next->y - current->y, current->x - next->x};
        nextNormal.normalize();

        // AA point offset from original point is that point's normal, such that each side is offset
        // by .5 pixels
        Vector2 totalOffset = paintInfo.deriveAAOffset(totalOffsetFromNormals(lastNormal, nextNormal));

        AlphaVertex::set(&buffer[currentIndex++],
                current->x + totalOffset.x,
                current->y + totalOffset.y,
                0.0f);
        AlphaVertex::set(&buffer[currentIndex++],
                current->x - totalOffset.x,
                current->y - totalOffset.y,
                maxAlpha);

        current = next;
        lastNormal = nextNormal;
    }

    // wrap around to beginning
    buffer[currentIndex++] = buffer[0];
    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) {
        buffer[currentIndex++] = buffer[srcAindex * 2 + 1];
        if (srcAindex == srcBindex) break;
        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 static void storeCapAA(const PaintInfo& paintInfo, const Vector<Vertex>& vertices,
        AlphaVertex* buffer, bool isFirst, Vector2 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()
    Vector2 AAOffset = paintInfo.deriveAAOffset(normal);

    Vector2 strokeOffset = normal;
    paintInfo.scaleOffsetForStrokeWidth(strokeOffset);
    Vector2 outerOffset = strokeOffset + AAOffset;
    Vector2 innerOffset = strokeOffset - AAOffset;

    Vector2 capAAOffset = {0, 0};
    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 = (Vector2){-AAOffset.y, AAOffset.x};
    }

    // determine referencePoint, the center point for the 4 primary cap vertices
    const Vertex* point = isFirst ? vertices.begin() : (vertices.end() - 1);
    Vector2 referencePoint = {point->x, point->y};
    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)
        Vector2 rotated = {-strokeOffset.y, strokeOffset.x};
        referencePoint += rotated;
    }

    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;

            Vector2 radialOffset = {cosf(theta), sinf(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
                buffer[0] = buffer[capPerimIndex - 2];
                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) {
                buffer[capFillIndex++] = buffer[1 + i];
                // TODO: to support odd numbers of divisions, break here on the last iteration
                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) {
                buffer[capFillIndex++] = buffer[capIndex + 1 + i];
                // TODO: to support odd numbers of divisions, break here on the last iteration
                buffer[capFillIndex++] = buffer[capIndex + 3 + 2 * extra - i];
            }
        }
        return;
    }
    if (isFirst) {
        buffer[0] = buffer[postCapIndex + 2];
        buffer[1] = buffer[postCapIndex + 3];
        buffer[postCapIndex + 4] = buffer[1]; // degenerate tris (the only two!)
        buffer[postCapIndex + 5] = buffer[postCapIndex + 1];
    } else {
        buffer[6 * vertices.size()] = buffer[postCapIndex + 1];
        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]);
    Vector2 lastNormal = {current->y - last->y, last->x - current->x};
    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]);
        Vector2 nextNormal = {next->y - current->y, current->x - next->x};
        nextNormal.normalize();

        Vector2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
        Vector2 AAOffset = paintInfo.deriveAAOffset(totalOffset);

        Vector2 innerOffset = totalOffset;
        paintInfo.scaleOffsetForStrokeWidth(innerOffset);
        Vector2 outerOffset = innerOffset + AAOffset;
        innerOffset -= AAOffset;

        AlphaVertex::set(&buffer[currentAAOuterIndex++],
                current->x + outerOffset.x,
                current->y + outerOffset.y,
                0.0f);
        AlphaVertex::set(&buffer[currentAAOuterIndex++],
                current->x + innerOffset.x,
                current->y + innerOffset.y,
                paintInfo.maxAlpha);

        AlphaVertex::set(&buffer[currentStrokeIndex++],
                current->x + innerOffset.x,
                current->y + innerOffset.y,
                paintInfo.maxAlpha);
        AlphaVertex::set(&buffer[currentStrokeIndex++],
                current->x - innerOffset.x,
                current->y - innerOffset.y,
                paintInfo.maxAlpha);

        AlphaVertex::set(&buffer[currentAAInnerIndex--],
                current->x - innerOffset.x,
                current->y - innerOffset.y,
                paintInfo.maxAlpha);
        AlphaVertex::set(&buffer[currentAAInnerIndex--],
                current->x - outerOffset.x,
                current->y - 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]);
    Vector2 lastNormal = {current->y - last->y, last->x - current->x};
    lastNormal.normalize();
    for (unsigned int i = 0; i < perimeter.size(); i++) {
        const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
        Vector2 nextNormal = {next->y - current->y, current->x - next->x};
        nextNormal.normalize();

        Vector2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
        Vector2 AAOffset = paintInfo.deriveAAOffset(totalOffset);

        Vector2 innerOffset = totalOffset;
        paintInfo.scaleOffsetForStrokeWidth(innerOffset);
        Vector2 outerOffset = innerOffset + AAOffset;
        innerOffset -= AAOffset;

        AlphaVertex::set(&buffer[currentAAOuterIndex++],
                current->x + outerOffset.x,
                current->y + outerOffset.y,
                0.0f);
        AlphaVertex::set(&buffer[currentAAOuterIndex++],
                current->x + innerOffset.x,
                current->y + innerOffset.y,
                paintInfo.maxAlpha);

        AlphaVertex::set(&buffer[currentStrokeIndex++],
                current->x + innerOffset.x,
                current->y + innerOffset.y,
                paintInfo.maxAlpha);
        AlphaVertex::set(&buffer[currentStrokeIndex++],
                current->x - innerOffset.x,
                current->y - innerOffset.y,
                paintInfo.maxAlpha);

        AlphaVertex::set(&buffer[currentAAInnerIndex++],
                current->x - innerOffset.x,
                current->y - innerOffset.y,
                paintInfo.maxAlpha);
        AlphaVertex::set(&buffer[currentAAInnerIndex++],
                current->x - outerOffset.x,
                current->y - outerOffset.y,
                0.0f);

        current = next;
        lastNormal = nextNormal;
    }

    // wrap each strip around to beginning, creating degenerate tris to bridge strips
    buffer[currentAAOuterIndex++] = buffer[0];
    buffer[currentAAOuterIndex++] = buffer[1];
    buffer[currentAAOuterIndex++] = buffer[1];

    buffer[currentStrokeIndex++] = buffer[offset];
    buffer[currentStrokeIndex++] = buffer[offset + 1];
    buffer[currentStrokeIndex++] = buffer[offset + 1];

    buffer[currentAAInnerIndex++] = buffer[2 * offset];
    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,
            OUTLINE_REFINE_THRESHOLD_SQUARED, 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].x, tempVertices[i].y);
    }
#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);
        }
    }

    Rect bounds(path.getBounds());
    paintInfo.expandBoundsForStroke(&bounds);
    vertexBuffer.setBounds(bounds);
    vertexBuffer.setMeshFeatureFlags(paintInfo.isAA ? VertexBuffer::kAlpha : VertexBuffer::kNone);
}

template <class TYPE>
static void instanceVertices(VertexBuffer& srcBuffer, VertexBuffer& dstBuffer,
        const float* points, int count, Rect& bounds) {
    bounds.set(points[0], points[1], points[0], points[1]);

    int numPoints = count / 2;
    int verticesPerPoint = srcBuffer.getVertexCount();
    dstBuffer.alloc<TYPE>(numPoints * verticesPerPoint + (numPoints - 1) * 2);

    for (int i = 0; i < count; i += 2) {
        bounds.expandToCoverVertex(points[i + 0], points[i + 1]);
        dstBuffer.copyInto<TYPE>(srcBuffer, points[i + 0], points[i + 1]);
    }
    dstBuffer.createDegenerateSeparators<TYPE>(verticesPerPoint);
}

void PathTessellator::tessellatePoints(const float* points, int count, const SkPaint* paint,
        const mat4& transform, VertexBuffer& vertexBuffer) {
    const PaintInfo paintInfo(paint, transform);

    // determine point shape
    SkPath path;
    float radius = paintInfo.halfStrokeWidth;
    if (radius == 0.0f) radius = 0.5f;

    if (paintInfo.cap == SkPaint::kRound_Cap) {
        path.addCircle(0, 0, radius);
    } else {
        path.addRect(-radius, -radius, radius, radius);
    }

    // calculate outline
    Vector<Vertex> outlineVertices;
    approximatePathOutlineVertices(path, true,
            paintInfo.inverseScaleX * paintInfo.inverseScaleX,
            paintInfo.inverseScaleY * paintInfo.inverseScaleY,
            OUTLINE_REFINE_THRESHOLD_SQUARED, outlineVertices);

    if (!outlineVertices.size()) return;

    Rect bounds;
    // tessellate, then duplicate outline across points
    VertexBuffer tempBuffer;
    if (!paintInfo.isAA) {
        getFillVerticesFromPerimeter(outlineVertices, tempBuffer);
        instanceVertices<Vertex>(tempBuffer, vertexBuffer, points, count, bounds);
    } else {
        // note: pass maxAlpha directly, since we want fill to be alpha modulated
        getFillVerticesFromPerimeterAA(paintInfo, outlineVertices, tempBuffer, paintInfo.maxAlpha);
        instanceVertices<AlphaVertex>(tempBuffer, vertexBuffer, points, count, bounds);
    }

    // expand bounds from vertex coords to pixel data
    paintInfo.expandBoundsForStroke(&bounds);
    vertexBuffer.setBounds(bounds);
    vertexBuffer.setMeshFeatureFlags(paintInfo.isAA ? VertexBuffer::kAlpha : VertexBuffer::kNone);
}

void PathTessellator::tessellateLines(const float* points, int count, const SkPaint* paint,
        const mat4& transform, 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();
    Rect bounds;
    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
        bounds.expandToCoverVertex(tempVerticesData[0].x, tempVerticesData[0].y);
        bounds.expandToCoverVertex(tempVerticesData[1].x, tempVerticesData[1].y);
    }

    // since multiple objects tessellated into buffer, separate them with degen tris
    if (paintInfo.isAA) {
        vertexBuffer.createDegenerateSeparators<AlphaVertex>(lineAllocSize);
    } else {
        vertexBuffer.createDegenerateSeparators<Vertex>(lineAllocSize);
    }

    // expand bounds from vertex coords to pixel data
    paintInfo.expandBoundsForStroke(&bounds);
    vertexBuffer.setBounds(bounds);
    vertexBuffer.setMeshFeatureFlags(paintInfo.isAA ? VertexBuffer::kAlpha : VertexBuffer::kNone);
}

///////////////////////////////////////////////////////////////////////////////
// Simple path line approximation
///////////////////////////////////////////////////////////////////////////////

bool PathTessellator::approximatePathOutlineVertices(const SkPath& path, float thresholdSquared,
        Vector<Vertex>& outputVertices) {
    return approximatePathOutlineVertices(path, true, 1.0f, 1.0f, thresholdSquared, outputVertices);
}

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, float thresholdSquared,
        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, thresholdSquared, 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, thresholdSquared, outputVertices);
                break;
            default:
                break;
            }
    }

    int size = outputVertices.size();
    if (size >= 2 && outputVertices[0].x == outputVertices[size - 1].x &&
            outputVertices[0].y == outputVertices[size - 1].y) {
        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, float thresholdSquared,
        Vector<Vertex>& outputVertices, int depth) {
    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 (depth >= MAX_DEPTH
            || d * d <= thresholdSquared * (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, thresholdSquared, outputVertices, depth + 1);
        recursiveCubicBezierVertices(
                mx, my, p2c1c2x, p2c1c2y,
                p2x, p2y, p2c2x, p2c2y,
                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices, depth + 1);
    }
}

void PathTessellator::recursiveQuadraticBezierVertices(
        float ax, float ay,
        float bx, float by,
        float cx, float cy,
        float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
        Vector<Vertex>& outputVertices, int depth) {
    float dx = bx - ax;
    float dy = by - ay;
    float d = (cx - bx) * dy - (cy - by) * dx;

    // multiplying by sqrInvScaleY/X equivalent to multiplying in dimensional scale factors
    if (depth >= MAX_DEPTH
            || d * d <= thresholdSquared * (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, thresholdSquared, outputVertices, depth + 1);
        recursiveQuadraticBezierVertices(mx, my, bx, by, bcx, bcy,
                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices, depth + 1);
    }
}

}; // namespace uirenderer
}; // namespace android
