136e612a488511940b61f09803b270aa1c61b68e0Jason Sams/* 236e612a488511940b61f09803b270aa1c61b68e0Jason Sams * Copyright (C) 2008 The Android Open Source Project 336e612a488511940b61f09803b270aa1c61b68e0Jason Sams * 436e612a488511940b61f09803b270aa1c61b68e0Jason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 536e612a488511940b61f09803b270aa1c61b68e0Jason Sams * you may not use this file except in compliance with the License. 636e612a488511940b61f09803b270aa1c61b68e0Jason Sams * You may obtain a copy of the License at 736e612a488511940b61f09803b270aa1c61b68e0Jason Sams * 836e612a488511940b61f09803b270aa1c61b68e0Jason Sams * http://www.apache.org/licenses/LICENSE-2.0 936e612a488511940b61f09803b270aa1c61b68e0Jason Sams * 1036e612a488511940b61f09803b270aa1c61b68e0Jason Sams * Unless required by applicable law or agreed to in writing, software 1136e612a488511940b61f09803b270aa1c61b68e0Jason Sams * distributed under the License is distributed on an "AS IS" BASIS, 1236e612a488511940b61f09803b270aa1c61b68e0Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1336e612a488511940b61f09803b270aa1c61b68e0Jason Sams * See the License for the specific language governing permissions and 1436e612a488511940b61f09803b270aa1c61b68e0Jason Sams * limitations under the License. 1536e612a488511940b61f09803b270aa1c61b68e0Jason Sams */ 1636e612a488511940b61f09803b270aa1c61b68e0Jason Sams 1736e612a488511940b61f09803b270aa1c61b68e0Jason Samspackage android.renderscript; 1836e612a488511940b61f09803b270aa1c61b68e0Jason Sams 19ff7256e757502279b1777127a12eba235be679aeJason Samsimport java.util.concurrent.locks.ReentrantReadWriteLock; 2036e612a488511940b61f09803b270aa1c61b68e0Jason Sams 219c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines/** 22c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * BaseObj is the base class for all RenderScript objects owned by a RS context. 23c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * It is responsible for lifetime management and resource tracking. This class 24c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * should not be used by a user application. 2506d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams * 2636e612a488511940b61f09803b270aa1c61b68e0Jason Sams **/ 27ef353dde086a6833471deff4da58a6eaf8a1ef36Stephen Hinespublic class BaseObj { 280de9444aa6c25d2c586e8204a6168d10e67376e0Alex Sakhartchouk BaseObj(int id, RenderScript rs) { 29718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams rs.validate(); 3036e612a488511940b61f09803b270aa1c61b68e0Jason Sams mRS = rs; 310de9444aa6c25d2c586e8204a6168d10e67376e0Alex Sakhartchouk mID = id; 321bada8cd6e4f340de93cff4a2439835fc3b1456cJason Sams mDestroyed = false; 3336e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 3436e612a488511940b61f09803b270aa1c61b68e0Jason Sams 3506d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams void setID(int id) { 3606d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams if (mID != 0) { 3706d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams throw new RSRuntimeException("Internal Error, reset of object ID."); 3806d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams } 3906d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams mID = id; 4006d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams } 4106d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams 429c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines /** 4327676fe24be7444a174c15df476e49adc5335d03Jason Sams * Lookup the native object ID for this object. Primarily used by the 4427676fe24be7444a174c15df476e49adc5335d03Jason Sams * generated reflected code. 4527676fe24be7444a174c15df476e49adc5335d03Jason Sams * 46e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams * @param rs Context to verify against internal context for 47e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams * match. 4827676fe24be7444a174c15df476e49adc5335d03Jason Sams * 4927676fe24be7444a174c15df476e49adc5335d03Jason Sams * @return int 5027676fe24be7444a174c15df476e49adc5335d03Jason Sams */ 51e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams int getID(RenderScript rs) { 52e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams mRS.validate(); 537aa150c0967b725850cf27de58f50a25a960b092Jason Sams if (mDestroyed) { 54c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams throw new RSInvalidStateException("using a destroyed object."); 557aa150c0967b725850cf27de58f50a25a960b092Jason Sams } 565476b450e50939940dcf3f15c92335cee2fc572dJason Sams if (mID == 0) { 575476b450e50939940dcf3f15c92335cee2fc572dJason Sams throw new RSRuntimeException("Internal error: Object id 0."); 585476b450e50939940dcf3f15c92335cee2fc572dJason Sams } 59e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams if ((rs != null) && (rs != mRS)) { 60e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams throw new RSInvalidStateException("using object with mismatched context."); 61e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams } 6236e612a488511940b61f09803b270aa1c61b68e0Jason Sams return mID; 6336e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 6436e612a488511940b61f09803b270aa1c61b68e0Jason Sams 65bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams void checkValid() { 66bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams if (mID == 0) { 67bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams throw new RSIllegalArgumentException("Invalid object."); 68bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams } 69bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams } 70bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams 7106d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams private int mID; 7206d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams private boolean mDestroyed; 7306d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams private String mName; 7436e612a488511940b61f09803b270aa1c61b68e0Jason Sams RenderScript mRS; 7536e612a488511940b61f09803b270aa1c61b68e0Jason Sams 769c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines /** 7727676fe24be7444a174c15df476e49adc5335d03Jason Sams * setName assigns a name to an object. This object can later be looked up 78c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * by this name. 7927676fe24be7444a174c15df476e49adc5335d03Jason Sams * 8027676fe24be7444a174c15df476e49adc5335d03Jason Sams * @param name The name to assign to the object. 8127676fe24be7444a174c15df476e49adc5335d03Jason Sams */ 8227676fe24be7444a174c15df476e49adc5335d03Jason Sams public void setName(String name) { 8384a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines if (name == null) { 8484a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines throw new RSIllegalArgumentException( 8584a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines "setName requires a string of non-zero length."); 8684a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines } 8727676fe24be7444a174c15df476e49adc5335d03Jason Sams if(name.length() < 1) { 8884a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines throw new RSIllegalArgumentException( 8984a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines "setName does not accept a zero length string."); 9036e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 9136e612a488511940b61f09803b270aa1c61b68e0Jason Sams if(mName != null) { 9284a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines throw new RSIllegalArgumentException( 9384a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines "setName object already has a name."); 9436e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 9536e612a488511940b61f09803b270aa1c61b68e0Jason Sams 9636e612a488511940b61f09803b270aa1c61b68e0Jason Sams try { 9727676fe24be7444a174c15df476e49adc5335d03Jason Sams byte[] bytes = name.getBytes("UTF-8"); 9836e612a488511940b61f09803b270aa1c61b68e0Jason Sams mRS.nAssignName(mID, bytes); 9927676fe24be7444a174c15df476e49adc5335d03Jason Sams mName = name; 10036e612a488511940b61f09803b270aa1c61b68e0Jason Sams } catch (java.io.UnsupportedEncodingException e) { 10136e612a488511940b61f09803b270aa1c61b68e0Jason Sams throw new RuntimeException(e); 10236e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 10336e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 10436e612a488511940b61f09803b270aa1c61b68e0Jason Sams 1059c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines /** 1060400b07c6bfc3fca49bc10db0a2040aba8664c8eAlex Sakhartchouk * @return name of the renderscript object 1070400b07c6bfc3fca49bc10db0a2040aba8664c8eAlex Sakhartchouk */ 1080400b07c6bfc3fca49bc10db0a2040aba8664c8eAlex Sakhartchouk public String getName() { 1090400b07c6bfc3fca49bc10db0a2040aba8664c8eAlex Sakhartchouk return mName; 1100400b07c6bfc3fca49bc10db0a2040aba8664c8eAlex Sakhartchouk } 1110400b07c6bfc3fca49bc10db0a2040aba8664c8eAlex Sakhartchouk 112ff7256e757502279b1777127a12eba235be679aeJason Sams private void helpDestroy() { 113ff7256e757502279b1777127a12eba235be679aeJason Sams boolean shouldDestroy = false; 114ff7256e757502279b1777127a12eba235be679aeJason Sams synchronized(this) { 115ff7256e757502279b1777127a12eba235be679aeJason Sams if (!mDestroyed) { 116ff7256e757502279b1777127a12eba235be679aeJason Sams shouldDestroy = true; 117ff7256e757502279b1777127a12eba235be679aeJason Sams mDestroyed = true; 118ff7256e757502279b1777127a12eba235be679aeJason Sams } 119ff7256e757502279b1777127a12eba235be679aeJason Sams } 120ff7256e757502279b1777127a12eba235be679aeJason Sams 121ff7256e757502279b1777127a12eba235be679aeJason Sams if (shouldDestroy) { 122ff7256e757502279b1777127a12eba235be679aeJason Sams // must include nObjDestroy in the critical section 123ff7256e757502279b1777127a12eba235be679aeJason Sams ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock(); 124ff7256e757502279b1777127a12eba235be679aeJason Sams rlock.lock(); 125cf8573c15456c4581b691c7380722ea6dccf11c5Jason Sams // AllocationAdapters are BaseObjs with an ID of 0 but should not be passed to nObjDestroy 126cf8573c15456c4581b691c7380722ea6dccf11c5Jason Sams if(mRS.isAlive() && mID != 0) { 127d78be37d81f6c1aba75180c7608753a027a881eeJason Sams mRS.nObjDestroy(mID); 128730ee65d4ddb307898053b623120bad1655fadadJason Sams } 129ff7256e757502279b1777127a12eba235be679aeJason Sams rlock.unlock(); 130a9e7a05b84470257637c97d65f6562aa832c66efJason Sams mRS = null; 131730ee65d4ddb307898053b623120bad1655fadadJason Sams mID = 0; 13236e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 133ff7256e757502279b1777127a12eba235be679aeJason Sams } 134ff7256e757502279b1777127a12eba235be679aeJason Sams 135ff7256e757502279b1777127a12eba235be679aeJason Sams protected void finalize() throws Throwable { 136ff7256e757502279b1777127a12eba235be679aeJason Sams helpDestroy(); 13736e612a488511940b61f09803b270aa1c61b68e0Jason Sams super.finalize(); 13836e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 1397ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams 1409c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines /** 141c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * Frees any native resources associated with this object. The 142c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * primary use is to force immediate cleanup of resources when it is 143c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * believed the GC will not respond quickly enough. 14427676fe24be7444a174c15df476e49adc5335d03Jason Sams */ 145ff7256e757502279b1777127a12eba235be679aeJason Sams public void destroy() { 1467ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams if(mDestroyed) { 147c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams throw new RSInvalidStateException("Object already destroyed."); 1487ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams } 149ff7256e757502279b1777127a12eba235be679aeJason Sams helpDestroy(); 1507ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams } 1517ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams 1529c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines /** 15327676fe24be7444a174c15df476e49adc5335d03Jason Sams * If an object came from an a3d file, java fields need to be 15427676fe24be7444a174c15df476e49adc5335d03Jason Sams * created with objects from the native layer 15527676fe24be7444a174c15df476e49adc5335d03Jason Sams */ 15680a4c2cd34aedb4f1a2e5e7d1ac26a9aeebe41aeAlex Sakhartchouk void updateFromNative() { 15706d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams mRS.validate(); 158e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams mName = mRS.nGetName(getID(mRS)); 15980a4c2cd34aedb4f1a2e5e7d1ac26a9aeebe41aeAlex Sakhartchouk } 16080a4c2cd34aedb4f1a2e5e7d1ac26a9aeebe41aeAlex Sakhartchouk 1619c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines /** 162705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * Calculates the hash code value for a BaseObj. 163705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * 164705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * @return int 165705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines */ 166705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines @Override 167705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines public int hashCode() { 168705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines return mID; 169705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines } 170705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines 1719c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines /** 172705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * Compare the current BaseObj with another BaseObj for equality. 173705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * 174705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * @param obj The object to check equality with. 175705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * 176705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * @return boolean 177705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines */ 178705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines @Override 179705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines public boolean equals(Object obj) { 180705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines // Early-out check to see if both BaseObjs are actually the same 181705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines if (this == obj) 182705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines return true; 183705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines 184705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines if (getClass() != obj.getClass()) { 185705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines return false; 186705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines } 187705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines 188705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines BaseObj b = (BaseObj) obj; 189705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines return mID == b.mID; 190705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines } 19136e612a488511940b61f09803b270aa1c61b68e0Jason Sams} 19236e612a488511940b61f09803b270aa1c61b68e0Jason Sams 193