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/AndroidPathRenderer.cpp b/experimental/AndroidPathRenderer/AndroidPathRenderer.cpp
index 051ed19..6c32248 100644
--- a/experimental/AndroidPathRenderer/AndroidPathRenderer.cpp
+++ b/experimental/AndroidPathRenderer/AndroidPathRenderer.cpp
@@ -12,7 +12,7 @@
#define VERTEX_DEBUG 0
#include <SkPath.h>
-#include <SkPaint.h>
+#include <SkStrokeRec.h>
#include <stdlib.h>
#include <stdint.h>
@@ -520,12 +520,11 @@
#endif
}
-void PathRenderer::ConvexPathVertices(const SkPath &path, const SkPaint* paint,
+void PathRenderer::ConvexPathVertices(const SkPath &path, const SkStrokeRec& stroke, bool isAA,
const SkMatrix* transform, VertexBuffer* vertexBuffer) {
SK_TRACE_EVENT0("PathRenderer::convexPathVertices");
- SkPaint::Style style = paint->getStyle();
- bool isAA = paint->isAntiAlias();
+ SkStrokeRec::Style style = stroke.getStyle();
float inverseScaleX, inverseScaleY;
computeInverseScales(transform, inverseScaleX, inverseScaleY);
@@ -533,18 +532,18 @@
SkTArray<Vertex, true> tempVertices;
float threshInvScaleX = inverseScaleX;
float threshInvScaleY = inverseScaleY;
- if (style == SkPaint::kStroke_Style) {
+ if (style == SkStrokeRec::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());
+ threshInvScaleX *= bounds.width() / (bounds.width() + stroke.getWidth());
+ threshInvScaleY *= bounds.height() / (bounds.height() + stroke.getWidth());
}
}
// force close if we're filling the path, since fill path expects closed perimeter.
- bool forceClose = style != SkPaint::kStroke_Style;
+ bool forceClose = style != SkStrokeRec::kStroke_Style;
bool wasClosed = ConvexPathPerimeterVertices(path, forceClose, threshInvScaleX * threshInvScaleX,
threshInvScaleY * threshInvScaleY, &tempVertices);
@@ -559,8 +558,8 @@
}
#endif
- if (style == SkPaint::kStroke_Style) {
- float halfStrokeWidth = paint->getStrokeWidth() * 0.5f;
+ if (style == SkStrokeRec::kStroke_Style) {
+ float halfStrokeWidth = stroke.getWidth() * 0.5f;
if (!isAA) {
if (wasClosed) {
getStrokeVerticesFromPerimeter(tempVertices, halfStrokeWidth, vertexBuffer,
diff --git a/experimental/AndroidPathRenderer/AndroidPathRenderer.h b/experimental/AndroidPathRenderer/AndroidPathRenderer.h
index 64aebfa..0e87aed 100644
--- a/experimental/AndroidPathRenderer/AndroidPathRenderer.h
+++ b/experimental/AndroidPathRenderer/AndroidPathRenderer.h
@@ -57,7 +57,7 @@
public:
static SkRect ComputePathBounds(const SkPath& path, const SkPaint* paint);
- static void ConvexPathVertices(const SkPath& path, const SkPaint* paint,
+ static void ConvexPathVertices(const SkPath& path, const SkStrokeRec& stroke, bool isAA,
const SkMatrix* transform, VertexBuffer* vertexBuffer);
private:
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;
+}
diff --git a/experimental/AndroidPathRenderer/GrAndroidPathRenderer.h b/experimental/AndroidPathRenderer/GrAndroidPathRenderer.h
new file mode 100644
index 0000000..38d2030
--- /dev/null
+++ b/experimental/AndroidPathRenderer/GrAndroidPathRenderer.h
@@ -0,0 +1,29 @@
+
+/*
+ * 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 "GrPathRenderer.h"
+
+
+class GrAndroidPathRenderer : public GrPathRenderer {
+public:
+ GrAndroidPathRenderer();
+
+ virtual bool canDrawPath(const SkPath& path,
+ const SkStrokeRec& stroke,
+ const GrDrawTarget* target,
+ bool antiAlias) const SK_OVERRIDE;
+
+protected:
+ virtual bool onDrawPath(const SkPath& path,
+ const SkStrokeRec& stroke,
+ GrDrawTarget* target,
+ bool antiAlias) SK_OVERRIDE;
+
+private:
+ typedef GrPathRenderer INHERITED;
+};