1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.support.v8.renderscript; 18 19import android.util.Log; 20import java.util.concurrent.locks.ReentrantReadWriteLock; 21 22/** 23 * BaseObj is the base class for all RenderScript objects owned by a RS context. 24 * It is responsible for lifetime management and resource tracking. This class 25 * should not be used by a user application. 26 * 27 **/ 28public class BaseObj { 29 BaseObj(long id, RenderScript rs) { 30 rs.validate(); 31 mRS = rs; 32 mID = id; 33 mDestroyed = false; 34 } 35 36 void setID(long id) { 37 if (mID != 0) { 38 throw new RSRuntimeException("Internal Error, reset of object ID."); 39 } 40 mID = id; 41 } 42 43 /** 44 * Lookup the native object ID for this object. Primarily used by the 45 * generated reflected code. 46 * 47 * @param rs Context to verify against internal context for 48 * match. 49 * 50 * @return long 51 */ 52 long getID(RenderScript rs) { 53 mRS.validate(); 54 if (mDestroyed) { 55 throw new RSInvalidStateException("using a destroyed object."); 56 } 57 if (mID == 0) { 58 throw new RSRuntimeException("Internal error: Object id 0."); 59 } 60 if ((rs != null) && (rs != mRS)) { 61 throw new RSInvalidStateException("using object with mismatched context."); 62 } 63 return mID; 64 } 65 66 android.renderscript.BaseObj getNObj() { 67 return null; 68 } 69 70 void checkValid() { 71 if ((mID == 0) && (getNObj() == null)) { 72 throw new RSIllegalArgumentException("Invalid object."); 73 } 74 } 75 76 private long mID; 77 private boolean mDestroyed; 78 RenderScript mRS; 79 80 private void helpDestroy() { 81 boolean shouldDestroy = false; 82 synchronized(this) { 83 if (!mDestroyed) { 84 shouldDestroy = true; 85 mDestroyed = true; 86 } 87 } 88 89 if (shouldDestroy) { 90 // must include nObjDestroy in the critical section 91 ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock(); 92 rlock.lock(); 93 if(mRS.isAlive()) { 94 mRS.nObjDestroy(mID); 95 } 96 rlock.unlock(); 97 mRS = null; 98 mID = 0; 99 } 100 } 101 102 103 protected void finalize() throws Throwable { 104 helpDestroy(); 105 super.finalize(); 106 } 107 108 /** 109 * Frees any native resources associated with this object. The 110 * primary use is to force immediate cleanup of resources when it is 111 * believed the GC will not respond quickly enough. 112 */ 113 public void destroy() { 114 if(mDestroyed) { 115 throw new RSInvalidStateException("Object already destroyed."); 116 } 117 helpDestroy(); 118 } 119 120 /** 121 * Calculates the hash code value for a BaseObj. 122 * 123 * @return int 124 */ 125 @Override 126 public int hashCode() { 127 return (int)((mID & 0xfffffff) ^ (mID >> 32)); 128 } 129 130 /** 131 * Compare the current BaseObj with another BaseObj for equality. 132 * 133 * @param obj The object to check equality with. 134 * 135 * @return boolean 136 */ 137 @Override 138 public boolean equals(Object obj) { 139 // Early-out check to see if both BaseObjs are actually the same 140 if (this == obj) 141 return true; 142 143 if (obj == null) { 144 return false; 145 } 146 147 if (getClass() != obj.getClass()) { 148 return false; 149 } 150 151 BaseObj b = (BaseObj) obj; 152 return mID == b.mID; 153 } 154} 155 156