This takes the convex path tesselator from the Android code and hooks it into a
GrPathRenderer. GrAndroidPathRenderer is activated by gyp flag 'skia_android_path_rendering'.
A few changes to get this to work:
- Had to change SkPaint* param to SkStrokeRec& in ConvexPathVertices()
- Had to copy the vertex buffer created by the Android code to GrDrawTarget-generated vertex buffer, and convert float alpha to GrColor for AA paths
git-svn-id: http://skia.googlecode.com/svn/trunk@7110 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/AndroidPathRenderer/GrAndroidPathRenderer.cpp b/experimental/AndroidPathRenderer/GrAndroidPathRenderer.cpp
new file mode 100644
index 0000000..c2bb708
--- /dev/null
+++ b/experimental/AndroidPathRenderer/GrAndroidPathRenderer.cpp
@@ -0,0 +1,75 @@
+
+/*
+ * 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 layout depending on anti-alias
+ GrVertexLayout layout = antiAlias ? GrDrawTarget::kCoverage_VertexLayoutBit : 0;
+
+ // allocate our vert buffer
+ int vertCount = vertices.getSize();
+ GrDrawTarget::AutoReleaseGeometry geo(target, layout, vertCount, 0);
+ if (!geo.succeeded()) {
+ GrPrintf("Failed to get space for vertices!\n");
+ return false;
+ }
+
+ // copy android verts to our vertex buffer
+ if (antiAlias) {
+ 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 = GrDrawTarget::VertexSize(layout);
+ size_t copySize = vsize*vertCount;
+ memcpy(geo.vertices(), vertices.getBuffer(), copySize);
+ }
+
+ // render it
+ target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, vertCount);
+
+ return true;
+}