diff options
author | 2022-11-08 23:42:09 +0000 | |
---|---|---|
committer | 2022-12-03 02:11:46 +0000 | |
commit | 90c46ee50b07cc9e85b5fd28dacc6d14e50af421 (patch) | |
tree | af747d2cae55a20cd8c1dc440b2a89144f200929 | |
parent | 8af9e2cddd89e64d3712572613b05d7c9771f31d (diff) |
Exposed SkCanvas::drawMesh
Added drawMesh method to the Canvas API, utilizing SkCanvas::drawMesh.
Bug: b/253321460
Test: HwAccelerationTest MeshActivity
Change-Id: I43802af61bbd6f76444b4e4b7cec2b95bae34f66
-rw-r--r-- | graphics/java/android/graphics/BaseCanvas.java | 16 | ||||
-rw-r--r-- | graphics/java/android/graphics/BaseRecordingCanvas.java | 10 | ||||
-rw-r--r-- | graphics/java/android/graphics/Mesh.java | 14 | ||||
-rw-r--r-- | libs/hwui/Android.bp | 2 | ||||
-rw-r--r-- | libs/hwui/DisplayListOps.in | 1 | ||||
-rw-r--r-- | libs/hwui/RecordingCanvas.cpp | 23 | ||||
-rw-r--r-- | libs/hwui/RecordingCanvas.h | 3 | ||||
-rw-r--r-- | libs/hwui/SkiaCanvas.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/SkiaCanvas.h | 6 | ||||
-rw-r--r-- | libs/hwui/apex/jni_runtime.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/hwui/Canvas.h | 1 | ||||
-rw-r--r-- | libs/hwui/jni/Mesh.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/jni/MeshSpecification.cpp | 47 | ||||
-rw-r--r-- | libs/hwui/jni/android_graphics_Canvas.cpp | 77 | ||||
-rw-r--r-- | tests/HwAccelerationTest/AndroidManifest.xml | 8 | ||||
-rw-r--r-- | tests/HwAccelerationTest/src/com/android/test/hwui/MeshActivity.java | 124 |
16 files changed, 280 insertions, 66 deletions
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java index 54d64280c6f7..e62ac466ac43 100644 --- a/graphics/java/android/graphics/BaseCanvas.java +++ b/graphics/java/android/graphics/BaseCanvas.java @@ -96,7 +96,7 @@ public abstract class BaseCanvas { // 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 @@ public abstract class BaseCanvas { /** * @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 @@ public abstract class BaseCanvas { 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 1ba79b87e87c..eeff694eb3ac 100644 --- a/graphics/java/android/graphics/BaseRecordingCanvas.java +++ b/graphics/java/android/graphics/BaseRecordingCanvas.java @@ -606,6 +606,12 @@ public class BaseRecordingCanvas extends Canvas { 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 @@ public class BaseRecordingCanvas extends Canvas { 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 f0a0cf40ffa9..f32e0ee0cc79 100644 --- a/graphics/java/android/graphics/Mesh.java +++ b/graphics/java/android/graphics/Mesh.java @@ -196,7 +196,6 @@ public class Mesh { } nativeUpdateUniforms( mNativeMeshWrapper, uniformName, value1, value2, value3, value4, count); - nativeUpdateMesh(mNativeMeshWrapper); } private void setUniform(String uniformName, float[] values, boolean isColor) { @@ -208,7 +207,6 @@ public class Mesh { } nativeUpdateUniforms(mNativeMeshWrapper, uniformName, values, isColor); - nativeUpdateMesh(mNativeMeshWrapper); } /** @@ -271,7 +269,14 @@ public class Mesh { 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 @@ public class Mesh { nativeUpdateUniforms( mNativeMeshWrapper, uniformName, value1, value2, value3, value4, count); - nativeUpdateMesh(mNativeMeshWrapper); } private Mesh(long nativeMeshWrapper, boolean isIndexed) { @@ -313,5 +317,5 @@ public class Mesh { 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 88cfed9357d8..08fbc70c8221 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -340,6 +340,8 @@ cc_defaults { "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 4ec782f6fec0..e2127efca716 100644 --- a/libs/hwui/DisplayListOps.in +++ b/libs/hwui/DisplayListOps.in @@ -52,3 +52,4 @@ X(DrawShadowRec) X(DrawVectorDrawable) X(DrawRippleDrawable) X(DrawWebView) +X(DrawMesh) diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index f5ebfd5d9e23..c98a2d414b5b 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 @@ struct DrawDRRect final : Op { 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 @@ struct DrawVertices final : Op { 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::drawPoints(SkCanvas::PointMode mode, size_t count, const S 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 @@ void RecordingCanvas::onDrawVerticesObject(const SkVertices* vertices, 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 35bec9335d7c..1ec7b365235f 100644 --- a/libs/hwui/RecordingCanvas.h +++ b/libs/hwui/RecordingCanvas.h @@ -111,6 +111,8 @@ private: 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 @@ public: 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 473afbd2aa2f..d83d78f650aa 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -570,6 +570,10 @@ void SkiaCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, cons 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 51007c52260d..19ebf39ea30f 100644 --- a/libs/hwui/SkiaCanvas.h +++ b/libs/hwui/SkiaCanvas.h @@ -119,8 +119,8 @@ public: 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 @@ public: 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 39725a55b594..e6cfa7bcaf70 100644 --- a/libs/hwui/apex/jni_runtime.cpp +++ b/libs/hwui/apex/jni_runtime.cpp @@ -76,6 +76,8 @@ extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env); 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 @@ extern int register_android_view_ThreadedRenderer(JNIEnv* env); 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 82d23b51b12a..c148ad24c9de 100644 --- a/libs/hwui/hwui/Canvas.h +++ b/libs/hwui/hwui/Canvas.h @@ -226,6 +226,7 @@ public: 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 6dba6c1a966b..109aac321b6e 100644 --- a/libs/hwui/jni/Mesh.cpp +++ b/libs/hwui/jni/Mesh.cpp @@ -42,7 +42,7 @@ static jlong make(JNIEnv* env, jobject, jlong meshSpec, jint mode, jobject verte 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 @@ static jlong makeIndexed(JNIEnv* env, jobject, jlong meshSpec, jint mode, jobjec 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 22fa4d39e2ed..619a3ed552d8 100644 --- a/libs/hwui/jni/MeshSpecification.cpp +++ b/libs/hwui/jni/MeshSpecification.cpp @@ -50,7 +50,6 @@ std::vector<Attribute> extractAttributes(JNIEnv* env, jobjectArray attributes) { SkString(attName.c_str())}; attVector.push_back(std::move(temp)); } - return attVector; } @@ -76,11 +75,15 @@ static jlong Make(JNIEnv* env, jobject thiz, jobjectArray attributeArray, jint v 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 @@ static jlong MakeWithCS(JNIEnv* env, jobject thiz, jobjectArray attributeArray, 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 @@ static jlong MakeWithAlpha(JNIEnv* env, jobject thiz, jobjectArray attributeArra 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 @@ int register_android_graphics_MeshSpecification(JNIEnv* env) { 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 0513447ed05e..8a4d4e17edb1 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 @@ static void drawVertices(JNIEnv* env, jobject, jlong canvasHandle, 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 @@ static const JNINativeMethod gMethods[] = { // 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 939c7de22356..7383d6ab4994 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 000000000000..efe242ce728e --- /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); + } + } +} |