/* * 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 android.hardware.camera2.cts.helpers.UncheckedCloseable; import android.renderscript.Allocation; import android.renderscript.RenderScript; import android.renderscript.Type; import android.util.Log; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static android.hardware.camera2.cts.helpers.Preconditions.*; /** * Cache {@link Allocation} objects based on their type and usage. * *
This avoids expensive re-allocation of objects when they are used over and over again * by different scripts.
*/ public class AllocationCache implements UncheckedCloseable { private static final String TAG = "AllocationCache"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static int sDebugHits = 0; private static int sDebugMisses = 0; private final RenderScript mRS; private final HashMapFuture calls to getOrCreateTyped with the same type and usage may * return this allocation.
* *Allocations that have usage {@link Allocation#USAGE_IO_INPUT} get their * listeners reset. Those that have {@link Allocation#USAGE_IO_OUTPUT} get their * surfaces reset.
* * @param allocation A non-{@code null} RenderScript {@link Allocation} * @throws NullPointerException if allocation was null * @throws IllegalArgumentException if the allocation was already returned previously * @throws IllegalStateException if the cache was closed with {@link #close} */ public synchronized void returnToCache(Allocation allocation) { checkNotNull("allocation", allocation); checkNotClosed(); int usage = allocation.getUsage(); AllocationKey key = new AllocationKey(allocation.getType(), usage); ListFuture calls to getOrCreateTyped with the same type and usage may * return this allocation.
* *Allocations that have usage {@link Allocation#USAGE_IO_INPUT} get their * listeners reset. Those that have {@link Allocation#USAGE_IO_OUTPUT} get their * surfaces reset.
* *{@code null} values are a no-op.
* * @param allocation A potentially {@code null} RenderScript {@link Allocation} * @throws IllegalArgumentException if the allocation was already returned previously * @throws IllegalStateException if the cache was closed with {@link #close} */ public synchronized void returnToCacheIfNotNull(Allocation allocation) { if (allocation != null) { returnToCache(allocation); } } /** * Closes the object and destroys any Allocations still in the cache. */ @Override public synchronized void close() { if (mClosed) return; for (Map.EntryAn Allocation is considered compatible if both it's Type and usage is equivalent.
*/ private static class AllocationKey { private final Type mType; private final int mUsage; public AllocationKey(Type type, int usage) { mType = type; mUsage = usage; } @Override public int hashCode() { return mType.hashCode() ^ mUsage; } @Override public boolean equals(Object other) { if (other instanceof AllocationKey){ AllocationKey otherKey = (AllocationKey) other; return otherKey.mType.equals(mType) && otherKey.mUsage == mUsage; } return false; } } private void checkNotClosed() { if (mClosed == true) { throw new IllegalStateException("AllocationCache has already been closed"); } } }