From bfa0b29883d56edfc2ec217962290d3c94f9fc2a Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Thu, 19 Jan 2017 19:12:36 -0800 Subject: [PATCH] Use @CriticalNative in Canvas Bug: 33460152 Test: ViewShowHidePerfTests Switches non-drawing @FastNative methods to @CriticalNative, except where out arguments prevent it. Performance in ViewShowHidePerfTests not significantly impacted. Change-Id: I3edc963accb4f87f73d175c7b2534868602a7db3 --- core/jni/android_graphics_Canvas.cpp | 78 ++++++------ graphics/java/android/graphics/Canvas.java | 136 ++++++++++----------- 2 files changed, 100 insertions(+), 114 deletions(-) diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp index 9ce5670f904c4..c49287ccddb29 100644 --- a/core/jni/android_graphics_Canvas.cpp +++ b/core/jni/android_graphics_Canvas.cpp @@ -63,97 +63,87 @@ static void setBitmap(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap) get_canvas(canvasHandle)->setBitmap(bitmap); } -static jboolean isOpaque(JNIEnv*, jobject, jlong canvasHandle) { +static jboolean isOpaque(jlong canvasHandle) { return get_canvas(canvasHandle)->isOpaque() ? JNI_TRUE : JNI_FALSE; } -static jint getWidth(JNIEnv*, jobject, jlong canvasHandle) { +static jint getWidth(jlong canvasHandle) { return static_cast(get_canvas(canvasHandle)->width()); } -static jint getHeight(JNIEnv*, jobject, jlong canvasHandle) { +static jint getHeight(jlong canvasHandle) { return static_cast(get_canvas(canvasHandle)->height()); } -static void setHighContrastText(JNIEnv*, jobject, jlong canvasHandle, jboolean highContrastText) { +static void setHighContrastText(jlong canvasHandle, jboolean highContrastText) { Canvas* canvas = get_canvas(canvasHandle); canvas->setHighContrastText(highContrastText); } -static jint getSaveCount(JNIEnv*, jobject, jlong canvasHandle) { - return static_cast(get_canvas(canvasHandle)->getSaveCount()); -} - -static jint save(JNIEnv*, jobject, jlong canvasHandle, jint flagsHandle) { +static jint save(jlong canvasHandle, jint flagsHandle) { SaveFlags::Flags flags = static_cast(flagsHandle); return static_cast(get_canvas(canvasHandle)->save(flags)); } -static jint saveLayer(JNIEnv* env, jobject, jlong canvasHandle, jfloat l, jfloat t, +static jint saveLayer(jlong canvasHandle, jfloat l, jfloat t, jfloat r, jfloat b, jlong paintHandle, jint flagsHandle) { Paint* paint = reinterpret_cast(paintHandle); SaveFlags::Flags flags = static_cast(flagsHandle); return static_cast(get_canvas(canvasHandle)->saveLayer(l, t, r, b, paint, flags)); } -static jint saveLayerAlpha(JNIEnv* env, jobject, jlong canvasHandle, jfloat l, jfloat t, +static jint saveLayerAlpha(jlong canvasHandle, jfloat l, jfloat t, jfloat r, jfloat b, jint alpha, jint flagsHandle) { SaveFlags::Flags flags = static_cast(flagsHandle); return static_cast(get_canvas(canvasHandle)->saveLayerAlpha(l, t, r, b, alpha, flags)); } -static void restore(JNIEnv* env, jobject, jlong canvasHandle, jboolean throwOnUnderflow) { +static bool restore(jlong canvasHandle) { Canvas* canvas = get_canvas(canvasHandle); - if (canvas->getSaveCount() <= 1) { // cannot restore anymore - if (throwOnUnderflow) { - doThrowISE(env, "Underflow in restore - more restores than saves"); - } - return; // compat behavior - return without throwing + if (canvas->getSaveCount() <= 1) { + return false; // cannot restore anymore } canvas->restore(); + return true; // success } -static void restoreToCount(JNIEnv* env, jobject, jlong canvasHandle, jint restoreCount, - jboolean throwOnUnderflow) { +static void restoreToCount(jlong canvasHandle, jint saveCount) { Canvas* canvas = get_canvas(canvasHandle); - if (restoreCount < 1 || restoreCount > canvas->getSaveCount()) { - if (throwOnUnderflow) { - doThrowIAE(env, "Underflow in restoreToCount - more restores than saves"); - return; - } - restoreCount = 1; // compat behavior - restore as far as possible - } - canvas->restoreToCount(restoreCount); + canvas->restoreToCount(saveCount); } -static void getCTM(JNIEnv* env, jobject, jlong canvasHandle, jlong matrixHandle) { +static jint getSaveCount(jlong canvasHandle) { + return static_cast(get_canvas(canvasHandle)->getSaveCount()); +} + +static void getMatrix(jlong canvasHandle, jlong matrixHandle) { SkMatrix* matrix = reinterpret_cast(matrixHandle); get_canvas(canvasHandle)->getMatrix(matrix); } -static void setMatrix(JNIEnv* env, jobject, jlong canvasHandle, jlong matrixHandle) { +static void setMatrix(jlong canvasHandle, jlong matrixHandle) { const SkMatrix* matrix = reinterpret_cast(matrixHandle); get_canvas(canvasHandle)->setMatrix(matrix ? *matrix : SkMatrix::I()); } -static void concat(JNIEnv* env, jobject, jlong canvasHandle, jlong matrixHandle) { +static void concat(jlong canvasHandle, jlong matrixHandle) { const SkMatrix* matrix = reinterpret_cast(matrixHandle); get_canvas(canvasHandle)->concat(*matrix); } -static void rotate(JNIEnv*, jobject, jlong canvasHandle, jfloat degrees) { +static void rotate(jlong canvasHandle, jfloat degrees) { get_canvas(canvasHandle)->rotate(degrees); } -static void scale(JNIEnv*, jobject, jlong canvasHandle, jfloat sx, jfloat sy) { +static void scale(jlong canvasHandle, jfloat sx, jfloat sy) { get_canvas(canvasHandle)->scale(sx, sy); } -static void skew(JNIEnv*, jobject, jlong canvasHandle, jfloat sx, jfloat sy) { +static void skew(jlong canvasHandle, jfloat sx, jfloat sy) { get_canvas(canvasHandle)->skew(sx, sy); } -static void translate(JNIEnv*, jobject, jlong canvasHandle, jfloat dx, jfloat dy) { +static void translate(jlong canvasHandle, jfloat dx, jfloat dy) { get_canvas(canvasHandle)->translate(dx, dy); } @@ -171,13 +161,13 @@ static jboolean getClipBounds(JNIEnv* env, jobject, jlong canvasHandle, jobject return result ? JNI_TRUE : JNI_FALSE; } -static jboolean quickRejectRect(JNIEnv* env, jobject, jlong canvasHandle, +static jboolean quickRejectRect(jlong canvasHandle, jfloat left, jfloat top, jfloat right, jfloat bottom) { bool result = get_canvas(canvasHandle)->quickRejectRect(left, top, right, bottom); return result ? JNI_TRUE : JNI_FALSE; } -static jboolean quickRejectPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle) { +static jboolean quickRejectPath(jlong canvasHandle, jlong pathHandle) { SkPath* path = reinterpret_cast(pathHandle); bool result = get_canvas(canvasHandle)->quickRejectPath(*path); return result ? JNI_TRUE : JNI_FALSE; @@ -205,14 +195,14 @@ static SkClipOp opHandleToClipOp(jint opHandle) { return static_cast(rgnOp); } -static jboolean clipRect(JNIEnv*, jobject, jlong canvasHandle, jfloat l, jfloat t, +static jboolean clipRect(jlong canvasHandle, jfloat l, jfloat t, jfloat r, jfloat b, jint opHandle) { bool nonEmptyClip = get_canvas(canvasHandle)->clipRect(l, t, r, b, opHandleToClipOp(opHandle)); return nonEmptyClip ? JNI_TRUE : JNI_FALSE; } -static jboolean clipPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle, +static jboolean clipPath(jlong canvasHandle, jlong pathHandle, jint opHandle) { SkPath* path = reinterpret_cast(pathHandle); bool nonEmptyClip = get_canvas(canvasHandle)->clipPath(path, opHandleToClipOp(opHandle)); @@ -565,7 +555,7 @@ static void drawTextOnPathString(JNIEnv* env, jobject, jlong canvasHandle, jstri env->ReleaseStringChars(text, jchars); } -static void setDrawFilter(JNIEnv* env, jobject, jlong canvasHandle, jlong filterHandle) { +static void setDrawFilter(jlong canvasHandle, jlong filterHandle) { get_canvas(canvasHandle)->setDrawFilter(reinterpret_cast(filterHandle)); } @@ -587,6 +577,9 @@ static const JNINativeMethod gMethods[] = { // ------------ @FastNative ---------------- {"nSetBitmap", "(JLandroid/graphics/Bitmap;)V", (void*) CanvasJNI::setBitmap}, + {"nGetClipBounds","(JLandroid/graphics/Rect;)Z", (void*) CanvasJNI::getClipBounds}, + + // ------------ @CriticalNative ---------------- {"nIsOpaque","(J)Z", (void*) CanvasJNI::isOpaque}, {"nGetWidth","(J)I", (void*) CanvasJNI::getWidth}, {"nGetHeight","(J)I", (void*) CanvasJNI::getHeight}, @@ -595,16 +588,15 @@ static const JNINativeMethod gMethods[] = { {"nSaveLayer","(JFFFFJI)I", (void*) CanvasJNI::saveLayer}, {"nSaveLayerAlpha","(JFFFFII)I", (void*) CanvasJNI::saveLayerAlpha}, {"nGetSaveCount","(J)I", (void*) CanvasJNI::getSaveCount}, - {"nRestore","(JZ)V", (void*) CanvasJNI::restore}, - {"nRestoreToCount","(JIZ)V", (void*) CanvasJNI::restoreToCount}, - {"nGetCTM", "(JJ)V", (void*)CanvasJNI::getCTM}, + {"nRestore","(J)Z", (void*) CanvasJNI::restore}, + {"nRestoreToCount","(JI)V", (void*) CanvasJNI::restoreToCount}, + {"nGetMatrix", "(JJ)V", (void*)CanvasJNI::getMatrix}, {"nSetMatrix","(JJ)V", (void*) CanvasJNI::setMatrix}, {"nConcat","(JJ)V", (void*) CanvasJNI::concat}, {"nRotate","(JF)V", (void*) CanvasJNI::rotate}, {"nScale","(JFF)V", (void*) CanvasJNI::scale}, {"nSkew","(JFF)V", (void*) CanvasJNI::skew}, {"nTranslate","(JFF)V", (void*) CanvasJNI::translate}, - {"nGetClipBounds","(JLandroid/graphics/Rect;)Z", (void*) CanvasJNI::getClipBounds}, {"nQuickReject","(JJ)Z", (void*) CanvasJNI::quickRejectPath}, {"nQuickReject","(JFFFF)Z", (void*)CanvasJNI::quickRejectRect}, {"nClipRect","(JFFFFI)Z", (void*) CanvasJNI::clipRect}, diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index cc5cc7bd8cf85..85723456399a0 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -21,11 +21,8 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; -import android.text.GraphicsOperations; -import android.text.SpannableString; -import android.text.SpannedString; -import android.text.TextUtils; +import dalvik.annotation.optimization.CriticalNative; import dalvik.annotation.optimization.FastNative; import libcore.util.NativeAllocationRegistry; @@ -501,8 +498,10 @@ public class Canvas extends BaseCanvas { * an error to call restore() more times than save() was called. */ public void restore() { - boolean throwOnUnderflow = !sCompatibilityRestore || !isHardwareAccelerated(); - nRestore(mNativeCanvasWrapper, throwOnUnderflow); + if (!nRestore(mNativeCanvasWrapper) + && (!sCompatibilityRestore || !isHardwareAccelerated())) { + throw new IllegalStateException("Underflow in restore - more restores than saves"); + } } /** @@ -527,8 +526,16 @@ public class Canvas extends BaseCanvas { * @param saveCount The save level to restore to. */ public void restoreToCount(int saveCount) { - boolean throwOnUnderflow = !sCompatibilityRestore || !isHardwareAccelerated(); - nRestoreToCount(mNativeCanvasWrapper, saveCount, throwOnUnderflow); + if (saveCount < 1) { + if (!sCompatibilityRestore || !isHardwareAccelerated()) { + // do nothing and throw without restoring + throw new IllegalArgumentException( + "Underflow in restoreToCount - more restores than saves"); + } + // compat behavior - restore as far as possible + saveCount = 1; + } + nRestoreToCount(mNativeCanvasWrapper, saveCount); } /** @@ -643,7 +650,7 @@ public class Canvas extends BaseCanvas { */ @Deprecated public void getMatrix(@NonNull Matrix ctm) { - nGetCTM(mNativeCanvasWrapper, ctm.native_instance); + nGetMatrix(mNativeCanvasWrapper, ctm.native_instance); } /** @@ -1059,79 +1066,66 @@ public class Canvas extends BaseCanvas { // ---------------- @FastNative ------------------- @FastNative - private static native void nSetBitmap(long canvasHandle, - Bitmap bitmap); + private static native void nSetBitmap(long canvasHandle, Bitmap bitmap); + @FastNative + private static native boolean nGetClipBounds(long nativeCanvas, Rect bounds); + + // ---------------- @CriticalNative ------------------- + + @CriticalNative private static native boolean nIsOpaque(long canvasHandle); - @FastNative + @CriticalNative private static native void nSetHighContrastText(long renderer, boolean highContrastText); - @FastNative + @CriticalNative private static native int nGetWidth(long canvasHandle); - @FastNative + @CriticalNative private static native int nGetHeight(long canvasHandle); - @FastNative + @CriticalNative private static native int nSave(long canvasHandle, int saveFlags); - @FastNative - private static native int nSaveLayer(long nativeCanvas, float l, - float t, float r, float b, - long nativePaint, - int layerFlags); - @FastNative - private static native int nSaveLayerAlpha(long nativeCanvas, float l, - float t, float r, float b, - int alpha, int layerFlags); - @FastNative - private static native void nRestore(long canvasHandle, boolean tolerateUnderflow); - @FastNative - private static native void nRestoreToCount(long canvasHandle, - int saveCount, - boolean tolerateUnderflow); - @FastNative + @CriticalNative + private static native int nSaveLayer(long nativeCanvas, float l, float t, float r, float b, + long nativePaint, int layerFlags); + @CriticalNative + private static native int nSaveLayerAlpha(long nativeCanvas, float l, float t, float r, float b, + int alpha, int layerFlags); + @CriticalNative + private static native boolean nRestore(long canvasHandle); + @CriticalNative + private static native void nRestoreToCount(long canvasHandle, int saveCount); + @CriticalNative private static native int nGetSaveCount(long canvasHandle); - @FastNative - private static native void nTranslate(long canvasHandle, - float dx, float dy); - @FastNative - private static native void nScale(long canvasHandle, - float sx, float sy); - @FastNative + @CriticalNative + private static native void nTranslate(long canvasHandle, float dx, float dy); + @CriticalNative + private static native void nScale(long canvasHandle, float sx, float sy); + @CriticalNative private static native void nRotate(long canvasHandle, float degrees); - @FastNative - private static native void nSkew(long canvasHandle, - float sx, float sy); - @FastNative - private static native void nConcat(long nativeCanvas, - long nativeMatrix); - @FastNative - private static native void nSetMatrix(long nativeCanvas, - long nativeMatrix); - @FastNative + @CriticalNative + private static native void nSkew(long canvasHandle, float sx, float sy); + @CriticalNative + private static native void nConcat(long nativeCanvas, long nativeMatrix); + @CriticalNative + private static native void nSetMatrix(long nativeCanvas, long nativeMatrix); + @CriticalNative private static native boolean nClipRect(long nativeCanvas, - float left, float top, - float right, float bottom, - int regionOp); - @FastNative - private static native boolean nClipPath(long nativeCanvas, - long nativePath, - int regionOp); - @FastNative - private static native void nSetDrawFilter(long nativeCanvas, - long nativeFilter); - @FastNative - private static native boolean nGetClipBounds(long nativeCanvas, - Rect bounds); - @FastNative - private static native void nGetCTM(long nativeCanvas, - long nativeMatrix); - @FastNative - private static native boolean nQuickReject(long nativeCanvas, - long nativePath); - @FastNative - private static native boolean nQuickReject(long nativeCanvas, - float left, float top, - float right, float bottom); + float left, float top, float right, float bottom, int regionOp); + @CriticalNative + private static native boolean nClipPath(long nativeCanvas, long nativePath, int regionOp); + @CriticalNative + private static native void nSetDrawFilter(long nativeCanvas, long nativeFilter); + @CriticalNative + private static native void nGetMatrix(long nativeCanvas, long nativeMatrix); + @CriticalNative + private static native boolean nQuickReject(long nativeCanvas, long nativePath); + @CriticalNative + private static native boolean nQuickReject(long nativeCanvas, float left, float top, + float right, float bottom); + + + // ---------------- Draw Methods ------------------- /** *