This takes the convex path tesselator from the Android code and hooks it into a
authorjvanverth@google.com <jvanverth@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 9 Jan 2013 21:04:52 +0000 (21:04 +0000)
committerjvanverth@google.com <jvanverth@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 9 Jan 2013 21:04:52 +0000 (21:04 +0000)
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

experimental/AndroidPathRenderer/AndroidPathRenderer.cpp
experimental/AndroidPathRenderer/AndroidPathRenderer.h
experimental/AndroidPathRenderer/GrAndroidPathRenderer.cpp [new file with mode: 0644]
experimental/AndroidPathRenderer/GrAndroidPathRenderer.h [new file with mode: 0644]
gyp/common_variables.gypi
gyp/experimental.gyp
gyp/gpu.gyp
src/gpu/GrAddPathRenderers_default.cpp

index 051ed197382fbfc5bb622e9fc13714c71ad4c4ff..6c3224863ee564ece679be0f6f92b945934ec465 100644 (file)
@@ -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 @@ static void getStrokeVerticesFromPerimeterAA(const SkTArray<Vertex, true>& perim
 #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 @@ void PathRenderer::ConvexPathVertices(const SkPath &path, const SkPaint* paint,
     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 @@ void PathRenderer::ConvexPathVertices(const SkPath &path, const SkPaint* paint,
     }
 #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,
index 64aebfa59ec97d1f46c6f723be0ff00db54cf156..0e87aed1d1f9a5700be377c18249cff23074e350 100644 (file)
@@ -57,7 +57,7 @@ class PathRenderer {
 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 (file)
index 0000000..c2bb708
--- /dev/null
@@ -0,0 +1,75 @@
+\r
+/*\r
+ * Copyright 2012 Google Inc.\r
+ *\r
+ * Use of this source code is governed by a BSD-style license that can be\r
+ * found in the LICENSE file.\r
+ */\r
+\r
+#include "GrAndroidPathRenderer.h"\r
+#include "AndroidPathRenderer.h"\r
+#include "Vertex.h"\r
+\r
+GrAndroidPathRenderer::GrAndroidPathRenderer() {\r
+}\r
+\r
+bool GrAndroidPathRenderer::canDrawPath(const SkPath& path,\r
+                                        const SkStrokeRec& stroke,\r
+                                        const GrDrawTarget* target,\r
+                                        bool antiAlias) const {\r
+    return ((stroke.isFillStyle() || stroke.getStyle() == SkStrokeRec::kStroke_Style) \r
+             && !path.isInverseFillType() && path.isConvex());\r
+}\r
+\r
+struct ColorVertex {\r
+    SkPoint pos;\r
+    GrColor color;\r
+};\r
+\r
+bool GrAndroidPathRenderer::onDrawPath(const SkPath& origPath,\r
+                                       const SkStrokeRec& stroke,\r
+                                       GrDrawTarget* target,\r
+                                       bool antiAlias) {\r
+\r
+    // generate verts using Android algorithm\r
+    android::uirenderer::VertexBuffer vertices;\r
+    android::uirenderer::PathRenderer::ConvexPathVertices(origPath, stroke, antiAlias, NULL, \r
+                                                          &vertices);\r
\r
+    // set vertex layout depending on anti-alias\r
+    GrVertexLayout layout = antiAlias ? GrDrawTarget::kCoverage_VertexLayoutBit : 0;\r
+\r
+    // allocate our vert buffer\r
+    int vertCount = vertices.getSize();\r
+    GrDrawTarget::AutoReleaseGeometry geo(target, layout, vertCount, 0);\r
+    if (!geo.succeeded()) {\r
+        GrPrintf("Failed to get space for vertices!\n");\r
+        return false;\r
+    }\r
+\r
+    // copy android verts to our vertex buffer\r
+    if (antiAlias) {\r
+        ColorVertex* outVert = reinterpret_cast<ColorVertex*>(geo.vertices());\r
+        android::uirenderer::AlphaVertex* inVert = \r
+            reinterpret_cast<android::uirenderer::AlphaVertex*>(vertices.getBuffer());\r
+\r
+        for (int i = 0; i < vertCount; ++i) {\r
+            // copy vertex position\r
+            outVert->pos.set(inVert->position[0], inVert->position[1]);\r
+            // copy alpha\r
+            int coverage = static_cast<int>(inVert->alpha * 0xff);\r
+            outVert->color = GrColorPackRGBA(coverage, coverage, coverage, coverage);\r
+            ++outVert;\r
+            ++inVert;\r
+        }\r
+    } else {\r
+       size_t vsize = GrDrawTarget::VertexSize(layout);\r
+       size_t copySize = vsize*vertCount;\r
+       memcpy(geo.vertices(), vertices.getBuffer(), copySize);\r
+    }\r
+    \r
+    // render it\r
+    target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, vertCount);\r
+\r
+    return true;\r
+}\r
diff --git a/experimental/AndroidPathRenderer/GrAndroidPathRenderer.h b/experimental/AndroidPathRenderer/GrAndroidPathRenderer.h
new file mode 100644 (file)
index 0000000..38d2030
--- /dev/null
@@ -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;
+};
index fc2b3a93f4b61bb011dc55c00dabee2a251e5c89..5aca19c23b2e81b6f21d9775fb371494e624ea04 100644 (file)
@@ -82,6 +82,7 @@
       'skia_mesa%': 0,
       'skia_nv_path_rendering%': 0,
       'skia_stroke_path_rendering%': 0,
+      'skia_android_path_rendering%': 0,
       'skia_texture_cache_mb_limit%': 0,
       'skia_angle%': 0,
       'skia_directwrite%': 0,
     'skia_mesa%': '<(skia_mesa)',
     'skia_nv_path_rendering%': '<(skia_nv_path_rendering)',
     'skia_stroke_path_rendering%': '<(skia_stroke_path_rendering)',
+    'skia_android_path_rendering%': '<(skia_android_path_rendering)',
     'skia_texture_cache_mb_limit%': '<(skia_texture_cache_mb_limit)',
     'skia_angle%': '<(skia_angle)',
     'skia_arch_width%': '<(skia_arch_width)',
index 09d5944b521cf4c3ccba3a0ea01f760c6a20f247..09711ac40007c4cc182f4cffc37ab2549caa4957 100644 (file)
@@ -6,13 +6,11 @@
       'include_dirs': [
         '../include/config',
         '../include/core',
-        '../experimental/AndroidPathRenderer',
       ],
       'sources': [
         '../experimental/SkSetPoly3To3.cpp',
         '../experimental/SkSetPoly3To3_A.cpp',
         '../experimental/SkSetPoly3To3_D.cpp',
-        '../experimental/AndroidPathRenderer/AndroidPathRenderer.cpp',
       ],
       'direct_dependent_settings': {
         'include_dirs': [
index 474bdc146a2242ee44ace4230afabd9a026a1a8a..7438babe5967021f9d16b30d5ab3411c256e71ab 100644 (file)
             'GR_STROKE_PATH_RENDERING=1',
           ],
         }],
+        [ 'skia_android_path_rendering', {
+          'sources': [
+            '../experimental/AndroidPathRenderer/GrAndroidPathRenderer.cpp',
+            '../experimental/AndroidPathRenderer/GrAndroidPathRenderer.h',
+            '../experimental/AndroidPathRenderer/AndroidPathRenderer.cpp',
+            '../experimental/AndroidPathRenderer/AndroidPathRenderer.h',
+            '../experimental/AndroidPathRenderer/Vertex.h',
+          ],
+          'defines': [
+            'GR_ANDROID_PATH_RENDERING=1',
+          ],
+        }],
         [ 'skia_os == "linux"', {
           'sources!': [
             '../src/gpu/gl/GrGLDefaultInterface_none.cpp',
index 618bd3100b4b1782c51fbec00652030602f512f2..4f172434dec2eebbe1f3ab4fd019a74bc9a49b64 100644 (file)
 #if GR_STROKE_PATH_RENDERING
 #include "../../experimental/StrokePathRenderer/GrStrokePathRenderer.h"
 #endif
+#if GR_ANDROID_PATH_RENDERING
+#include "../../experimental/AndroidPathRenderer/GrAndroidPathRenderer.h"
+#endif
 
 void GrPathRenderer::AddPathRenderers(GrContext* ctx, GrPathRendererChain* chain) {
 #if GR_STROKE_PATH_RENDERING
     chain->addPathRenderer(SkNEW(GrStrokePathRenderer))->unref();
+#endif
+#if GR_ANDROID_PATH_RENDERING
+    chain->addPathRenderer(SkNEW(GrAndroidPathRenderer))->unref();
 #endif
     if (GrPathRenderer* pr = GrStencilAndCoverPathRenderer::Create(ctx)) {
         chain->addPathRenderer(pr)->unref();