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