
/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrAndroidPathRenderer.h"
#include "AndroidPathRenderer.h"
#include "Vertex.h"

GrAndroidPathRenderer::GrAndroidPathRenderer() {
}

bool GrAndroidPathRenderer::canDrawPath(const SkPath& path,
                                        const SkStrokeRec& stroke,
                                        const GrDrawTarget* target,
                                        bool antiAlias) const {
    return ((stroke.isFillStyle() || stroke.getStyle() == SkStrokeRec::kStroke_Style)
             && !path.isInverseFillType() && path.isConvex());
}

struct ColorVertex {
    SkPoint pos;
    GrColor color;
};

bool GrAndroidPathRenderer::onDrawPath(const SkPath& origPath,
                                       const SkStrokeRec& stroke,
                                       GrDrawTarget* target,
                                       bool antiAlias) {

    // generate verts using Android algorithm
    android::uirenderer::VertexBuffer vertices;
    android::uirenderer::PathRenderer::ConvexPathVertices(origPath, stroke, antiAlias, NULL,
                                                          &vertices);

    // set vertex attributes depending on anti-alias
    GrDrawState* drawState = target->drawState();
    if (antiAlias) {
        // position + coverage
        GrVertexAttrib attribs[] = {
            GrVertexAttrib(kVec2f_GrVertexAttribType, 0),
            GrVertexAttrib(kVec4ub_GrVertexAttribType, sizeof(GrPoint))
        };
        drawState->setVertexAttribs(attribs, SK_ARRAY_COUNT(attribs));
        drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
        drawState->setAttribIndex(GrDrawState::kCoverage_AttribIndex, 1);
        drawState->setAttribBindings(GrDrawState::kCoverage_AttribBindingsBit);
    } else {
        drawState->setDefaultVertexAttribs();
    }

    // allocate our vert buffer
    int vertCount = vertices.getSize();
    GrDrawTarget::AutoReleaseGeometry geo(target, vertCount, 0);
    if (!geo.succeeded()) {
        GrPrintf("Failed to get space for vertices!\n");
        return false;
    }

    // copy android verts to our vertex buffer
    if (antiAlias) {
        SkASSERT(sizeof(ColorVertex) == drawState->getVertexSize());
        ColorVertex* outVert = reinterpret_cast<ColorVertex*>(geo.vertices());
        android::uirenderer::AlphaVertex* inVert =
            reinterpret_cast<android::uirenderer::AlphaVertex*>(vertices.getBuffer());

        for (int i = 0; i < vertCount; ++i) {
            // copy vertex position
            outVert->pos.set(inVert->position[0], inVert->position[1]);
            // copy alpha
            int coverage = static_cast<int>(inVert->alpha * 0xff);
            outVert->color = GrColorPackRGBA(coverage, coverage, coverage, coverage);
            ++outVert;
            ++inVert;
        }
    } else {
       size_t vsize = drawState->getVertexSize();
       size_t copySize = vsize*vertCount;
       memcpy(geo.vertices(), vertices.getBuffer(), copySize);
    }

    // render it
    target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, vertCount);

    return true;
}
