/* * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.hardware.camera2.cts.rs; import static android.hardware.camera2.cts.helpers.Preconditions.*; import android.hardware.camera2.cts.helpers.UncheckedCloseable; import android.renderscript.Allocation; import android.renderscript.RenderScript; import android.util.Log; import java.util.HashMap; /** * Base class for all renderscript script abstractions. * *
Each script has exactly one input and one output allocation, and is able to execute * one {@link android.renderscript.Script} script file.
* *Each script owns it's input allocation, but not the output allocation.
* *Subclasses of this class must implement exactly one of two constructors: *
Two script parameters are considered equal only if their script class and value * class are both equal.
*/ @SuppressWarnings("unchecked") @Override public boolean equals(Object other) { if (other instanceof ScriptParameter) { ScriptParameterMust be called before executing any scripts.
* * @throws IllegalStateException If the script has already been {@link #close closed}. */ void setInput(Allocation allocation) { checkNotClosed(); checkNotNull("allocation", allocation); checkEquals("allocation info", AllocationInfo.newInstance(allocation), "input info", mInputInfo); // Scripts own the input, so return old input to cache if the input changes if (mInputAllocation != allocation) { mCache.returnToCacheIfNotNull(mInputAllocation); } mInputAllocation = allocation; updateScriptInput(); } protected abstract void updateScriptInput(); /** * Set the output. * *Must be called before executing any scripts.
* * @throws IllegalStateException If the script has already been {@link #close closed}. */ void setOutput(Allocation allocation) { checkNotClosed(); checkNotNull("allocation", allocation); checkEquals("allocation info", AllocationInfo.newInstance(allocation), "output info", mOutputInfo); // Scripts do not own the output, simply set a reference to the new one. mOutputAllocation = allocation; } protected Script(AllocationInfo inputInfo, AllocationInfo outputInfo, T rsScript) { checkNotNull("inputInfo", inputInfo); checkNotNull("outputInfo", outputInfo); checkNotNull("rsScript", rsScript); mInputInfo = inputInfo; mOutputInfo = outputInfo; mScript = rsScript; if (VERBOSE) { Log.v(TAG, String.format("%s - inputInfo = %s, outputInfo = %s, rsScript = %s", getName(), inputInfo, outputInfo, rsScript)); } } /** * Get the {@link Allocation} associated with this script's input. * * @return The input {@link Allocation}, which is never {@code null}. * * @throws IllegalStateException If the script has already been {@link #close closed}. */ public Allocation getInput() { checkNotClosed(); return mInputAllocation; } /** * Get the {@link Allocation} associated with this script's output. * * @return The output {@link Allocation}, which is never {@code null}. * * @throws IllegalStateException If the script has already been {@link #close closed}. */ public Allocation getOutput() { checkNotClosed(); return mOutputAllocation; } /** * Execute the script's kernel against the input/output {@link Allocation allocations}. * *Once this is complete, the output will have the new data available (for either * the next script, or to read out with a copy).
* * @throws IllegalStateException If the script has already been {@link #close closed}. */ public void execute() { checkNotClosed(); if (mInputAllocation == null || mOutputAllocation == null) { throw new IllegalStateException("Both inputs and outputs must have been set"); } executeUnchecked(); } /** * Get the name of this script. * *The name is the short hand name of the concrete class backing this script.
* *This method works even if the script has already been {@link #close closed}.
* * @return A string representing the script name. */ public String getName() { return getClass().getSimpleName(); } protected abstract void executeUnchecked(); protected void checkNotClosed() { if (mClosed) { throw new IllegalStateException("Script has been closed"); } } /** * Destroy the underlying script object and return the input allocation back to the * {@link AllocationCache cache}. * *This method has no effect if called more than once.
*/ @Override public void close() { if (mClosed) return; // Scripts own the input allocation. They do NOT own outputs. mCache.returnToCacheIfNotNull(mInputAllocation); mScript.destroy(); mClosed = true; } @Override protected void finalize() throws Throwable { try { close(); } finally { super.finalize(); } } protected static RenderScript getRS() { return RenderScriptSingleton.getRS(); } }