Merge "Convert Shader to NativeAllocationRegistry" into oc-dev

This commit is contained in:
John Reck
2017-05-23 16:43:37 +00:00
committed by Android (Google) Code Review
3 changed files with 30 additions and 25 deletions

View 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) { static void Shader_safeUnref(SkShader* shader) {
SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);
SkSafeUnref(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, static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jobject jbitmap,
@@ -284,7 +287,7 @@ static const JNINativeMethod gColorMethods[] = {
}; };
static const JNINativeMethod gShaderMethods[] = { static const JNINativeMethod gShaderMethods[] = {
{ "nativeSafeUnref", "(J)V", (void*)Shader_safeUnref }, { "nativeGetFinalizer", "()J", (void*)Shader_getNativeFinalizer },
}; };
static const JNINativeMethod gBitmapShaderMethods[] = { static const JNINativeMethod gBitmapShaderMethods[] = {

View File

@@ -76,8 +76,9 @@ public class ComposeShader extends Shader {
mShaderA.getNativeInstance(), mShaderB.getNativeInstance(), mPorterDuffMode); mShaderA.getNativeInstance(), mShaderB.getNativeInstance(), mPorterDuffMode);
} }
/** @hide */
@Override @Override
void verifyNativeInstance() { protected void verifyNativeInstance() {
if (mShaderA.getNativeInstance() != mNativeInstanceShaderA if (mShaderA.getNativeInstance() != mNativeInstanceShaderA
|| mShaderB.getNativeInstance() != mNativeInstanceShaderB) { || mShaderB.getNativeInstance() != mNativeInstanceShaderB) {
// Child shader native instance has been updated, // Child shader native instance has been updated,

View File

@@ -19,6 +19,8 @@ package android.graphics;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import libcore.util.NativeAllocationRegistry;
/** /**
* Shader is the based class for objects that return horizontal spans of colors * 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 * 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. * drawn with that paint will get its color(s) from the shader.
*/ */
public class 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. * @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. * is called - otherwise may be out of date with java setters/properties.
*/ */
private long mNativeInstance; private long mNativeInstance;
// Runnable to do immediate destruction
private Runnable mCleaner;
/** /**
* Current matrix - always set to null if local matrix is identity. * Current matrix - always set to null if local matrix is identity.
@@ -105,9 +115,11 @@ public class Shader {
return 0; return 0;
} }
void discardNativeInstance() { /** @hide */
protected final void discardNativeInstance() {
if (mNativeInstance != 0) { if (mNativeInstance != 0) {
nativeSafeUnref(mNativeInstance); mCleaner.run();
mCleaner = null;
mNativeInstance = 0; mNativeInstance = 0;
} }
} }
@@ -115,20 +127,9 @@ public class Shader {
/** /**
* Callback for subclasses to call {@link #discardNativeInstance()} if the most recently * Callback for subclasses to call {@link #discardNativeInstance()} if the most recently
* constructed native instance is no longer valid. * constructed native instance is no longer valid.
* @hide
*/ */
void verifyNativeInstance() { protected void verifyNativeInstance() {
}
@Override
protected void finalize() throws Throwable {
try {
if (mNativeInstance != 0) {
nativeSafeUnref(mNativeInstance);
}
mNativeInstance = -1;
} finally {
super.finalize();
}
} }
/** /**
@@ -150,20 +151,20 @@ public class Shader {
/** /**
* @hide * @hide
*/ */
public long getNativeInstance() { public final long getNativeInstance() {
if (mNativeInstance == -1) {
throw new IllegalStateException("attempting to use a finalized Shader");
}
// verify mNativeInstance is valid // verify mNativeInstance is valid
verifyNativeInstance(); verifyNativeInstance();
if (mNativeInstance == 0) { if (mNativeInstance == 0) {
mNativeInstance = createNativeInstance(mLocalMatrix == null mNativeInstance = createNativeInstance(mLocalMatrix == null
? 0 : mLocalMatrix.native_instance); ? 0 : mLocalMatrix.native_instance);
mCleaner = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
this, mNativeInstance);
} }
return mNativeInstance; return mNativeInstance;
} }
private static native void nativeSafeUnref(long nativeInstance); private static native long nativeGetFinalizer();
} }