diff options
-rw-r--r-- | core/jni/android/graphics/Shader.cpp | 9 | ||||
-rw-r--r-- | graphics/java/android/graphics/ComposeShader.java | 3 | ||||
-rw-r--r-- | graphics/java/android/graphics/Shader.java | 43 |
3 files changed, 30 insertions, 25 deletions
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp index 214d97c213e4..5f803da4b23f 100644 --- a/core/jni/android/graphics/Shader.cpp +++ b/core/jni/android/graphics/Shader.cpp @@ -50,11 +50,14 @@ static jint Color_HSVToColor(JNIEnv* env, jobject, jint alpha, jfloatArray hsvAr /////////////////////////////////////////////////////////////////////////////////////////////// -static void Shader_safeUnref(JNIEnv* env, jobject o, jlong shaderHandle) { - SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle); +static void Shader_safeUnref(SkShader* shader) { SkSafeUnref(shader); } +static jlong Shader_getNativeFinalizer(JNIEnv*, jobject) { + return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Shader_safeUnref)); +} + /////////////////////////////////////////////////////////////////////////////////////////////// static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jobject jbitmap, @@ -284,7 +287,7 @@ static const JNINativeMethod gColorMethods[] = { }; static const JNINativeMethod gShaderMethods[] = { - { "nativeSafeUnref", "(J)V", (void*)Shader_safeUnref }, + { "nativeGetFinalizer", "()J", (void*)Shader_getNativeFinalizer }, }; static const JNINativeMethod gBitmapShaderMethods[] = { diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java index 0b1141a0e505..70a5f53ae1e0 100644 --- a/graphics/java/android/graphics/ComposeShader.java +++ b/graphics/java/android/graphics/ComposeShader.java @@ -76,8 +76,9 @@ public class ComposeShader extends Shader { mShaderA.getNativeInstance(), mShaderB.getNativeInstance(), mPorterDuffMode); } + /** @hide */ @Override - void verifyNativeInstance() { + protected void verifyNativeInstance() { if (mShaderA.getNativeInstance() != mNativeInstanceShaderA || mShaderB.getNativeInstance() != mNativeInstanceShaderB) { // Child shader native instance has been updated, diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java index 8410ab2a1e02..13016ff096aa 100644 --- a/graphics/java/android/graphics/Shader.java +++ b/graphics/java/android/graphics/Shader.java @@ -19,6 +19,8 @@ package android.graphics; import android.annotation.NonNull; import android.annotation.Nullable; +import libcore.util.NativeAllocationRegistry; + /** * Shader is the based class for objects that return horizontal spans of colors * during drawing. A subclass of Shader is installed in a Paint calling @@ -26,6 +28,12 @@ import android.annotation.Nullable; * drawn with that paint will get its color(s) from the shader. */ public class Shader { + + private static class NoImagePreloadHolder { + public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry( + Shader.class.getClassLoader(), nativeGetFinalizer(), 50); + } + /** * @deprecated Use subclass constructors directly instead. */ @@ -37,6 +45,8 @@ public class Shader { * is called - otherwise may be out of date with java setters/properties. */ private long mNativeInstance; + // Runnable to do immediate destruction + private Runnable mCleaner; /** * Current matrix - always set to null if local matrix is identity. @@ -105,9 +115,11 @@ public class Shader { return 0; } - void discardNativeInstance() { + /** @hide */ + protected final void discardNativeInstance() { if (mNativeInstance != 0) { - nativeSafeUnref(mNativeInstance); + mCleaner.run(); + mCleaner = null; mNativeInstance = 0; } } @@ -115,20 +127,9 @@ public class Shader { /** * Callback for subclasses to call {@link #discardNativeInstance()} if the most recently * constructed native instance is no longer valid. + * @hide */ - void verifyNativeInstance() { - } - - @Override - protected void finalize() throws Throwable { - try { - if (mNativeInstance != 0) { - nativeSafeUnref(mNativeInstance); - } - mNativeInstance = -1; - } finally { - super.finalize(); - } + protected void verifyNativeInstance() { } /** @@ -150,20 +151,20 @@ public class Shader { /** * @hide */ - public long getNativeInstance() { - if (mNativeInstance == -1) { - throw new IllegalStateException("attempting to use a finalized Shader"); - } - + public final long getNativeInstance() { // verify mNativeInstance is valid verifyNativeInstance(); if (mNativeInstance == 0) { mNativeInstance = createNativeInstance(mLocalMatrix == null ? 0 : mLocalMatrix.native_instance); + mCleaner = NoImagePreloadHolder.sRegistry.registerNativeAllocation( + this, mNativeInstance); } return mNativeInstance; } - private static native void nativeSafeUnref(long nativeInstance); + private static native long nativeGetFinalizer(); + } + |