Exposed SkCanvas::drawMesh

Added drawMesh method to the Canvas API, utilizing SkCanvas::drawMesh.

Bug: b/253321460
Test: HwAccelerationTest MeshActivity
Change-Id: I43802af61bbd6f76444b4e4b7cec2b95bae34f66
diff --git a/libs/hwui/jni/Mesh.cpp b/libs/hwui/jni/Mesh.cpp
index 6dba6c1..109aac3 100644
--- a/libs/hwui/jni/Mesh.cpp
+++ b/libs/hwui/jni/Mesh.cpp
@@ -42,7 +42,7 @@
                   jint right, jint bottom) {
     auto skMeshSpec = sk_ref_sp(reinterpret_cast<SkMeshSpecification*>(meshSpec));
     sk_sp<SkMesh::VertexBuffer> skVertexBuffer =
-            genVertexBuffer(env, vertexBuffer, skMeshSpec->attributes().size_bytes(), isDirect);
+            genVertexBuffer(env, vertexBuffer, vertexCount * skMeshSpec->stride(), isDirect);
     auto skRect = SkRect::MakeLTRB(left, top, right, bottom);
     auto mesh = SkMesh::Make(skMeshSpec, SkMesh::Mode(mode), skVertexBuffer, vertexCount,
                              vertexOffset, nullptr, skRect);
@@ -55,8 +55,8 @@
                          jobject indexBuffer, jboolean isIndexDirect, jint indexCount,
                          jint indexOffset, jint left, jint top, jint right, jint bottom) {
     auto skMeshSpec = sk_ref_sp(reinterpret_cast<SkMeshSpecification*>(meshSpec));
-    sk_sp<SkMesh::VertexBuffer> skVertexBuffer = genVertexBuffer(
-            env, vertexBuffer, skMeshSpec->attributes().size_bytes(), isVertexDirect);
+    sk_sp<SkMesh::VertexBuffer> skVertexBuffer =
+            genVertexBuffer(env, vertexBuffer, vertexCount * skMeshSpec->stride(), isVertexDirect);
     sk_sp<SkMesh::IndexBuffer> skIndexBuffer =
             genIndexBuffer(env, indexBuffer, indexCount * gIndexByteSize, isIndexDirect);
     auto skRect = SkRect::MakeLTRB(left, top, right, bottom);
diff --git a/libs/hwui/jni/MeshSpecification.cpp b/libs/hwui/jni/MeshSpecification.cpp
index 22fa4d3..619a3ed 100644
--- a/libs/hwui/jni/MeshSpecification.cpp
+++ b/libs/hwui/jni/MeshSpecification.cpp
@@ -50,7 +50,6 @@
                        SkString(attName.c_str())};
         attVector.push_back(std::move(temp));
     }
-
     return attVector;
 }
 
@@ -76,11 +75,15 @@
     auto varyings = extractVaryings(env, varyingArray);
     auto skVertexShader = ScopedUtfChars(env, vertexShader);
     auto skFragmentShader = ScopedUtfChars(env, fragmentShader);
-    auto meshSpec = SkMeshSpecification::Make(attributes, vertexStride, varyings,
-                                              SkString(skVertexShader.c_str()),
-                                              SkString(skFragmentShader.c_str()))
-                            .specification;
-    return reinterpret_cast<jlong>(meshSpec.release());
+    auto meshSpecResult = SkMeshSpecification::Make(attributes, vertexStride, varyings,
+                                                    SkString(skVertexShader.c_str()),
+                                                    SkString(skFragmentShader.c_str()));
+
+    if (meshSpecResult.specification.get() == nullptr) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", meshSpecResult.error.c_str());
+    }
+
+    return reinterpret_cast<jlong>(meshSpecResult.specification.release());
 }
 
 static jlong MakeWithCS(JNIEnv* env, jobject thiz, jobjectArray attributeArray, jint vertexStride,
@@ -90,13 +93,15 @@
     auto varyings = extractVaryings(env, varyingArray);
     auto skVertexShader = ScopedUtfChars(env, vertexShader);
     auto skFragmentShader = ScopedUtfChars(env, fragmentShader);
-    auto meshSpec = SkMeshSpecification::Make(attributes, vertexStride, varyings,
-                                              SkString(skVertexShader.c_str()),
-                                              SkString(skFragmentShader.c_str()),
-                                              GraphicsJNI::getNativeColorSpace(colorSpace))
-                            .specification;
+    auto meshSpecResult = SkMeshSpecification::Make(
+            attributes, vertexStride, varyings, SkString(skVertexShader.c_str()),
+            SkString(skFragmentShader.c_str()), GraphicsJNI::getNativeColorSpace(colorSpace));
 
-    return reinterpret_cast<jlong>(meshSpec.release());
+    if (meshSpecResult.specification.get() == nullptr) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", meshSpecResult.error.c_str());
+    }
+
+    return reinterpret_cast<jlong>(meshSpecResult.specification.release());
 }
 
 static jlong MakeWithAlpha(JNIEnv* env, jobject thiz, jobjectArray attributeArray,
@@ -106,12 +111,16 @@
     auto varyings = extractVaryings(env, varyingArray);
     auto skVertexShader = ScopedUtfChars(env, vertexShader);
     auto skFragmentShader = ScopedUtfChars(env, fragmentShader);
-    auto meshSpec = SkMeshSpecification::Make(
-                            attributes, vertexStride, varyings, SkString(skVertexShader.c_str()),
-                            SkString(skFragmentShader.c_str()),
-                            GraphicsJNI::getNativeColorSpace(colorSpace), SkAlphaType(alphaType))
-                            .specification;
-    return reinterpret_cast<jlong>(meshSpec.release());
+    auto meshSpecResult = SkMeshSpecification::Make(
+            attributes, vertexStride, varyings, SkString(skVertexShader.c_str()),
+            SkString(skFragmentShader.c_str()), GraphicsJNI::getNativeColorSpace(colorSpace),
+            SkAlphaType(alphaType));
+
+    if (meshSpecResult.specification.get() == nullptr) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", meshSpecResult.error.c_str());
+    }
+
+    return reinterpret_cast<jlong>(meshSpecResult.specification.release());
 }
 
 static void MeshSpecification_safeUnref(SkMeshSpecification* meshSpec) {
@@ -153,4 +162,4 @@
     return 0;
 }
 
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/libs/hwui/jni/android_graphics_Canvas.cpp b/libs/hwui/jni/android_graphics_Canvas.cpp
index 0513447..8a4d4e1 100644
--- a/libs/hwui/jni/android_graphics_Canvas.cpp
+++ b/libs/hwui/jni/android_graphics_Canvas.cpp
@@ -21,6 +21,7 @@
 #else
 #define __ANDROID_API_P__ 28
 #endif
+#include <Mesh.h>
 #include <androidfw/ResourceTypes.h>
 #include <hwui/Canvas.h>
 #include <hwui/Paint.h>
@@ -30,8 +31,8 @@
 #include <nativehelper/ScopedPrimitiveArray.h>
 #include <nativehelper/ScopedStringChars.h>
 
-#include "FontUtils.h"
 #include "Bitmap.h"
+#include "FontUtils.h"
 #include "SkBitmap.h"
 #include "SkBlendMode.h"
 #include "SkClipOp.h"
@@ -42,10 +43,10 @@
 #include "SkMatrix.h"
 #include "SkPath.h"
 #include "SkPoint.h"
+#include "SkRRect.h"
 #include "SkRect.h"
 #include "SkRefCnt.h"
 #include "SkRegion.h"
-#include "SkRRect.h"
 #include "SkScalar.h"
 #include "SkVertices.h"
 
@@ -443,6 +444,14 @@
                            blendMode, *paint);
 }
 
+static void drawMesh(JNIEnv* env, jobject, jlong canvasHandle, jlong meshHandle, jint modeHandle,
+                     jlong paintHandle) {
+    const SkMesh mesh = reinterpret_cast<MeshWrapper*>(meshHandle)->mesh;
+    SkBlendMode blendMode = static_cast<SkBlendMode>(modeHandle);
+    SkPaint* paint = reinterpret_cast<Paint*>(paintHandle);
+    get_canvas(canvasHandle)->drawMesh(mesh, SkBlender::Mode(blendMode), *paint);
+}
+
 static void drawNinePatch(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
         jlong chunkHandle, jfloat left, jfloat top, jfloat right, jfloat bottom,
         jlong paintHandle, jint dstDensity, jint srcDensity) {
@@ -761,38 +770,38 @@
 // If called from Canvas these are regular JNI
 // If called from DisplayListCanvas they are @FastNative
 static const JNINativeMethod gDrawMethods[] = {
-    {"nDrawColor","(JII)V", (void*) CanvasJNI::drawColor},
-    {"nDrawColor","(JJJI)V", (void*) CanvasJNI::drawColorLong},
-    {"nDrawPaint","(JJ)V", (void*) CanvasJNI::drawPaint},
-    {"nDrawPoint", "(JFFJ)V", (void*) CanvasJNI::drawPoint},
-    {"nDrawPoints", "(J[FIIJ)V", (void*) CanvasJNI::drawPoints},
-    {"nDrawLine", "(JFFFFJ)V", (void*) CanvasJNI::drawLine},
-    {"nDrawLines", "(J[FIIJ)V", (void*) CanvasJNI::drawLines},
-    {"nDrawRect","(JFFFFJ)V", (void*) CanvasJNI::drawRect},
-    {"nDrawRegion", "(JJJ)V", (void*) CanvasJNI::drawRegion },
-    {"nDrawRoundRect","(JFFFFFFJ)V", (void*) CanvasJNI::drawRoundRect},
-    {"nDrawDoubleRoundRect", "(JFFFFFFFFFFFFJ)V", (void*) CanvasJNI::drawDoubleRoundRectXY},
-    {"nDrawDoubleRoundRect", "(JFFFF[FFFFF[FJ)V", (void*) CanvasJNI::drawDoubleRoundRectRadii},
-    {"nDrawCircle","(JFFFJ)V", (void*) CanvasJNI::drawCircle},
-    {"nDrawOval","(JFFFFJ)V", (void*) CanvasJNI::drawOval},
-    {"nDrawArc","(JFFFFFFZJ)V", (void*) CanvasJNI::drawArc},
-    {"nDrawPath","(JJJ)V", (void*) CanvasJNI::drawPath},
-    {"nDrawVertices", "(JII[FI[FI[II[SIIJ)V", (void*)CanvasJNI::drawVertices},
-    {"nDrawNinePatch", "(JJJFFFFJII)V", (void*)CanvasJNI::drawNinePatch},
-    {"nDrawBitmapMatrix", "(JJJJ)V", (void*)CanvasJNI::drawBitmapMatrix},
-    {"nDrawBitmapMesh", "(JJII[FI[IIJ)V", (void*)CanvasJNI::drawBitmapMesh},
-    {"nDrawBitmap","(JJFFJIII)V", (void*) CanvasJNI::drawBitmap},
-    {"nDrawBitmap","(JJFFFFFFFFJII)V", (void*) CanvasJNI::drawBitmapRect},
-    {"nDrawBitmap", "(J[IIIFFIIZJ)V", (void*)CanvasJNI::drawBitmapArray},
-    {"nDrawGlyphs", "(J[I[FIIIJJ)V", (void*)CanvasJNI::drawGlyphs},
-    {"nDrawText","(J[CIIFFIJ)V", (void*) CanvasJNI::drawTextChars},
-    {"nDrawText","(JLjava/lang/String;IIFFIJ)V", (void*) CanvasJNI::drawTextString},
-    {"nDrawTextRun","(J[CIIIIFFZJJ)V", (void*) CanvasJNI::drawTextRunChars},
-    {"nDrawTextRun","(JLjava/lang/String;IIIIFFZJ)V", (void*) CanvasJNI::drawTextRunString},
-    {"nDrawTextOnPath","(J[CIIJFFIJ)V", (void*) CanvasJNI::drawTextOnPathChars},
-    {"nDrawTextOnPath","(JLjava/lang/String;JFFIJ)V", (void*) CanvasJNI::drawTextOnPathString},
-    {"nPunchHole", "(JFFFFFFF)V", (void*) CanvasJNI::punchHole}
-};
+        {"nDrawColor", "(JII)V", (void*)CanvasJNI::drawColor},
+        {"nDrawColor", "(JJJI)V", (void*)CanvasJNI::drawColorLong},
+        {"nDrawPaint", "(JJ)V", (void*)CanvasJNI::drawPaint},
+        {"nDrawPoint", "(JFFJ)V", (void*)CanvasJNI::drawPoint},
+        {"nDrawPoints", "(J[FIIJ)V", (void*)CanvasJNI::drawPoints},
+        {"nDrawLine", "(JFFFFJ)V", (void*)CanvasJNI::drawLine},
+        {"nDrawLines", "(J[FIIJ)V", (void*)CanvasJNI::drawLines},
+        {"nDrawRect", "(JFFFFJ)V", (void*)CanvasJNI::drawRect},
+        {"nDrawRegion", "(JJJ)V", (void*)CanvasJNI::drawRegion},
+        {"nDrawRoundRect", "(JFFFFFFJ)V", (void*)CanvasJNI::drawRoundRect},
+        {"nDrawDoubleRoundRect", "(JFFFFFFFFFFFFJ)V", (void*)CanvasJNI::drawDoubleRoundRectXY},
+        {"nDrawDoubleRoundRect", "(JFFFF[FFFFF[FJ)V", (void*)CanvasJNI::drawDoubleRoundRectRadii},
+        {"nDrawCircle", "(JFFFJ)V", (void*)CanvasJNI::drawCircle},
+        {"nDrawOval", "(JFFFFJ)V", (void*)CanvasJNI::drawOval},
+        {"nDrawArc", "(JFFFFFFZJ)V", (void*)CanvasJNI::drawArc},
+        {"nDrawPath", "(JJJ)V", (void*)CanvasJNI::drawPath},
+        {"nDrawVertices", "(JII[FI[FI[II[SIIJ)V", (void*)CanvasJNI::drawVertices},
+        {"nDrawMesh", "(JJIJ)V", (void*)CanvasJNI::drawMesh},
+        {"nDrawNinePatch", "(JJJFFFFJII)V", (void*)CanvasJNI::drawNinePatch},
+        {"nDrawBitmapMatrix", "(JJJJ)V", (void*)CanvasJNI::drawBitmapMatrix},
+        {"nDrawBitmapMesh", "(JJII[FI[IIJ)V", (void*)CanvasJNI::drawBitmapMesh},
+        {"nDrawBitmap", "(JJFFJIII)V", (void*)CanvasJNI::drawBitmap},
+        {"nDrawBitmap", "(JJFFFFFFFFJII)V", (void*)CanvasJNI::drawBitmapRect},
+        {"nDrawBitmap", "(J[IIIFFIIZJ)V", (void*)CanvasJNI::drawBitmapArray},
+        {"nDrawGlyphs", "(J[I[FIIIJJ)V", (void*)CanvasJNI::drawGlyphs},
+        {"nDrawText", "(J[CIIFFIJ)V", (void*)CanvasJNI::drawTextChars},
+        {"nDrawText", "(JLjava/lang/String;IIFFIJ)V", (void*)CanvasJNI::drawTextString},
+        {"nDrawTextRun", "(J[CIIIIFFZJJ)V", (void*)CanvasJNI::drawTextRunChars},
+        {"nDrawTextRun", "(JLjava/lang/String;IIIIFFZJ)V", (void*)CanvasJNI::drawTextRunString},
+        {"nDrawTextOnPath", "(J[CIIJFFIJ)V", (void*)CanvasJNI::drawTextOnPathChars},
+        {"nDrawTextOnPath", "(JLjava/lang/String;JFFIJ)V", (void*)CanvasJNI::drawTextOnPathString},
+        {"nPunchHole", "(JFFFFFFF)V", (void*)CanvasJNI::punchHole}};
 
 int register_android_graphics_Canvas(JNIEnv* env) {
     int ret = 0;