1 /* 2 * Copyright (C) 2008 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 17 package android.renderscript; 18 19 import android.compat.annotation.UnsupportedAppUsage; 20 21 import dalvik.system.CloseGuard; 22 23 import java.util.concurrent.locks.ReentrantReadWriteLock; 24 25 /** 26 * BaseObj is the base class for all RenderScript objects owned by a RS context. 27 * It is responsible for lifetime management and resource tracking. This class 28 * should not be used by a user application. 29 * 30 * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a 31 * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration 32 * guide</a> for the proposed alternatives. 33 **/ 34 @Deprecated 35 public class BaseObj { BaseObj(long id, RenderScript rs)36 BaseObj(long id, RenderScript rs) { 37 rs.validate(); 38 mRS = rs; 39 mID = id; 40 mDestroyed = false; 41 } 42 setID(long id)43 void setID(long id) { 44 if (mID != 0) { 45 throw new RSRuntimeException("Internal Error, reset of object ID."); 46 } 47 mID = id; 48 } 49 50 /** 51 * Lookup the native object ID for this object. Primarily used by the 52 * generated reflected code. 53 * 54 * @param rs Context to verify against internal context for 55 * match. 56 * 57 * @return long 58 */ getID(RenderScript rs)59 long getID(RenderScript rs) { 60 mRS.validate(); 61 if (mDestroyed) { 62 throw new RSInvalidStateException("using a destroyed object."); 63 } 64 if (mID == 0) { 65 throw new RSRuntimeException("Internal error: Object id 0."); 66 } 67 if ((rs != null) && (rs != mRS)) { 68 throw new RSInvalidStateException("using object with mismatched context."); 69 } 70 return mID; 71 } 72 checkValid()73 void checkValid() { 74 if (mID == 0) { 75 throw new RSIllegalArgumentException("Invalid object."); 76 } 77 } 78 79 private long mID; 80 final CloseGuard guard = CloseGuard.get(); 81 private boolean mDestroyed; 82 private String mName; 83 @UnsupportedAppUsage 84 RenderScript mRS; 85 86 /** 87 * setName assigns a name to an object. This object can later be looked up 88 * by this name. 89 * 90 * @param name The name to assign to the object. 91 */ setName(String name)92 public void setName(String name) { 93 if (name == null) { 94 throw new RSIllegalArgumentException( 95 "setName requires a string of non-zero length."); 96 } 97 if(name.length() < 1) { 98 throw new RSIllegalArgumentException( 99 "setName does not accept a zero length string."); 100 } 101 if(mName != null) { 102 throw new RSIllegalArgumentException( 103 "setName object already has a name."); 104 } 105 106 try { 107 byte[] bytes = name.getBytes("UTF-8"); 108 mRS.nAssignName(mID, bytes); 109 mName = name; 110 } catch (java.io.UnsupportedEncodingException e) { 111 throw new RuntimeException(e); 112 } 113 } 114 115 /** 116 * @return name of the renderscript object 117 */ getName()118 public String getName() { 119 return mName; 120 } 121 helpDestroy()122 private void helpDestroy() { 123 boolean shouldDestroy = false; 124 synchronized(this) { 125 if (!mDestroyed) { 126 shouldDestroy = true; 127 mDestroyed = true; 128 } 129 } 130 131 if (shouldDestroy) { 132 guard.close(); 133 // must include nObjDestroy in the critical section 134 ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock(); 135 rlock.lock(); 136 // AllocationAdapters are BaseObjs with an ID of 0 but should not be passed to nObjDestroy 137 if(mRS.isAlive() && mID != 0) { 138 mRS.nObjDestroy(mID); 139 } 140 rlock.unlock(); 141 mRS = null; 142 mID = 0; 143 } 144 } 145 finalize()146 protected void finalize() throws Throwable { 147 try { 148 if (guard != null) { 149 guard.warnIfOpen(); 150 } 151 helpDestroy(); 152 } finally { 153 super.finalize(); 154 } 155 } 156 157 /** 158 * Frees any native resources associated with this object. The 159 * primary use is to force immediate cleanup of resources when it is 160 * believed the GC will not respond quickly enough. 161 */ destroy()162 public void destroy() { 163 if(mDestroyed) { 164 throw new RSInvalidStateException("Object already destroyed."); 165 } 166 helpDestroy(); 167 } 168 169 /** 170 * If an object came from an a3d file, java fields need to be 171 * created with objects from the native layer 172 */ updateFromNative()173 void updateFromNative() { 174 mRS.validate(); 175 mName = mRS.nGetName(getID(mRS)); 176 } 177 178 /** 179 * Calculates the hash code value for a BaseObj. 180 * 181 * @return int 182 */ 183 @Override hashCode()184 public int hashCode() { 185 return (int)((mID & 0xfffffff) ^ (mID >> 32)); 186 } 187 188 /** 189 * Compare the current BaseObj with another BaseObj for equality. 190 * 191 * @param obj The object to check equality with. 192 * 193 * @return boolean 194 */ 195 @Override equals(Object obj)196 public boolean equals(Object obj) { 197 // Early-out check to see if both BaseObjs are actually the same 198 if (this == obj) 199 return true; 200 201 if (obj == null) { 202 return false; 203 } 204 205 if (getClass() != obj.getClass()) { 206 return false; 207 } 208 209 BaseObj b = (BaseObj) obj; 210 return mID == b.mID; 211 } 212 } 213 214