diff options
| author | 2016-12-14 18:03:18 +0000 | |
|---|---|---|
| committer | 2016-12-14 18:03:22 +0000 | |
| commit | 15589c36d7ca999b0870aba2ffec11f8651d1ee0 (patch) | |
| tree | b1c1d559d97b35661f130a719d5417da7e99729e | |
| parent | 82f8f3e04eca0bd56cfdaae5250ba9576ef199f5 (diff) | |
| parent | 2414e1b051326745e087a88cdfbf1fff8962edd3 (diff) | |
Merge "Outline & Path perf improvements"
| -rw-r--r-- | apct-tests/perftests/core/src/android/graphics/perftests/PathPerfTest.java | 112 | ||||
| -rw-r--r-- | core/jni/android/graphics/Path.cpp | 247 | ||||
| -rw-r--r-- | graphics/java/android/graphics/Outline.java | 36 | ||||
| -rw-r--r-- | graphics/java/android/graphics/Path.java | 200 |
4 files changed, 381 insertions, 214 deletions
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/PathPerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/PathPerfTest.java new file mode 100644 index 000000000000..7a49b4f456b1 --- /dev/null +++ b/apct-tests/perftests/core/src/android/graphics/perftests/PathPerfTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2016 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 android.graphics.perftests; + +import android.graphics.Path; +import android.graphics.RectF; +import android.perftests.utils.BenchmarkState; +import android.perftests.utils.PerfStatusReporter; +import android.support.test.filters.LargeTest; + +import org.junit.Rule; +import org.junit.Test; + +@LargeTest +public class PathPerfTest { + @Rule + public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); + + @Test + public void testReset() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + Path path = new Path(); + while (state.keepRunning()) { + path.reset(); + } + } + + @Test + public void testAddReset() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + Path path = new Path(); + while (state.keepRunning()) { + path.addRect(0, 0, 100, 100, Path.Direction.CW); + path.reset(); + } + } + + @Test + public void testRewind() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + Path path = new Path(); + while (state.keepRunning()) { + path.rewind(); + } + } + + @Test + public void testAddRewind() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + Path path = new Path(); + while (state.keepRunning()) { + path.addRect(0, 0, 100, 100, Path.Direction.CW); + path.rewind(); + } + } + + @Test + public void testIsEmpty() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + Path path = new Path(); + path.addRect(0, 0, 100, 100, Path.Direction.CW); + while (state.keepRunning()) { + path.isEmpty(); + } + } + + @Test + public void testIsConvex() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + Path path = new Path(); + path.addRect(0, 0, 100, 100, Path.Direction.CW); + while (state.keepRunning()) { + path.isConvex(); + } + } + + @Test + public void testGetSetFillType() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + Path path = new Path(); + path.addRect(0, 0, 100, 100, Path.Direction.CW); + while (state.keepRunning()) { + path.setFillType(Path.FillType.EVEN_ODD); + path.getFillType(); + } + } + + @Test + public void testIsRect() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + Path path = new Path(); + path.addRect(0, 0, 100, 100, Path.Direction.CW); + final RectF outRect = new RectF(); + while (state.keepRunning()) { + path.isRect(outRect); + } + } +} diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp index ab393f2bc1f1..292454bd0875 100644 --- a/core/jni/android/graphics/Path.cpp +++ b/core/jni/android/graphics/Path.cpp @@ -36,121 +36,88 @@ namespace android { class SkPathGlue { public: - static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) { - SkPath* obj = reinterpret_cast<SkPath*>(objHandle); - // Purge entries from the HWUI path cache if this path's data is unique - if (obj->unique() && android::uirenderer::Caches::hasInstance()) { - android::uirenderer::Caches::getInstance().pathCache.removeDeferred(obj); - } - delete obj; - } + // ---------------- Regular JNI ----------------------------- - static jlong init1(JNIEnv* env, jobject clazz) { + static jlong init(JNIEnv* env, jclass clazz) { return reinterpret_cast<jlong>(new SkPath()); } - static jlong init2(JNIEnv* env, jobject clazz, jlong valHandle) { + static jlong init_Path(JNIEnv* env, jclass clazz, jlong valHandle) { SkPath* val = reinterpret_cast<SkPath*>(valHandle); return reinterpret_cast<jlong>(new SkPath(*val)); } - static void reset(JNIEnv* env, jobject clazz, jlong objHandle) { + static void finalize(JNIEnv* env, jclass clazz, jlong objHandle) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); - obj->reset(); - } - - static void rewind(JNIEnv* env, jobject clazz, jlong objHandle) { - SkPath* obj = reinterpret_cast<SkPath*>(objHandle); - obj->rewind(); + // Purge entries from the HWUI path cache if this path's data is unique + if (obj->unique() && android::uirenderer::Caches::hasInstance()) { + android::uirenderer::Caches::getInstance().pathCache.removeDeferred(obj); + } + delete obj; } - static void assign(JNIEnv* env, jobject clazz, jlong dstHandle, jlong srcHandle) { + static void set(JNIEnv* env, jclass clazz, jlong dstHandle, jlong srcHandle) { SkPath* dst = reinterpret_cast<SkPath*>(dstHandle); const SkPath* src = reinterpret_cast<SkPath*>(srcHandle); *dst = *src; } - static jboolean isConvex(JNIEnv* env, jobject clazz, jlong objHandle) { - SkPath* obj = reinterpret_cast<SkPath*>(objHandle); - return obj->isConvex(); - } - - static jint getFillType(JNIEnv* env, jobject clazz, jlong objHandle) { - SkPath* obj = reinterpret_cast<SkPath*>(objHandle); - return obj->getFillType(); - } - - static void setFillType(JNIEnv* env, jobject clazz, jlong pathHandle, jint ftHandle) { - SkPath* path = reinterpret_cast<SkPath*>(pathHandle); - SkPath::FillType ft = static_cast<SkPath::FillType>(ftHandle); - path->setFillType(ft); - } - - static jboolean isEmpty(JNIEnv* env, jobject clazz, jlong objHandle) { - SkPath* obj = reinterpret_cast<SkPath*>(objHandle); - return obj->isEmpty(); - } - - static jboolean isRect(JNIEnv* env, jobject clazz, jlong objHandle, jobject jrect) { - SkRect rect; - SkPath* obj = reinterpret_cast<SkPath*>(objHandle); - jboolean result = obj->isRect(&rect); - GraphicsJNI::rect_to_jrectf(rect, env, jrect); - return result; - } - - static void computeBounds(JNIEnv* env, jobject clazz, jlong objHandle, jobject jbounds) { + static void computeBounds(JNIEnv* env, jclass clazz, jlong objHandle, jobject jbounds) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); const SkRect& bounds = obj->getBounds(); GraphicsJNI::rect_to_jrectf(bounds, env, jbounds); } - static void incReserve(JNIEnv* env, jobject clazz, jlong objHandle, jint extraPtCount) { + static void incReserve(JNIEnv* env, jclass clazz, jlong objHandle, jint extraPtCount) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->incReserve(extraPtCount); } - static void moveTo__FF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat x, jfloat y) { + static void moveTo__FF(JNIEnv* env, jclass clazz, jlong objHandle, jfloat x, jfloat y) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->moveTo(x, y); } - static void rMoveTo(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy) { + static void rMoveTo(JNIEnv* env, jclass clazz, jlong objHandle, jfloat dx, jfloat dy) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->rMoveTo(dx, dy); } - static void lineTo__FF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat x, jfloat y) { + static void lineTo__FF(JNIEnv* env, jclass clazz, jlong objHandle, jfloat x, jfloat y) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->lineTo(x, y); } - static void rLineTo(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy) { + static void rLineTo(JNIEnv* env, jclass clazz, jlong objHandle, jfloat dx, jfloat dy) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->rLineTo(dx, dy); } - static void quadTo__FFFF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat x1, jfloat y1, jfloat x2, jfloat y2) { + static void quadTo__FFFF(JNIEnv* env, jclass clazz, jlong objHandle, jfloat x1, jfloat y1, + jfloat x2, jfloat y2) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->quadTo(x1, y1, x2, y2); } - static void rQuadTo(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx1, jfloat dy1, jfloat dx2, jfloat dy2) { + static void rQuadTo(JNIEnv* env, jclass clazz, jlong objHandle, jfloat dx1, jfloat dy1, + jfloat dx2, jfloat dy2) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->rQuadTo(dx1, dy1, dx2, dy2); } - static void cubicTo__FFFFFF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat x1, jfloat y1, jfloat x2, jfloat y2, jfloat x3, jfloat y3) { + static void cubicTo__FFFFFF(JNIEnv* env, jclass clazz, jlong objHandle, jfloat x1, jfloat y1, + jfloat x2, jfloat y2, jfloat x3, jfloat y3) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->cubicTo(x1, y1, x2, y2, x3, y3); } - static void rCubicTo(JNIEnv* env, jobject clazz, jlong objHandle, jfloat x1, jfloat y1, jfloat x2, jfloat y2, jfloat x3, jfloat y3) { + static void rCubicTo(JNIEnv* env, jclass clazz, jlong objHandle, jfloat x1, jfloat y1, + jfloat x2, jfloat y2, jfloat x3, jfloat y3) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->rCubicTo(x1, y1, x2, y2, x3, y3); } - static void arcTo(JNIEnv* env, jobject clazz, jlong objHandle, jfloat left, jfloat top, + static void arcTo(JNIEnv* env, jclass clazz, jlong objHandle, jfloat left, jfloat top, jfloat right, jfloat bottom, jfloat startAngle, jfloat sweepAngle, jboolean forceMoveTo) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); @@ -158,19 +125,19 @@ public: obj->arcTo(oval, startAngle, sweepAngle, forceMoveTo); } - static void close(JNIEnv* env, jobject clazz, jlong objHandle) { + static void close(JNIEnv* env, jclass clazz, jlong objHandle) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->close(); } - static void addRect(JNIEnv* env, jobject clazz, jlong objHandle, + static void addRect(JNIEnv* env, jclass clazz, jlong objHandle, jfloat left, jfloat top, jfloat right, jfloat bottom, jint dirHandle) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); SkPath::Direction dir = static_cast<SkPath::Direction>(dirHandle); obj->addRect(left, top, right, bottom, dir); } - static void addOval(JNIEnv* env, jobject clazz, jlong objHandle, + static void addOval(JNIEnv* env, jclass clazz, jlong objHandle, jfloat left, jfloat top, jfloat right, jfloat bottom, jint dirHandle) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); SkPath::Direction dir = static_cast<SkPath::Direction>(dirHandle); @@ -178,20 +145,21 @@ public: obj->addOval(oval, dir); } - static void addCircle(JNIEnv* env, jobject clazz, jlong objHandle, jfloat x, jfloat y, jfloat radius, jint dirHandle) { + static void addCircle(JNIEnv* env, jclass clazz, jlong objHandle, jfloat x, jfloat y, + jfloat radius, jint dirHandle) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); SkPath::Direction dir = static_cast<SkPath::Direction>(dirHandle); obj->addCircle(x, y, radius, dir); } - static void addArc(JNIEnv* env, jobject clazz, jlong objHandle, jfloat left, jfloat top, + static void addArc(JNIEnv* env, jclass clazz, jlong objHandle, jfloat left, jfloat top, jfloat right, jfloat bottom, jfloat startAngle, jfloat sweepAngle) { SkRect oval = SkRect::MakeLTRB(left, top, right, bottom); SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->addArc(oval, startAngle, sweepAngle); } - static void addRoundRectXY(JNIEnv* env, jobject clazz, jlong objHandle, jfloat left, jfloat top, + static void addRoundRectXY(JNIEnv* env, jclass clazz, jlong objHandle, jfloat left, jfloat top, jfloat right, jfloat bottom, jfloat rx, jfloat ry, jint dirHandle) { SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); SkPath* obj = reinterpret_cast<SkPath*>(objHandle); @@ -199,8 +167,8 @@ public: obj->addRoundRect(rect, rx, ry, dir); } - static void addRoundRect8(JNIEnv* env, jobject, jlong objHandle, jfloat left, jfloat top, - jfloat right, jfloat bottom, jfloatArray array, jint dirHandle) { + static void addRoundRect8(JNIEnv* env, jclass clazz, jlong objHandle, jfloat left, jfloat top, + jfloat right, jfloat bottom, jfloatArray array, jint dirHandle) { SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); SkPath* obj = reinterpret_cast<SkPath*>(objHandle); SkPath::Direction dir = static_cast<SkPath::Direction>(dirHandle); @@ -213,49 +181,53 @@ public: obj->addRoundRect(rect, src, dir); } - static void addPath__PathFF(JNIEnv* env, jobject clazz, jlong objHandle, jlong srcHandle, jfloat dx, jfloat dy) { + static void addPath__PathFF(JNIEnv* env, jclass clazz, jlong objHandle, jlong srcHandle, + jfloat dx, jfloat dy) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); SkPath* src = reinterpret_cast<SkPath*>(srcHandle); obj->addPath(*src, dx, dy); } - static void addPath__Path(JNIEnv* env, jobject clazz, jlong objHandle, jlong srcHandle) { + static void addPath__Path(JNIEnv* env, jclass clazz, jlong objHandle, jlong srcHandle) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); SkPath* src = reinterpret_cast<SkPath*>(srcHandle); obj->addPath(*src); } - static void addPath__PathMatrix(JNIEnv* env, jobject clazz, jlong objHandle, jlong srcHandle, jlong matrixHandle) { + static void addPath__PathMatrix(JNIEnv* env, jclass clazz, jlong objHandle, jlong srcHandle, + jlong matrixHandle) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); SkPath* src = reinterpret_cast<SkPath*>(srcHandle); SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); obj->addPath(*src, *matrix); } - static void offset__FF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy) { + static void offset__FF(JNIEnv* env, jclass clazz, jlong objHandle, jfloat dx, jfloat dy) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->offset(dx, dy); } - static void setLastPoint(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy) { + static void setLastPoint(JNIEnv* env, jclass clazz, jlong objHandle, jfloat dx, jfloat dy) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->setLastPt(dx, dy); } - static void transform__MatrixPath(JNIEnv* env, jobject clazz, jlong objHandle, jlong matrixHandle, jlong dstHandle) { + static void transform__MatrixPath(JNIEnv* env, jclass clazz, jlong objHandle, jlong matrixHandle, + jlong dstHandle) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); SkPath* dst = reinterpret_cast<SkPath*>(dstHandle); obj->transform(*matrix, dst); } - static void transform__Matrix(JNIEnv* env, jobject clazz, jlong objHandle, jlong matrixHandle) { + static void transform__Matrix(JNIEnv* env, jclass clazz, jlong objHandle, jlong matrixHandle) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); obj->transform(*matrix); } - static jboolean op(JNIEnv* env, jobject clazz, jlong p1Handle, jlong p2Handle, jint opHandle, jlong rHandle) { + static jboolean op(JNIEnv* env, jclass clazz, jlong p1Handle, jlong p2Handle, jint opHandle, + jlong rHandle) { SkPath* p1 = reinterpret_cast<SkPath*>(p1Handle); SkPath* p2 = reinterpret_cast<SkPath*>(p2Handle); SkPathOp op = static_cast<SkPathOp>(opHandle); @@ -416,8 +388,8 @@ public: // Note that more than one point may have the same length along the path in // the case of a move. // NULL can be returned if the Path is empty. - static jfloatArray approximate(JNIEnv* env, jclass, jlong pathHandle, float acceptableError) - { + static jfloatArray approximate(JNIEnv* env, jclass clazz, jlong pathHandle, + float acceptableError) { SkPath* path = reinterpret_cast<SkPath*>(pathHandle); SkASSERT(path); SkPath::Iter pathIter(*path, false); @@ -467,47 +439,94 @@ public: delete[] approximation; return result; } + + // ---------------- @FastNative ----------------------------- + + static jboolean isRect(JNIEnv* env, jclass clazz, jlong objHandle, jobject jrect) { + SkRect rect; + SkPath* obj = reinterpret_cast<SkPath*>(objHandle); + jboolean result = obj->isRect(&rect); + GraphicsJNI::rect_to_jrectf(rect, env, jrect); + return result; + } + + // ---------------- @CriticalNative ------------------------- + + static void reset(jlong objHandle) { + SkPath* obj = reinterpret_cast<SkPath*>(objHandle); + obj->reset(); + } + + static void rewind(jlong objHandle) { + SkPath* obj = reinterpret_cast<SkPath*>(objHandle); + obj->rewind(); + } + + static jboolean isEmpty(jlong objHandle) { + SkPath* obj = reinterpret_cast<SkPath*>(objHandle); + return obj->isEmpty(); + } + + static jboolean isConvex(jlong objHandle) { + SkPath* obj = reinterpret_cast<SkPath*>(objHandle); + return obj->isConvex(); + } + + static jint getFillType(jlong objHandle) { + SkPath* obj = reinterpret_cast<SkPath*>(objHandle); + return obj->getFillType(); + } + + static void setFillType(jlong pathHandle, jint ftHandle) {; + SkPath* path = reinterpret_cast<SkPath*>(pathHandle); + SkPath::FillType ft = static_cast<SkPath::FillType>(ftHandle); + path->setFillType(ft); + } }; static const JNINativeMethod methods[] = { - {"finalizer", "(J)V", (void*) SkPathGlue::finalizer}, - {"init1","()J", (void*) SkPathGlue::init1}, - {"init2","(J)J", (void*) SkPathGlue::init2}, - {"native_reset","(J)V", (void*) SkPathGlue::reset}, - {"native_rewind","(J)V", (void*) SkPathGlue::rewind}, - {"native_set","(JJ)V", (void*) SkPathGlue::assign}, - {"native_isConvex","(J)Z", (void*) SkPathGlue::isConvex}, - {"native_getFillType","(J)I", (void*) SkPathGlue::getFillType}, - {"native_setFillType","(JI)V", (void*) SkPathGlue::setFillType}, - {"native_isEmpty","(J)Z", (void*) SkPathGlue::isEmpty}, - {"native_isRect","(JLandroid/graphics/RectF;)Z", (void*) SkPathGlue::isRect}, - {"native_computeBounds","(JLandroid/graphics/RectF;)V", (void*) SkPathGlue::computeBounds}, - {"native_incReserve","(JI)V", (void*) SkPathGlue::incReserve}, - {"native_moveTo","(JFF)V", (void*) SkPathGlue::moveTo__FF}, - {"native_rMoveTo","(JFF)V", (void*) SkPathGlue::rMoveTo}, - {"native_lineTo","(JFF)V", (void*) SkPathGlue::lineTo__FF}, - {"native_rLineTo","(JFF)V", (void*) SkPathGlue::rLineTo}, - {"native_quadTo","(JFFFF)V", (void*) SkPathGlue::quadTo__FFFF}, - {"native_rQuadTo","(JFFFF)V", (void*) SkPathGlue::rQuadTo}, - {"native_cubicTo","(JFFFFFF)V", (void*) SkPathGlue::cubicTo__FFFFFF}, - {"native_rCubicTo","(JFFFFFF)V", (void*) SkPathGlue::rCubicTo}, - {"native_arcTo","(JFFFFFFZ)V", (void*) SkPathGlue::arcTo}, - {"native_close","(J)V", (void*) SkPathGlue::close}, - {"native_addRect","(JFFFFI)V", (void*) SkPathGlue::addRect}, - {"native_addOval","(JFFFFI)V", (void*) SkPathGlue::addOval}, - {"native_addCircle","(JFFFI)V", (void*) SkPathGlue::addCircle}, - {"native_addArc","(JFFFFFF)V", (void*) SkPathGlue::addArc}, - {"native_addRoundRect","(JFFFFFFI)V", (void*) SkPathGlue::addRoundRectXY}, - {"native_addRoundRect","(JFFFF[FI)V", (void*) SkPathGlue::addRoundRect8}, - {"native_addPath","(JJFF)V", (void*) SkPathGlue::addPath__PathFF}, - {"native_addPath","(JJ)V", (void*) SkPathGlue::addPath__Path}, - {"native_addPath","(JJJ)V", (void*) SkPathGlue::addPath__PathMatrix}, - {"native_offset","(JFF)V", (void*) SkPathGlue::offset__FF}, - {"native_setLastPoint","(JFF)V", (void*) SkPathGlue::setLastPoint}, - {"native_transform","(JJJ)V", (void*) SkPathGlue::transform__MatrixPath}, - {"native_transform","(JJ)V", (void*) SkPathGlue::transform__Matrix}, - {"native_op","(JJIJ)Z", (void*) SkPathGlue::op}, - {"native_approximate", "(JF)[F", (void*) SkPathGlue::approximate}, + {"nInit","()J", (void*) SkPathGlue::init}, + {"nInit","(J)J", (void*) SkPathGlue::init_Path}, + {"nFinalize", "(J)V", (void*) SkPathGlue::finalize}, + {"nSet","(JJ)V", (void*) SkPathGlue::set}, + {"nComputeBounds","(JLandroid/graphics/RectF;)V", (void*) SkPathGlue::computeBounds}, + {"nIncReserve","(JI)V", (void*) SkPathGlue::incReserve}, + {"nMoveTo","(JFF)V", (void*) SkPathGlue::moveTo__FF}, + {"nRMoveTo","(JFF)V", (void*) SkPathGlue::rMoveTo}, + {"nLineTo","(JFF)V", (void*) SkPathGlue::lineTo__FF}, + {"nRLineTo","(JFF)V", (void*) SkPathGlue::rLineTo}, + {"nQuadTo","(JFFFF)V", (void*) SkPathGlue::quadTo__FFFF}, + {"nRQuadTo","(JFFFF)V", (void*) SkPathGlue::rQuadTo}, + {"nCubicTo","(JFFFFFF)V", (void*) SkPathGlue::cubicTo__FFFFFF}, + {"nRCubicTo","(JFFFFFF)V", (void*) SkPathGlue::rCubicTo}, + {"nArcTo","(JFFFFFFZ)V", (void*) SkPathGlue::arcTo}, + {"nClose","(J)V", (void*) SkPathGlue::close}, + {"nAddRect","(JFFFFI)V", (void*) SkPathGlue::addRect}, + {"nAddOval","(JFFFFI)V", (void*) SkPathGlue::addOval}, + {"nAddCircle","(JFFFI)V", (void*) SkPathGlue::addCircle}, + {"nAddArc","(JFFFFFF)V", (void*) SkPathGlue::addArc}, + {"nAddRoundRect","(JFFFFFFI)V", (void*) SkPathGlue::addRoundRectXY}, + {"nAddRoundRect","(JFFFF[FI)V", (void*) SkPathGlue::addRoundRect8}, + {"nAddPath","(JJFF)V", (void*) SkPathGlue::addPath__PathFF}, + {"nAddPath","(JJ)V", (void*) SkPathGlue::addPath__Path}, + {"nAddPath","(JJJ)V", (void*) SkPathGlue::addPath__PathMatrix}, + {"nOffset","(JFF)V", (void*) SkPathGlue::offset__FF}, + {"nSetLastPoint","(JFF)V", (void*) SkPathGlue::setLastPoint}, + {"nTransform","(JJJ)V", (void*) SkPathGlue::transform__MatrixPath}, + {"nTransform","(JJ)V", (void*) SkPathGlue::transform__Matrix}, + {"nOp","(JJIJ)Z", (void*) SkPathGlue::op}, + {"nApproximate", "(JF)[F", (void*) SkPathGlue::approximate}, + + // ------- @FastNative below here ---------------------- + {"nIsRect","(JLandroid/graphics/RectF;)Z", (void*) SkPathGlue::isRect}, + + // ------- @CriticalNative below here ------------------ + {"nReset","(J)V", (void*) SkPathGlue::reset}, + {"nRewind","(J)V", (void*) SkPathGlue::rewind}, + {"nIsEmpty","(J)Z", (void*) SkPathGlue::isEmpty}, + {"nIsConvex","(J)Z", (void*) SkPathGlue::isConvex}, + {"nGetFillType","(J)I", (void*) SkPathGlue::getFillType}, + {"nSetFillType","(JI)V", (void*) SkPathGlue::setFillType}, }; int register_android_graphics_Path(JNIEnv* env) { diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java index aa81b9196fe1..3e59f34f6bc7 100644 --- a/graphics/java/android/graphics/Outline.java +++ b/graphics/java/android/graphics/Outline.java @@ -58,8 +58,12 @@ public final class Outline { @Mode public int mMode = MODE_EMPTY; - /** @hide */ - public final Path mPath = new Path(); + /** + * Only guaranteed to be non-null when mode == MODE_CONVEX_PATH + * + * @hide + */ + public Path mPath; /** @hide */ public final Rect mRect = new Rect(); @@ -87,8 +91,11 @@ public final class Outline { * @see #isEmpty() */ public void setEmpty() { + if (mPath != null) { + // rewind here to avoid thrashing the allocations, but could alternately clear ref + mPath.rewind(); + } mMode = MODE_EMPTY; - mPath.rewind(); mRect.setEmpty(); mRadius = RADIUS_UNDEFINED; } @@ -148,7 +155,12 @@ public final class Outline { */ public void set(@NonNull Outline src) { mMode = src.mMode; - mPath.set(src.mPath); + if (src.mMode == MODE_CONVEX_PATH) { + if (mPath == null) { + mPath = new Path(); + } + mPath.set(src.mPath); + } mRect.set(src.mRect); mRadius = src.mRadius; mAlpha = src.mAlpha; @@ -180,10 +192,13 @@ public final class Outline { return; } + if (mMode == MODE_CONVEX_PATH) { + // rewind here to avoid thrashing the allocations, but could alternately clear ref + mPath.rewind(); + } mMode = MODE_ROUND_RECT; mRect.set(left, top, right, bottom); mRadius = radius; - mPath.rewind(); } /** @@ -236,8 +251,13 @@ public final class Outline { return; } + if (mPath == null) { + mPath = new Path(); + } else { + mPath.rewind(); + } + mMode = MODE_CONVEX_PATH; - mPath.rewind(); mPath.addOval(left, top, right, bottom, Path.Direction.CW); mRect.setEmpty(); mRadius = RADIUS_UNDEFINED; @@ -264,6 +284,10 @@ public final class Outline { throw new IllegalArgumentException("path must be convex"); } + if (mPath == null) { + mPath = new Path(); + } + mMode = MODE_CONVEX_PATH; mPath.set(convexPath); mRect.setEmpty(); diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java index 4ed2581f2b32..363137321f5f 100644 --- a/graphics/java/android/graphics/Path.java +++ b/graphics/java/android/graphics/Path.java @@ -19,6 +19,9 @@ package android.graphics; import android.annotation.NonNull; import android.annotation.Nullable; +import dalvik.annotation.optimization.CriticalNative; +import dalvik.annotation.optimization.FastNative; + /** * The Path class encapsulates compound (multiple contour) geometric paths * consisting of straight line segments, quadratic curves, and cubic curves. @@ -46,7 +49,7 @@ public class Path { * Create an empty path */ public Path() { - mNativePath = init1(); + mNativePath = nInit(); } /** @@ -63,7 +66,7 @@ public class Path { rects = new Region(src.rects); } } - mNativePath = init2(valNative); + mNativePath = nInit(valNative); } /** @@ -77,7 +80,7 @@ public class Path { // We promised not to change this, so preserve it around the native // call, which does now reset fill type. final FillType fillType = getFillType(); - native_reset(mNativePath); + nReset(mNativePath); setFillType(fillType); } @@ -89,7 +92,7 @@ public class Path { isSimplePath = true; mLastDirection = null; if (rects != null) rects.setEmpty(); - native_rewind(mNativePath); + nRewind(mNativePath); } /** Replace the contents of this with the contents of src. @@ -99,7 +102,7 @@ public class Path { return; } isSimplePath = src.isSimplePath; - native_set(mNativePath, src.mNativePath); + nSet(mNativePath, src.mNativePath); if (!isSimplePath) { return; } @@ -174,7 +177,7 @@ public class Path { * @see #op(Path, android.graphics.Path.Op) */ public boolean op(Path path1, Path path2, Op op) { - if (native_op(path1.mNativePath, path2.mNativePath, op.ordinal(), this.mNativePath)) { + if (nOp(path1.mNativePath, path2.mNativePath, op.ordinal(), this.mNativePath)) { isSimplePath = false; rects = null; return true; @@ -194,7 +197,7 @@ public class Path { * @return True if the path is convex. */ public boolean isConvex() { - return native_isConvex(mNativePath); + return nIsConvex(mNativePath); } /** @@ -243,7 +246,7 @@ public class Path { * @return the path's fill type */ public FillType getFillType() { - return sFillTypeArray[native_getFillType(mNativePath)]; + return sFillTypeArray[nGetFillType(mNativePath)]; } /** @@ -252,7 +255,7 @@ public class Path { * @param ft The new fill type for this path */ public void setFillType(FillType ft) { - native_setFillType(mNativePath, ft.nativeInt); + nSetFillType(mNativePath, ft.nativeInt); } /** @@ -261,7 +264,7 @@ public class Path { * @return true if the filltype is one of the INVERSE variants */ public boolean isInverseFillType() { - final int ft = native_getFillType(mNativePath); + final int ft = nGetFillType(mNativePath); return (ft & FillType.INVERSE_WINDING.nativeInt) != 0; } @@ -269,9 +272,9 @@ public class Path { * Toggles the INVERSE state of the filltype */ public void toggleInverseFillType() { - int ft = native_getFillType(mNativePath); + int ft = nGetFillType(mNativePath); ft ^= FillType.INVERSE_WINDING.nativeInt; - native_setFillType(mNativePath, ft); + nSetFillType(mNativePath, ft); } /** @@ -280,7 +283,7 @@ public class Path { * @return true if the path is empty (contains no lines or curves) */ public boolean isEmpty() { - return native_isEmpty(mNativePath); + return nIsEmpty(mNativePath); } /** @@ -293,7 +296,7 @@ public class Path { * @return true if the path specifies a rectangle */ public boolean isRect(RectF rect) { - return native_isRect(mNativePath, rect); + return nIsRect(mNativePath, rect); } /** @@ -306,7 +309,7 @@ public class Path { */ @SuppressWarnings({"UnusedDeclaration"}) public void computeBounds(RectF bounds, boolean exact) { - native_computeBounds(mNativePath, bounds); + nComputeBounds(mNativePath, bounds); } /** @@ -317,7 +320,7 @@ public class Path { * path */ public void incReserve(int extraPtCount) { - native_incReserve(mNativePath, extraPtCount); + nIncReserve(mNativePath, extraPtCount); } /** @@ -327,7 +330,7 @@ public class Path { * @param y The y-coordinate of the start of a new contour */ public void moveTo(float x, float y) { - native_moveTo(mNativePath, x, y); + nMoveTo(mNativePath, x, y); } /** @@ -341,7 +344,7 @@ public class Path { * previous contour, to specify the start of a new contour */ public void rMoveTo(float dx, float dy) { - native_rMoveTo(mNativePath, dx, dy); + nRMoveTo(mNativePath, dx, dy); } /** @@ -354,7 +357,7 @@ public class Path { */ public void lineTo(float x, float y) { isSimplePath = false; - native_lineTo(mNativePath, x, y); + nLineTo(mNativePath, x, y); } /** @@ -369,7 +372,7 @@ public class Path { */ public void rLineTo(float dx, float dy) { isSimplePath = false; - native_rLineTo(mNativePath, dx, dy); + nRLineTo(mNativePath, dx, dy); } /** @@ -384,7 +387,7 @@ public class Path { */ public void quadTo(float x1, float y1, float x2, float y2) { isSimplePath = false; - native_quadTo(mNativePath, x1, y1, x2, y2); + nQuadTo(mNativePath, x1, y1, x2, y2); } /** @@ -403,7 +406,7 @@ public class Path { */ public void rQuadTo(float dx1, float dy1, float dx2, float dy2) { isSimplePath = false; - native_rQuadTo(mNativePath, dx1, dy1, dx2, dy2); + nRQuadTo(mNativePath, dx1, dy1, dx2, dy2); } /** @@ -421,7 +424,7 @@ public class Path { public void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3) { isSimplePath = false; - native_cubicTo(mNativePath, x1, y1, x2, y2, x3, y3); + nCubicTo(mNativePath, x1, y1, x2, y2, x3, y3); } /** @@ -432,7 +435,7 @@ public class Path { public void rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3) { isSimplePath = false; - native_rCubicTo(mNativePath, x1, y1, x2, y2, x3, y3); + nRCubicTo(mNativePath, x1, y1, x2, y2, x3, y3); } /** @@ -483,7 +486,7 @@ public class Path { public void arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo) { isSimplePath = false; - native_arcTo(mNativePath, left, top, right, bottom, startAngle, sweepAngle, forceMoveTo); + nArcTo(mNativePath, left, top, right, bottom, startAngle, sweepAngle, forceMoveTo); } /** @@ -492,7 +495,7 @@ public class Path { */ public void close() { isSimplePath = false; - native_close(mNativePath); + nClose(mNativePath); } /** @@ -544,7 +547,7 @@ public class Path { */ public void addRect(float left, float top, float right, float bottom, Direction dir) { detectSimplePath(left, top, right, bottom, dir); - native_addRect(mNativePath, left, top, right, bottom, dir.nativeInt); + nAddRect(mNativePath, left, top, right, bottom, dir.nativeInt); } /** @@ -564,7 +567,7 @@ public class Path { */ public void addOval(float left, float top, float right, float bottom, Direction dir) { isSimplePath = false; - native_addOval(mNativePath, left, top, right, bottom, dir.nativeInt); + nAddOval(mNativePath, left, top, right, bottom, dir.nativeInt); } /** @@ -577,7 +580,7 @@ public class Path { */ public void addCircle(float x, float y, float radius, Direction dir) { isSimplePath = false; - native_addCircle(mNativePath, x, y, radius, dir.nativeInt); + nAddCircle(mNativePath, x, y, radius, dir.nativeInt); } /** @@ -600,7 +603,7 @@ public class Path { public void addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle) { isSimplePath = false; - native_addArc(mNativePath, left, top, right, bottom, startAngle, sweepAngle); + nAddArc(mNativePath, left, top, right, bottom, startAngle, sweepAngle); } /** @@ -625,7 +628,7 @@ public class Path { public void addRoundRect(float left, float top, float right, float bottom, float rx, float ry, Direction dir) { isSimplePath = false; - native_addRoundRect(mNativePath, left, top, right, bottom, rx, ry, dir.nativeInt); + nAddRoundRect(mNativePath, left, top, right, bottom, rx, ry, dir.nativeInt); } /** @@ -658,7 +661,7 @@ public class Path { throw new ArrayIndexOutOfBoundsException("radii[] needs 8 values"); } isSimplePath = false; - native_addRoundRect(mNativePath, left, top, right, bottom, radii, dir.nativeInt); + nAddRoundRect(mNativePath, left, top, right, bottom, radii, dir.nativeInt); } /** @@ -669,7 +672,7 @@ public class Path { */ public void addPath(Path src, float dx, float dy) { isSimplePath = false; - native_addPath(mNativePath, src.mNativePath, dx, dy); + nAddPath(mNativePath, src.mNativePath, dx, dy); } /** @@ -679,7 +682,7 @@ public class Path { */ public void addPath(Path src) { isSimplePath = false; - native_addPath(mNativePath, src.mNativePath); + nAddPath(mNativePath, src.mNativePath); } /** @@ -689,7 +692,7 @@ public class Path { */ public void addPath(Path src, Matrix matrix) { if (!src.isSimplePath) isSimplePath = false; - native_addPath(mNativePath, src.mNativePath, matrix.native_instance); + nAddPath(mNativePath, src.mNativePath, matrix.native_instance); } /** @@ -725,7 +728,7 @@ public class Path { } else { isSimplePath = false; } - native_offset(mNativePath, dx, dy); + nOffset(mNativePath, dx, dy); } /** @@ -736,7 +739,7 @@ public class Path { */ public void setLastPoint(float dx, float dy) { isSimplePath = false; - native_setLastPoint(mNativePath, dx, dy); + nSetLastPoint(mNativePath, dx, dy); } /** @@ -753,7 +756,7 @@ public class Path { dst.isSimplePath = false; dstNative = dst.mNativePath; } - native_transform(mNativePath, matrix.native_instance, dstNative); + nTransform(mNativePath, matrix.native_instance, dstNative); } /** @@ -763,12 +766,12 @@ public class Path { */ public void transform(Matrix matrix) { isSimplePath = false; - native_transform(mNativePath, matrix.native_instance); + nTransform(mNativePath, matrix.native_instance); } protected void finalize() throws Throwable { try { - finalizer(mNativePath); + nFinalize(mNativePath); mNativePath = 0; // Other finalizers can still call us. } finally { super.finalize(); @@ -803,59 +806,68 @@ public class Path { * @return An array of components for points approximating the Path. */ public float[] approximate(float acceptableError) { - return native_approximate(mNativePath, acceptableError); - } - - private static native long init1(); - private static native long init2(long nPath); - private static native void native_reset(long nPath); - private static native void native_rewind(long nPath); - private static native void native_set(long native_dst, long native_src); - private static native boolean native_isConvex(long nPath); - private static native int native_getFillType(long nPath); - private static native void native_setFillType(long nPath, int ft); - private static native boolean native_isEmpty(long nPath); - private static native boolean native_isRect(long nPath, RectF rect); - private static native void native_computeBounds(long nPath, RectF bounds); - private static native void native_incReserve(long nPath, int extraPtCount); - private static native void native_moveTo(long nPath, float x, float y); - private static native void native_rMoveTo(long nPath, float dx, float dy); - private static native void native_lineTo(long nPath, float x, float y); - private static native void native_rLineTo(long nPath, float dx, float dy); - private static native void native_quadTo(long nPath, float x1, float y1, - float x2, float y2); - private static native void native_rQuadTo(long nPath, float dx1, float dy1, - float dx2, float dy2); - private static native void native_cubicTo(long nPath, float x1, float y1, - float x2, float y2, float x3, float y3); - private static native void native_rCubicTo(long nPath, float x1, float y1, - float x2, float y2, float x3, float y3); - private static native void native_arcTo(long nPath, float left, float top, - float right, float bottom, float startAngle, - float sweepAngle, boolean forceMoveTo); - private static native void native_close(long nPath); - private static native void native_addRect(long nPath, float left, float top, - float right, float bottom, int dir); - private static native void native_addOval(long nPath, float left, float top, + return nApproximate(mNativePath, acceptableError); + } + + // ------------------ Regular JNI ------------------------ + + private static native long nInit(); + private static native long nInit(long nPath); + private static native void nFinalize(long nPath); + private static native void nSet(long native_dst, long nSrc); + private static native void nComputeBounds(long nPath, RectF bounds); + private static native void nIncReserve(long nPath, int extraPtCount); + private static native void nMoveTo(long nPath, float x, float y); + private static native void nRMoveTo(long nPath, float dx, float dy); + private static native void nLineTo(long nPath, float x, float y); + private static native void nRLineTo(long nPath, float dx, float dy); + private static native void nQuadTo(long nPath, float x1, float y1, float x2, float y2); + private static native void nRQuadTo(long nPath, float dx1, float dy1, float dx2, float dy2); + private static native void nCubicTo(long nPath, float x1, float y1, float x2, float y2, + float x3, float y3); + private static native void nRCubicTo(long nPath, float x1, float y1, float x2, float y2, + float x3, float y3); + private static native void nArcTo(long nPath, float left, float top, float right, float bottom, + float startAngle, float sweepAngle, boolean forceMoveTo); + private static native void nClose(long nPath); + private static native void nAddRect(long nPath, float left, float top, + float right, float bottom, int dir); + private static native void nAddOval(long nPath, float left, float top, float right, float bottom, int dir); - private static native void native_addCircle(long nPath, float x, float y, float radius, int dir); - private static native void native_addArc(long nPath, float left, float top, - float right, float bottom, - float startAngle, float sweepAngle); - private static native void native_addRoundRect(long nPath, float left, float top, - float right, float bottom, - float rx, float ry, int dir); - private static native void native_addRoundRect(long nPath, float left, float top, - float right, float bottom, - float[] radii, int dir); - private static native void native_addPath(long nPath, long src, float dx, float dy); - private static native void native_addPath(long nPath, long src); - private static native void native_addPath(long nPath, long src, long matrix); - private static native void native_offset(long nPath, float dx, float dy); - private static native void native_setLastPoint(long nPath, float dx, float dy); - private static native void native_transform(long nPath, long matrix, long dst_path); - private static native void native_transform(long nPath, long matrix); - private static native boolean native_op(long path1, long path2, int op, long result); - private static native void finalizer(long nPath); - private static native float[] native_approximate(long nPath, float error); + private static native void nAddCircle(long nPath, float x, float y, float radius, int dir); + private static native void nAddArc(long nPath, float left, float top, float right, float bottom, + float startAngle, float sweepAngle); + private static native void nAddRoundRect(long nPath, float left, float top, + float right, float bottom, float rx, float ry, int dir); + private static native void nAddRoundRect(long nPath, float left, float top, + float right, float bottom, float[] radii, int dir); + private static native void nAddPath(long nPath, long src, float dx, float dy); + private static native void nAddPath(long nPath, long src); + private static native void nAddPath(long nPath, long src, long matrix); + private static native void nOffset(long nPath, float dx, float dy); + private static native void nSetLastPoint(long nPath, float dx, float dy); + private static native void nTransform(long nPath, long matrix, long dst_path); + private static native void nTransform(long nPath, long matrix); + private static native boolean nOp(long path1, long path2, int op, long result); + private static native float[] nApproximate(long nPath, float error); + + // ------------------ Fast JNI ------------------------ + + @FastNative + private static native boolean nIsRect(long nPath, RectF rect); + + // ------------------ Critical JNI ------------------------ + + @CriticalNative + private static native void nReset(long nPath); + @CriticalNative + private static native void nRewind(long nPath); + @CriticalNative + private static native boolean nIsEmpty(long nPath); + @CriticalNative + private static native boolean nIsConvex(long nPath); + @CriticalNative + private static native int nGetFillType(long nPath); + @CriticalNative + private static native void nSetFillType(long nPath, int ft); } |