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/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index 54d6428..e62ac46 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -96,7 +96,7 @@
// These are also implemented in RecordingCanvas so that we can
// selectively apply on them
// Everything below here is copy/pasted from Canvas.java
- // The JNI registration is handled by android_view_Canvas.cpp
+ // The JNI registration is handled by android_graphics_Canvas.cpp
// ---------------------------------------------------------------------------
public void drawArc(float left, float top, float right, float bottom, float startAngle,
@@ -670,6 +670,17 @@
/**
* @hide
*/
+ public void drawMesh(Mesh mesh, BlendMode blendMode, Paint paint) {
+ if (!isHardwareAccelerated() && onHwFeatureInSwMode()) {
+ throw new RuntimeException("software rendering doesn't support meshes");
+ }
+ nDrawMesh(this.mNativeCanvasWrapper, mesh.getNativeWrapperInstance(),
+ blendMode.getXfermode().porterDuffMode, paint.getNativeInstance());
+ }
+
+ /**
+ * @hide
+ */
public void punchHole(float left, float top, float right, float bottom, float rx, float ry,
float alpha) {
nPunchHole(mNativeCanvasWrapper, left, top, right, bottom, rx, ry, alpha);
@@ -801,6 +812,9 @@
int vertOffset, float[] texs, int texOffset, int[] colors, int colorOffset,
short[] indices, int indexOffset, int indexCount, long nativePaint);
+ private static native void nDrawMesh(
+ long nativeCanvas, long nativeMesh, int mode, long nativePaint);
+
private static native void nDrawGlyphs(long nativeCanvas, int[] glyphIds, float[] positions,
int glyphIdStart, int positionStart, int glyphCount, long nativeFont, long nativePaint);
diff --git a/graphics/java/android/graphics/BaseRecordingCanvas.java b/graphics/java/android/graphics/BaseRecordingCanvas.java
index 1ba79b8..eeff694 100644
--- a/graphics/java/android/graphics/BaseRecordingCanvas.java
+++ b/graphics/java/android/graphics/BaseRecordingCanvas.java
@@ -606,6 +606,12 @@
indices, indexOffset, indexCount, paint.getNativeInstance());
}
+ @Override
+ public final void drawMesh(Mesh mesh, BlendMode blendMode, Paint paint) {
+ nDrawMesh(mNativeCanvasWrapper, mesh.getNativeWrapperInstance(),
+ blendMode.getXfermode().porterDuffMode, paint.getNativeInstance());
+ }
+
/**
* @hide
*/
@@ -708,6 +714,10 @@
long nativePaint);
@FastNative
+ private static native void nDrawMesh(
+ long canvasHandle, long nativeMesh, int mode, long nativePaint);
+
+ @FastNative
private static native void nDrawVertices(long nativeCanvas, int mode, int n, float[] verts,
int vertOffset, float[] texs, int texOffset, int[] colors, int colorOffset,
short[] indices, int indexOffset, int indexCount, long nativePaint);
diff --git a/graphics/java/android/graphics/Mesh.java b/graphics/java/android/graphics/Mesh.java
index f0a0cf4..f32e0ee 100644
--- a/graphics/java/android/graphics/Mesh.java
+++ b/graphics/java/android/graphics/Mesh.java
@@ -196,7 +196,6 @@
}
nativeUpdateUniforms(
mNativeMeshWrapper, uniformName, value1, value2, value3, value4, count);
- nativeUpdateMesh(mNativeMeshWrapper);
}
private void setUniform(String uniformName, float[] values, boolean isColor) {
@@ -208,7 +207,6 @@
}
nativeUpdateUniforms(mNativeMeshWrapper, uniformName, values, isColor);
- nativeUpdateMesh(mNativeMeshWrapper);
}
/**
@@ -271,7 +269,14 @@
throw new NullPointerException("The uniform values parameter must not be null");
}
nativeUpdateUniforms(mNativeMeshWrapper, uniformName, values);
- nativeUpdateMesh(mNativeMeshWrapper);
+ }
+
+ /**
+ * @hide so only calls from module can utilize it
+ */
+ long getNativeWrapperInstance() {
+ nativeUpdateMesh(mNativeMeshWrapper, mIsIndexed);
+ return mNativeMeshWrapper;
}
private void setIntUniform(
@@ -282,7 +287,6 @@
nativeUpdateUniforms(
mNativeMeshWrapper, uniformName, value1, value2, value3, value4, count);
- nativeUpdateMesh(mNativeMeshWrapper);
}
private Mesh(long nativeMeshWrapper, boolean isIndexed) {
@@ -313,5 +317,5 @@
private static native void nativeUpdateUniforms(long builder, String uniformName, int[] values);
- private static native void nativeUpdateMesh(long nativeMeshWrapper);
+ private static native void nativeUpdateMesh(long nativeMeshWrapper, boolean mIsIndexed);
}
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 88cfed9..08fbc70 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -340,6 +340,8 @@
"jni/Graphics.cpp",
"jni/ImageDecoder.cpp",
"jni/Interpolator.cpp",
+ "jni/MeshSpecification.cpp",
+ "jni/Mesh.cpp",
"jni/MaskFilter.cpp",
"jni/NinePatch.cpp",
"jni/NinePatchPeeker.cpp",
diff --git a/libs/hwui/DisplayListOps.in b/libs/hwui/DisplayListOps.in
index 4ec782f..e2127ef 100644
--- a/libs/hwui/DisplayListOps.in
+++ b/libs/hwui/DisplayListOps.in
@@ -52,3 +52,4 @@
X(DrawVectorDrawable)
X(DrawRippleDrawable)
X(DrawWebView)
+X(DrawMesh)
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index f5ebfd5..c98a2d4 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -15,11 +15,13 @@
*/
#include "RecordingCanvas.h"
-#include <hwui/Paint.h>
#include <GrRecordingContext.h>
+#include <SkMesh.h>
+#include <hwui/Paint.h>
#include <experimental/type_traits>
+#include <utility>
#include "SkAndroidFrameworkUtils.h"
#include "SkCanvas.h"
@@ -270,7 +272,6 @@
SkPaint paint;
void draw(SkCanvas* c, const SkMatrix&) const { c->drawDRRect(outer, inner, paint); }
};
-
struct DrawAnnotation final : Op {
static const auto kType = Type::DrawAnnotation;
DrawAnnotation(const SkRect& rect, SkData* value) : rect(rect), value(sk_ref_sp(value)) {}
@@ -452,6 +453,16 @@
c->drawVertices(vertices, mode, paint);
}
};
+struct DrawMesh final : Op {
+ static const auto kType = Type::DrawMesh;
+ DrawMesh(const SkMesh& mesh, sk_sp<SkBlender> blender, const SkPaint& paint)
+ : mesh(mesh), blender(std::move(blender)), paint(paint) {}
+
+ SkMesh mesh;
+ sk_sp<SkBlender> blender;
+ SkPaint paint;
+ void draw(SkCanvas* c, const SkMatrix&) const { c->drawMesh(mesh, blender, paint); }
+};
struct DrawAtlas final : Op {
static const auto kType = Type::DrawAtlas;
DrawAtlas(const SkImage* atlas, int count, SkBlendMode mode, const SkSamplingOptions& sampling,
@@ -763,6 +774,10 @@
void DisplayListData::drawVertices(const SkVertices* vert, SkBlendMode mode, const SkPaint& paint) {
this->push<DrawVertices>(0, vert, mode, paint);
}
+void DisplayListData::drawMesh(const SkMesh& mesh, const sk_sp<SkBlender>& blender,
+ const SkPaint& paint) {
+ this->push<DrawMesh>(0, mesh, blender, paint);
+}
void DisplayListData::drawAtlas(const SkImage* atlas, const SkRSXform xforms[], const SkRect texs[],
const SkColor colors[], int count, SkBlendMode xfermode,
const SkSamplingOptions& sampling, const SkRect* cull,
@@ -1105,6 +1120,10 @@
SkBlendMode mode, const SkPaint& paint) {
fDL->drawVertices(vertices, mode, paint);
}
+void RecordingCanvas::onDrawMesh(const SkMesh& mesh, sk_sp<SkBlender> blender,
+ const SkPaint& paint) {
+ fDL->drawMesh(mesh, blender, paint);
+}
void RecordingCanvas::onDrawAtlas2(const SkImage* atlas, const SkRSXform xforms[],
const SkRect texs[], const SkColor colors[], int count,
SkBlendMode bmode, const SkSamplingOptions& sampling,
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 35bec93..1ec7b36 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -111,6 +111,8 @@
void drawRRect(const SkRRect&, const SkPaint&);
void drawDRRect(const SkRRect&, const SkRRect&, const SkPaint&);
+ void drawMesh(const SkMesh&, const sk_sp<SkBlender>&, const SkPaint&);
+
void drawAnnotation(const SkRect&, const char*, SkData*);
void drawDrawable(SkDrawable*, const SkMatrix*);
void drawPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
@@ -210,6 +212,7 @@
const SkPaint&) override;
void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
+ void onDrawMesh(const SkMesh&, sk_sp<SkBlender>, const SkPaint&) override;
void onDrawAtlas2(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
SkBlendMode, const SkSamplingOptions&, const SkRect*, const SkPaint*) override;
void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 473afbd..d83d78f 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -570,6 +570,10 @@
applyLooper(&paint, [&](const SkPaint& p) { mCanvas->drawVertices(vertices, mode, p); });
}
+void SkiaCanvas::drawMesh(const SkMesh& mesh, sk_sp<SkBlender> blender, const SkPaint& paint) {
+ mCanvas->drawMesh(mesh, blender, paint);
+}
+
// ----------------------------------------------------------------------------
// Canvas draw operations: Bitmaps
// ----------------------------------------------------------------------------
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 51007c5..19ebf39 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -119,8 +119,8 @@
virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
const Paint& paint) override;
- virtual void drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner,
- const Paint& paint) override;
+ virtual void drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner,
+ const Paint& paint) override;
virtual void drawCircle(float x, float y, float radius, const Paint& paint) override;
virtual void drawOval(float left, float top, float right, float bottom,
@@ -129,6 +129,8 @@
float sweepAngle, bool useCenter, const Paint& paint) override;
virtual void drawPath(const SkPath& path, const Paint& paint) override;
virtual void drawVertices(const SkVertices*, SkBlendMode, const Paint& paint) override;
+ virtual void drawMesh(const SkMesh& mesh, sk_sp<SkBlender> blender,
+ const SkPaint& paint) override;
virtual void drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) override;
virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const Paint* paint) override;
diff --git a/libs/hwui/apex/jni_runtime.cpp b/libs/hwui/apex/jni_runtime.cpp
index 39725a5..e6cfa7b 100644
--- a/libs/hwui/apex/jni_runtime.cpp
+++ b/libs/hwui/apex/jni_runtime.cpp
@@ -76,6 +76,8 @@
extern int register_android_graphics_text_MeasuredText(JNIEnv* env);
extern int register_android_graphics_text_LineBreaker(JNIEnv *env);
extern int register_android_graphics_text_TextShaper(JNIEnv *env);
+extern int register_android_graphics_MeshSpecification(JNIEnv* env);
+extern int register_android_graphics_Mesh(JNIEnv* env);
extern int register_android_util_PathParser(JNIEnv* env);
extern int register_android_view_DisplayListCanvas(JNIEnv* env);
@@ -143,6 +145,8 @@
REG_JNI(register_android_graphics_text_MeasuredText),
REG_JNI(register_android_graphics_text_LineBreaker),
REG_JNI(register_android_graphics_text_TextShaper),
+ REG_JNI(register_android_graphics_MeshSpecification),
+ REG_JNI(register_android_graphics_Mesh),
REG_JNI(register_android_util_PathParser),
REG_JNI(register_android_view_RenderNode),
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 82d23b5..c148ad2 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -226,6 +226,7 @@
float sweepAngle, bool useCenter, const Paint& paint) = 0;
virtual void drawPath(const SkPath& path, const Paint& paint) = 0;
virtual void drawVertices(const SkVertices*, SkBlendMode, const Paint& paint) = 0;
+ virtual void drawMesh(const SkMesh& mesh, sk_sp<SkBlender>, const SkPaint& paint) = 0;
// Bitmap-based
virtual void drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) = 0;
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;
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 939c7de..7383d6a 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -1146,5 +1146,13 @@
</intent-filter>
</activity>
+ <activity android:name="MeshActivity"
+ android:label="Mesh/SimpleMesh"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="com.android.test.hwui.TEST"/>
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MeshActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MeshActivity.java
new file mode 100644
index 0000000..efe242c
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MeshActivity.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.BlendMode;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Mesh;
+import android.graphics.MeshSpecification;
+import android.graphics.MeshSpecification.Attribute;
+import android.graphics.MeshSpecification.Varying;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.view.View;
+
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+public class MeshActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(new MeshView(this));
+ }
+
+ static class MeshView extends View {
+ MeshView(Context c) {
+ super(c);
+ this.setOnTouchListener((v, event) -> {
+ invalidate();
+ return true;
+ });
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ MeshSpecification meshSpec = createMeshSpecification();
+ FloatBuffer vertexBuffer = FloatBuffer.allocate(6);
+ vertexBuffer.put(0, 100.0f);
+ vertexBuffer.put(1, 100.0f);
+ vertexBuffer.put(2, 400.0f);
+ vertexBuffer.put(3, 0.0f);
+ vertexBuffer.put(4, 0.0f);
+ vertexBuffer.put(5, 400.0f);
+ vertexBuffer.rewind();
+ Mesh mesh = Mesh.make(
+ meshSpec, Mesh.Mode.Triangles, vertexBuffer, 3, new Rect(0, 0, 1000, 1000));
+
+ int numTriangles = 100;
+ // number of triangles plus first 2 vertices
+ FloatBuffer iVertexBuffer = FloatBuffer.allocate(numTriangles * 2 + 4);
+ ShortBuffer indexBuffer = ShortBuffer.allocate(300);
+
+ int radius = 200;
+ // origin
+ iVertexBuffer.put(0, 500.0f);
+ iVertexBuffer.put(1, 500.0f);
+
+ // first point
+ iVertexBuffer.put(2, 500.0f + radius);
+ iVertexBuffer.put(3, 500.0f);
+ int nVert = 2;
+ int nInd = 0;
+ for (int i = 1; i <= numTriangles; i++) {
+ double angle = (Math.PI * i) / numTriangles;
+ double x = radius * Math.cos(angle);
+ double y = radius * Math.sin(angle);
+ iVertexBuffer.put((i + 1) * 2, 500 + (float) x);
+ iVertexBuffer.put((i + 1) * 2 + 1, 500 + (float) y);
+
+ indexBuffer.put(nInd++, (short) 0);
+ indexBuffer.put(nInd++, (short) (nVert - 1));
+ indexBuffer.put(nInd++, (short) nVert);
+ nVert++;
+ }
+ iVertexBuffer.rewind();
+ indexBuffer.rewind();
+ Mesh mesh2 = Mesh.makeIndexed(meshSpec, Mesh.Mode.Triangles, iVertexBuffer, 102,
+ indexBuffer, new Rect(0, 0, 1000, 1000));
+
+ Paint paint = new Paint();
+ paint.setColor(Color.RED);
+ canvas.drawMesh(mesh, BlendMode.COLOR, new Paint());
+ canvas.drawMesh(mesh2, BlendMode.COLOR, paint);
+ }
+
+ private MeshSpecification createMeshSpecification() {
+ String vs = "Varyings main(const Attributes attributes) { "
+ + " Varyings varyings;"
+ + " varyings.position = attributes.position;"
+ + " return varyings;"
+ + "}";
+ String fs = "float2 main(const Varyings varyings, out float4 color) {\n"
+ + " color = vec4(1.0, 0.0, 0.0, 1.0);"
+ + " return varyings.position;\n"
+ + "}";
+ Attribute[] attList =
+ new Attribute[] {new Attribute(MeshSpecification.FLOAT2, 0, "position")};
+ Varying[] varyList =
+ new MeshSpecification.Varying[] {};
+ return MeshSpecification.make(attList, 8, varyList, vs, fs);
+ }
+ }
+}