1
2/*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include "GrAndroidPathRenderer.h"
10#include "AndroidPathRenderer.h"
11#include "Vertex.h"
12
13GrAndroidPathRenderer::GrAndroidPathRenderer() {
14}
15
16bool GrAndroidPathRenderer::canDrawPath(const SkPath& path,
17                                        const SkStrokeRec& stroke,
18                                        const GrDrawTarget* target,
19                                        bool antiAlias) const {
20    return ((stroke.isFillStyle() || stroke.getStyle() == SkStrokeRec::kStroke_Style)
21             && !path.isInverseFillType() && path.isConvex());
22}
23
24struct ColorVertex {
25    SkPoint pos;
26    GrColor color;
27};
28
29bool GrAndroidPathRenderer::onDrawPath(const SkPath& origPath,
30                                       const SkStrokeRec& stroke,
31                                       GrDrawTarget* target,
32                                       bool antiAlias) {
33
34    // generate verts using Android algorithm
35    android::uirenderer::VertexBuffer vertices;
36    android::uirenderer::PathRenderer::ConvexPathVertices(origPath, stroke, antiAlias, NULL,
37                                                          &vertices);
38
39    // set vertex attributes depending on anti-alias
40    GrDrawState* drawState = target->drawState();
41    if (antiAlias) {
42        // position + coverage
43        GrVertexAttrib attribs[] = {
44            GrVertexAttrib(kVec2f_GrVertexAttribType, 0),
45            GrVertexAttrib(kVec4ub_GrVertexAttribType, sizeof(GrPoint))
46        };
47        drawState->setVertexAttribs(attribs, SK_ARRAY_COUNT(attribs));
48        drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
49        drawState->setAttribIndex(GrDrawState::kCoverage_AttribIndex, 1);
50        drawState->setAttribBindings(GrDrawState::kCoverage_AttribBindingsBit);
51    } else {
52        drawState->setDefaultVertexAttribs();
53    }
54
55    // allocate our vert buffer
56    int vertCount = vertices.getSize();
57    GrDrawTarget::AutoReleaseGeometry geo(target, vertCount, 0);
58    if (!geo.succeeded()) {
59        SkDebugf("Failed to get space for vertices!\n");
60        return false;
61    }
62
63    // copy android verts to our vertex buffer
64    if (antiAlias) {
65        SkASSERT(sizeof(ColorVertex) == drawState->getVertexSize());
66        ColorVertex* outVert = reinterpret_cast<ColorVertex*>(geo.vertices());
67        android::uirenderer::AlphaVertex* inVert =
68            reinterpret_cast<android::uirenderer::AlphaVertex*>(vertices.getBuffer());
69
70        for (int i = 0; i < vertCount; ++i) {
71            // copy vertex position
72            outVert->pos.set(inVert->position[0], inVert->position[1]);
73            // copy alpha
74            int coverage = static_cast<int>(inVert->alpha * 0xff);
75            outVert->color = GrColorPackRGBA(coverage, coverage, coverage, coverage);
76            ++outVert;
77            ++inVert;
78        }
79    } else {
80       size_t vsize = drawState->getVertexSize();
81       size_t copySize = vsize*vertCount;
82       memcpy(geo.vertices(), vertices.getBuffer(), copySize);
83    }
84
85    // render it
86    target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, vertCount);
87
88    return true;
89}
90