OSDN Git Service

Convert Shader to NativeAllocationRegistry
authorJohn Reck <jreck@google.com>
Fri, 19 May 2017 17:55:20 +0000 (10:55 -0700)
committerJohn Reck <jreck@google.com>
Fri, 19 May 2017 17:55:20 +0000 (10:55 -0700)
Bug: 38258699
Test: manual
Change-Id: I1537dee3187ea0366f2c236f3e6825196d738a37

core/jni/android/graphics/Shader.cpp
graphics/java/android/graphics/ComposeShader.java
graphics/java/android/graphics/Shader.java

index 214d97c..5f803da 100644 (file)
@@ -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[] = {
index 0b1141a..70a5f53 100644 (file)
@@ -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,
index 8410ab2..13016ff 100644 (file)
@@ -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();
+
 }
+