Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 284045db authored by John Reck's avatar John Reck Committed by Android (Google) Code Review
Browse files

Merge "Convert Shader to NativeAllocationRegistry"

parents 2937245a 8bde0be1
Loading
Loading
Loading
Loading
+6 −3
Original line number Original line Diff line number Diff line
@@ -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[] = {
+2 −1
Original line number Original line Diff line number Diff line
@@ -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,
+22 −21
Original line number Original line Diff line number Diff line
@@ -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();

}
}