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

Commit f75e4ca3 authored by Jason Sams's avatar Jason Sams Committed by Gerrit Code Review
Browse files

Merge "Make it harder to leak contexts"

parents 89da4ca6 e16da12b
Loading
Loading
Loading
Loading
+103 −14
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.util.Log;
import android.view.Surface;
import android.os.SystemProperties;
import android.os.Trace;
import java.util.ArrayList;

/**
 * This class provides access to a RenderScript context, which controls RenderScript
@@ -49,6 +50,12 @@ public class RenderScript {
    @SuppressWarnings({"UnusedDeclaration", "deprecation"})
    static final boolean LOG_ENABLED = false;

    static private ArrayList<RenderScript> mProcessContextList = new ArrayList<RenderScript>();
    private boolean mIsProcessContext = false;
    private int mContextFlags = 0;
    private int mContextSdkVersion = 0;


    private Context mApplicationContext;

    /*
@@ -1312,13 +1319,6 @@ public class RenderScript {
        return mApplicationContext;
    }

    /**
     * @hide
     */
    public static RenderScript create(Context ctx, int sdkVersion) {
        return create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE);
    }

    /**
     * Create a RenderScript context.
     *
@@ -1326,7 +1326,7 @@ public class RenderScript {
     * @param ctx The context.
     * @return RenderScript
     */
    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) {
    private static RenderScript internalCreate(Context ctx, int sdkVersion, ContextType ct, int flags) {
        if (!sInitialized) {
            Log.e(LOG_TAG, "RenderScript.create() called when disabled; someone is likely to crash");
            return null;
@@ -1341,6 +1341,8 @@ public class RenderScript {
        rs.mDev = rs.nDeviceCreate();
        rs.mContext = rs.nContextCreate(rs.mDev, flags, sdkVersion, ct.mID);
        rs.mContextType = ct;
        rs.mContextFlags = flags;
        rs.mContextSdkVersion = sdkVersion;
        if (rs.mContext == 0) {
            throw new RSDriverException("Failed to create RS context.");
        }
@@ -1350,7 +1352,9 @@ public class RenderScript {
    }

    /**
     * Create a RenderScript context.
     * calls create(cts, ContextType.NORMAL, CREATE_FLAG_NONE)
     *
     * See documentation for @create for details
     *
     * @param ctx The context.
     * @return RenderScript
@@ -1360,21 +1364,32 @@ public class RenderScript {
    }

    /**
     * Create a RenderScript context.
     * calls create(cts, ct, CREATE_FLAG_NONE)
     *
     * See documentation for @create for details
     *
     * @param ctx The context.
     * @param ct The type of context to be created.
     * @return RenderScript
     */
    public static RenderScript create(Context ctx, ContextType ct) {
        int v = ctx.getApplicationInfo().targetSdkVersion;
        return create(ctx, v, ct, CREATE_FLAG_NONE);
        return create(ctx, ct, CREATE_FLAG_NONE);
    }

     /**
     * Create a RenderScript context.
     * Gets or creates a RenderScript context of the specified type.
     *
     * The returned context will be cached for future reuse within
     * the process. When an application is finished using
     * RenderScript it should call releaseAllContexts()
     *
     * A process context is a context designed for easy creation and
     * lifecycle management.  Multiple calls to this function will
     * return the same object provided they are called with the same
     * options.  This allows it to be used any time a RenderScript
     * context is needed.
     *
     * Prior to API 23 this always created a new context.
     *
     * @param ctx The context.
     * @param ct The type of context to be created.
@@ -1383,9 +1398,75 @@ public class RenderScript {
     */
    public static RenderScript create(Context ctx, ContextType ct, int flags) {
        int v = ctx.getApplicationInfo().targetSdkVersion;
        return create(ctx, v, ct, flags);
        if (v < 23) {
            return internalCreate(ctx, v, ct, flags);
        }

        synchronized (mProcessContextList) {
            for (RenderScript prs : mProcessContextList) {
                if ((prs.mContextType == ct) &&
                    (prs.mContextFlags == flags) &&
                    (prs.mContextSdkVersion == v)) {

                    return prs;
                }
            }

            RenderScript prs = internalCreate(ctx, v, ct, flags);
            prs.mIsProcessContext = true;
            mProcessContextList.add(prs);
            return prs;
        }
    }

    /**
     * @hide
     *
     * Releases all the process contexts.  This is the same as
     * calling .destroy() on each unique context retreived with
     * create(...). If no contexts have been created this
     * function does nothing.
     *
     * Typically you call this when your application is losing focus
     * and will not be using a context for some time.
     *
     * This has no effect on a context created with
     * createMultiContext()
     */
    public static void releaseAllContexts() {
        ArrayList<RenderScript> oldList;
        synchronized (mProcessContextList) {
            oldList = mProcessContextList;
            mProcessContextList = new ArrayList<RenderScript>();
        }

        for (RenderScript prs : oldList) {
            prs.mIsProcessContext = false;
            prs.destroy();
        }
        oldList.clear();
    }



    /**
     * Create a RenderScript context.
     *
     * This is an advanced function intended for applications which
     * need to create more than one RenderScript context to be used
     * at the same time.
     *
     * If you need a single context please use create()
     *
     * @hide
     * @param ctx The context.
     * @return RenderScript
     */
    public static RenderScript createMultiContext(Context ctx, ContextType ct, int flags, int API_number) {
        return internalCreate(ctx, API_number, ct, flags);
    }


    /**
     * Print the currently available debugging information about the state of
     * the RS context to the log.
@@ -1442,8 +1523,16 @@ public class RenderScript {
     * using this context or any objects belonging to this context is
     * illegal.
     *
     * API 23+, this function is a NOP if the context was created
     * with create().  Please use releaseAllContexts() to clean up
     * contexts created with the create function.
     *
     */
    public void destroy() {
        if (mIsProcessContext) {
            // users cannot destroy a process context
            return;
        }
        validate();
        helpDestroy();
    }