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