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 196484b6be5ca5233614d0a8991a5d909543824fc7Yang Niimport dalvik.system.CloseGuard; 20504abb362660f87239103be182a2e717a98ff32aTim Murrayimport java.util.concurrent.locks.ReentrantReadWriteLock; 2136e612a488511940b61f09803b270aa1c61b68e0Jason Sams 229c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines/** 23c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * BaseObj is the base class for all RenderScript objects owned by a RS context. 24c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * It is responsible for lifetime management and resource tracking. This class 25c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * should not be used by a user application. 2606d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams * 2736e612a488511940b61f09803b270aa1c61b68e0Jason Sams **/ 28ef353dde086a6833471deff4da58a6eaf8a1ef36Stephen Hinespublic class BaseObj { 297a629fac82f88126642081b4474879f6a883e313Tim Murray BaseObj(long id, RenderScript rs) { 30718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams rs.validate(); 3136e612a488511940b61f09803b270aa1c61b68e0Jason Sams mRS = rs; 320de9444aa6c25d2c586e8204a6168d10e67376e0Alex Sakhartchouk mID = id; 331bada8cd6e4f340de93cff4a2439835fc3b1456cJason Sams mDestroyed = false; 3436e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 3536e612a488511940b61f09803b270aa1c61b68e0Jason Sams 360e0c0885aed99a119052a792becb5a0c5a93632dAshok Bhat void setID(long id) { 3706d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams if (mID != 0) { 3806d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams throw new RSRuntimeException("Internal Error, reset of object ID."); 3906d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams } 4006d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams mID = id; 4106d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams } 4206d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams 439c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines /** 4427676fe24be7444a174c15df476e49adc5335d03Jason Sams * Lookup the native object ID for this object. Primarily used by the 4527676fe24be7444a174c15df476e49adc5335d03Jason Sams * generated reflected code. 4627676fe24be7444a174c15df476e49adc5335d03Jason Sams * 47e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams * @param rs Context to verify against internal context for 48e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams * match. 4927676fe24be7444a174c15df476e49adc5335d03Jason Sams * 507a629fac82f88126642081b4474879f6a883e313Tim Murray * @return long 5127676fe24be7444a174c15df476e49adc5335d03Jason Sams */ 527a629fac82f88126642081b4474879f6a883e313Tim Murray long getID(RenderScript rs) { 53e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams mRS.validate(); 547aa150c0967b725850cf27de58f50a25a960b092Jason Sams if (mDestroyed) { 55c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams throw new RSInvalidStateException("using a destroyed object."); 567aa150c0967b725850cf27de58f50a25a960b092Jason Sams } 575476b450e50939940dcf3f15c92335cee2fc572dJason Sams if (mID == 0) { 585476b450e50939940dcf3f15c92335cee2fc572dJason Sams throw new RSRuntimeException("Internal error: Object id 0."); 595476b450e50939940dcf3f15c92335cee2fc572dJason Sams } 60e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams if ((rs != null) && (rs != mRS)) { 61e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams throw new RSInvalidStateException("using object with mismatched context."); 62e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams } 6336e612a488511940b61f09803b270aa1c61b68e0Jason Sams return mID; 6436e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 6536e612a488511940b61f09803b270aa1c61b68e0Jason Sams 66bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams void checkValid() { 67bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams if (mID == 0) { 68bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams throw new RSIllegalArgumentException("Invalid object."); 69bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams } 70bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams } 71bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams 727a629fac82f88126642081b4474879f6a883e313Tim Murray private long mID; 736484b6be5ca5233614d0a8991a5d909543824fc7Yang Ni final CloseGuard guard = CloseGuard.get(); 7406d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams private boolean mDestroyed; 7506d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams private String mName; 7636e612a488511940b61f09803b270aa1c61b68e0Jason Sams RenderScript mRS; 7736e612a488511940b61f09803b270aa1c61b68e0Jason Sams 789c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines /** 7927676fe24be7444a174c15df476e49adc5335d03Jason Sams * setName assigns a name to an object. This object can later be looked up 80c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * by this name. 8127676fe24be7444a174c15df476e49adc5335d03Jason Sams * 8227676fe24be7444a174c15df476e49adc5335d03Jason Sams * @param name The name to assign to the object. 8327676fe24be7444a174c15df476e49adc5335d03Jason Sams */ 8427676fe24be7444a174c15df476e49adc5335d03Jason Sams public void setName(String name) { 8584a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines if (name == null) { 8684a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines throw new RSIllegalArgumentException( 8784a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines "setName requires a string of non-zero length."); 8884a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines } 8927676fe24be7444a174c15df476e49adc5335d03Jason Sams if(name.length() < 1) { 9084a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines throw new RSIllegalArgumentException( 9184a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines "setName does not accept a zero length string."); 9236e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 9336e612a488511940b61f09803b270aa1c61b68e0Jason Sams if(mName != null) { 9484a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines throw new RSIllegalArgumentException( 9584a97cae1e53400676a4dfd6c7bf75f9ac230fceStephen Hines "setName object already has a name."); 9636e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 9736e612a488511940b61f09803b270aa1c61b68e0Jason Sams 9836e612a488511940b61f09803b270aa1c61b68e0Jason Sams try { 9927676fe24be7444a174c15df476e49adc5335d03Jason Sams byte[] bytes = name.getBytes("UTF-8"); 10036e612a488511940b61f09803b270aa1c61b68e0Jason Sams mRS.nAssignName(mID, bytes); 10127676fe24be7444a174c15df476e49adc5335d03Jason Sams mName = name; 10236e612a488511940b61f09803b270aa1c61b68e0Jason Sams } catch (java.io.UnsupportedEncodingException e) { 10336e612a488511940b61f09803b270aa1c61b68e0Jason Sams throw new RuntimeException(e); 10436e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 10536e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 10636e612a488511940b61f09803b270aa1c61b68e0Jason Sams 1079c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines /** 1080400b07c6bfc3fca49bc10db0a2040aba8664c8eAlex Sakhartchouk * @return name of the renderscript object 1090400b07c6bfc3fca49bc10db0a2040aba8664c8eAlex Sakhartchouk */ 1100400b07c6bfc3fca49bc10db0a2040aba8664c8eAlex Sakhartchouk public String getName() { 1110400b07c6bfc3fca49bc10db0a2040aba8664c8eAlex Sakhartchouk return mName; 1120400b07c6bfc3fca49bc10db0a2040aba8664c8eAlex Sakhartchouk } 1130400b07c6bfc3fca49bc10db0a2040aba8664c8eAlex Sakhartchouk 114504abb362660f87239103be182a2e717a98ff32aTim Murray private void helpDestroy() { 115504abb362660f87239103be182a2e717a98ff32aTim Murray boolean shouldDestroy = false; 116504abb362660f87239103be182a2e717a98ff32aTim Murray synchronized(this) { 117504abb362660f87239103be182a2e717a98ff32aTim Murray if (!mDestroyed) { 118504abb362660f87239103be182a2e717a98ff32aTim Murray shouldDestroy = true; 119504abb362660f87239103be182a2e717a98ff32aTim Murray mDestroyed = true; 120504abb362660f87239103be182a2e717a98ff32aTim Murray } 121504abb362660f87239103be182a2e717a98ff32aTim Murray } 122504abb362660f87239103be182a2e717a98ff32aTim Murray 123504abb362660f87239103be182a2e717a98ff32aTim Murray if (shouldDestroy) { 1246484b6be5ca5233614d0a8991a5d909543824fc7Yang Ni guard.close(); 125504abb362660f87239103be182a2e717a98ff32aTim Murray // must include nObjDestroy in the critical section 126504abb362660f87239103be182a2e717a98ff32aTim Murray ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock(); 127504abb362660f87239103be182a2e717a98ff32aTim Murray rlock.lock(); 1286d63c84f443b2dcc573cac69f234b3d52493d7b1Tim Murray // AllocationAdapters are BaseObjs with an ID of 0 but should not be passed to nObjDestroy 1296d63c84f443b2dcc573cac69f234b3d52493d7b1Tim Murray if(mRS.isAlive() && mID != 0) { 130d78be37d81f6c1aba75180c7608753a027a881eeJason Sams mRS.nObjDestroy(mID); 131730ee65d4ddb307898053b623120bad1655fadadJason Sams } 132504abb362660f87239103be182a2e717a98ff32aTim Murray rlock.unlock(); 133a9e7a05b84470257637c97d65f6562aa832c66efJason Sams mRS = null; 134730ee65d4ddb307898053b623120bad1655fadadJason Sams mID = 0; 13536e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 136504abb362660f87239103be182a2e717a98ff32aTim Murray } 137504abb362660f87239103be182a2e717a98ff32aTim Murray 138504abb362660f87239103be182a2e717a98ff32aTim Murray protected void finalize() throws Throwable { 1396484b6be5ca5233614d0a8991a5d909543824fc7Yang Ni try { 1406484b6be5ca5233614d0a8991a5d909543824fc7Yang Ni if (guard != null) { 1416484b6be5ca5233614d0a8991a5d909543824fc7Yang Ni guard.warnIfOpen(); 1426484b6be5ca5233614d0a8991a5d909543824fc7Yang Ni } 1436484b6be5ca5233614d0a8991a5d909543824fc7Yang Ni helpDestroy(); 1446484b6be5ca5233614d0a8991a5d909543824fc7Yang Ni } finally { 1456484b6be5ca5233614d0a8991a5d909543824fc7Yang Ni super.finalize(); 1466484b6be5ca5233614d0a8991a5d909543824fc7Yang Ni } 14736e612a488511940b61f09803b270aa1c61b68e0Jason Sams } 1487ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams 1499c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines /** 150c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * Frees any native resources associated with this object. The 151c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * primary use is to force immediate cleanup of resources when it is 152c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * believed the GC will not respond quickly enough. 15327676fe24be7444a174c15df476e49adc5335d03Jason Sams */ 154504abb362660f87239103be182a2e717a98ff32aTim Murray public void destroy() { 1557ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams if(mDestroyed) { 156c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams throw new RSInvalidStateException("Object already destroyed."); 1577ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams } 158504abb362660f87239103be182a2e717a98ff32aTim Murray helpDestroy(); 1597ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams } 1607ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams 1619c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines /** 16227676fe24be7444a174c15df476e49adc5335d03Jason Sams * If an object came from an a3d file, java fields need to be 16327676fe24be7444a174c15df476e49adc5335d03Jason Sams * created with objects from the native layer 16427676fe24be7444a174c15df476e49adc5335d03Jason Sams */ 16580a4c2cd34aedb4f1a2e5e7d1ac26a9aeebe41aeAlex Sakhartchouk void updateFromNative() { 16606d69de78845659e6904ae4964e606a7f1a6a4a8Jason Sams mRS.validate(); 167e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams mName = mRS.nGetName(getID(mRS)); 16880a4c2cd34aedb4f1a2e5e7d1ac26a9aeebe41aeAlex Sakhartchouk } 16980a4c2cd34aedb4f1a2e5e7d1ac26a9aeebe41aeAlex Sakhartchouk 1709c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines /** 171705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * Calculates the hash code value for a BaseObj. 172705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * 173705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * @return int 174705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines */ 175705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines @Override 176705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines public int hashCode() { 1777a629fac82f88126642081b4474879f6a883e313Tim Murray return (int)((mID & 0xfffffff) ^ (mID >> 32)); 178705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines } 179705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines 1809c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines /** 181705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * Compare the current BaseObj with another BaseObj for equality. 182705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * 183705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * @param obj The object to check equality with. 184705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * 185705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines * @return boolean 186705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines */ 187705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines @Override 188705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines public boolean equals(Object obj) { 189705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines // Early-out check to see if both BaseObjs are actually the same 190705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines if (this == obj) 191705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines return true; 192705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines 19378214c9531f936549bd9141ca7a6aa5ac27c8622Tim Murray if (obj == null) { 19478214c9531f936549bd9141ca7a6aa5ac27c8622Tim Murray return false; 19578214c9531f936549bd9141ca7a6aa5ac27c8622Tim Murray } 19678214c9531f936549bd9141ca7a6aa5ac27c8622Tim Murray 197705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines if (getClass() != obj.getClass()) { 198705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines return false; 199705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines } 200705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines 201705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines BaseObj b = (BaseObj) obj; 202705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines return mID == b.mID; 203705d2ea63a4b3c2345af83eec9dabdeea29cfa9fStephen Hines } 20436e612a488511940b61f09803b270aa1c61b68e0Jason Sams} 20536e612a488511940b61f09803b270aa1c61b68e0Jason Sams 206