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 android.util.Log;
     20 
     21 /**
     22  * BaseObj is the base class for interfacing with native renderscript objects.
     23  * It primarly contains code for tracking the native object ID and forcably
     24  * disconecting the object from the native allocation for early cleanup.
     25  *
     26  **/
     27 public class BaseObj {
     28     BaseObj(int id, RenderScript rs) {
     29         rs.validate();
     30         mRS = rs;
     31         mID = id;
     32         mDestroyed = false;
     33     }
     34 
     35     void setID(int 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 int
     50      */
     51     int 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 int 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.  This name will also be retained if the object is written
     79      * to an A3D file.
     80      *
     81      * @param name The name to assign to the object.
     82      */
     83     public void setName(String name) {
     84         if (name == null) {
     85             throw new RSIllegalArgumentException(
     86                 "setName requires a string of non-zero length.");
     87         }
     88         if(name.length() < 1) {
     89             throw new RSIllegalArgumentException(
     90                 "setName does not accept a zero length string.");
     91         }
     92         if(mName != null) {
     93             throw new RSIllegalArgumentException(
     94                 "setName object already has a name.");
     95         }
     96 
     97         try {
     98             byte[] bytes = name.getBytes("UTF-8");
     99             mRS.nAssignName(mID, bytes);
    100             mName = name;
    101         } catch (java.io.UnsupportedEncodingException e) {
    102             throw new RuntimeException(e);
    103         }
    104     }
    105 
    106     /**
    107      * @return name of the renderscript object
    108      */
    109     public String getName() {
    110         return mName;
    111     }
    112 
    113     protected void finalize() throws Throwable {
    114         if (!mDestroyed) {
    115             if(mID != 0 && mRS.isAlive()) {
    116                 mRS.nObjDestroy(mID);
    117             }
    118             mRS = null;
    119             mID = 0;
    120             mDestroyed = true;
    121             //Log.v(RenderScript.LOG_TAG, getClass() +
    122             // " auto finalizing object without having released the RS reference.");
    123         }
    124         super.finalize();
    125     }
    126 
    127     /**
    128      * destroy disconnects the object from the native object effectively
    129      * rendering this java object dead.  The primary use is to force immediate
    130      * cleanup of resources when it is believed the GC will not respond quickly
    131      * enough.
    132      */
    133     synchronized public void destroy() {
    134         if(mDestroyed) {
    135             throw new RSInvalidStateException("Object already destroyed.");
    136         }
    137         mDestroyed = true;
    138         mRS.nObjDestroy(mID);
    139     }
    140 
    141     /**
    142      * If an object came from an a3d file, java fields need to be
    143      * created with objects from the native layer
    144      */
    145     void updateFromNative() {
    146         mRS.validate();
    147         mName = mRS.nGetName(getID(mRS));
    148     }
    149 
    150     /**
    151      * Calculates the hash code value for a BaseObj.
    152      *
    153      * @return int
    154      */
    155     @Override
    156     public int hashCode() {
    157         return mID;
    158     }
    159 
    160     /**
    161      * Compare the current BaseObj with another BaseObj for equality.
    162      *
    163      * @param obj The object to check equality with.
    164      *
    165      * @return boolean
    166      */
    167     @Override
    168     public boolean equals(Object obj) {
    169         // Early-out check to see if both BaseObjs are actually the same
    170         if (this == obj)
    171             return true;
    172 
    173         if (getClass() != obj.getClass()) {
    174             return false;
    175         }
    176 
    177         BaseObj b = (BaseObj) obj;
    178         return mID == b.mID;
    179     }
    180 }
    181 
    182