198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams/*
298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * Copyright (C) 2012 The Android Open Source Project
398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams *
498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * you may not use this file except in compliance with the License.
698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * You may obtain a copy of the License at
798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams *
898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams *
1098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * Unless required by applicable law or agreed to in writing, software
1198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
1298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * See the License for the specific language governing permissions and
1498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * limitations under the License.
1598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams */
1698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
1798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Samspackage android.support.v8.renderscript;
1898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
1998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Samsimport android.util.Log;
2027250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murrayimport java.util.concurrent.locks.ReentrantReadWriteLock;
2198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
2298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams/**
237d435ae5ba100be5710b685653cc351cab159c11Stephen Hines * BaseObj is the base class for all RenderScript objects owned by a RS context.
247d435ae5ba100be5710b685653cc351cab159c11Stephen Hines * It is responsible for lifetime management and resource tracking. This class
257d435ae5ba100be5710b685653cc351cab159c11Stephen Hines * should not be used by a user application.
2698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams *
2798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams **/
2898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Samspublic class BaseObj {
293d9b60c9ae71c4c09df0b4e59c825a5d631e1254Miao Wang    BaseObj(long id, RenderScript rs) {
3098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        rs.validate();
3198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mRS = rs;
3298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mID = id;
3398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mDestroyed = false;
3498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
3598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
363d9b60c9ae71c4c09df0b4e59c825a5d631e1254Miao Wang    void setID(long id) {
3798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        if (mID != 0) {
3898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            throw new RSRuntimeException("Internal Error, reset of object ID.");
3998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
4098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mID = id;
4198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
4298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
4398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
4498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     * Lookup the native object ID for this object.  Primarily used by the
4598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     * generated reflected code.
4698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     *
4798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     * @param rs Context to verify against internal context for
4898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     *           match.
4998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     *
503d9b60c9ae71c4c09df0b4e59c825a5d631e1254Miao Wang     * @return long
5198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     */
523d9b60c9ae71c4c09df0b4e59c825a5d631e1254Miao Wang    long getID(RenderScript rs) {
5398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mRS.validate();
5498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        if (mDestroyed) {
5598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            throw new RSInvalidStateException("using a destroyed object.");
5698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
5798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        if (mID == 0) {
5898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            throw new RSRuntimeException("Internal error: Object id 0.");
5998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
6098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        if ((rs != null) && (rs != mRS)) {
6198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            throw new RSInvalidStateException("using object with mismatched context.");
6298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
6398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        return mID;
6498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
6598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
66ce8b0e674c93035013d1c33aaabc9bb6ceffde0fTim Murray    android.renderscript.BaseObj getNObj() {
67ce8b0e674c93035013d1c33aaabc9bb6ceffde0fTim Murray        return null;
68ce8b0e674c93035013d1c33aaabc9bb6ceffde0fTim Murray    }
69ce8b0e674c93035013d1c33aaabc9bb6ceffde0fTim Murray
7098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    void checkValid() {
71ce8b0e674c93035013d1c33aaabc9bb6ceffde0fTim Murray        if ((mID == 0) && (getNObj() == null)) {
7298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            throw new RSIllegalArgumentException("Invalid object.");
7398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
7498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
7598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
763d9b60c9ae71c4c09df0b4e59c825a5d631e1254Miao Wang    private long mID;
7798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    private boolean mDestroyed;
7898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    RenderScript mRS;
7998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
8027250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray    private void helpDestroy() {
8127250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray        boolean shouldDestroy = false;
8227250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray        synchronized(this) {
8327250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray            if (!mDestroyed) {
8427250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray                shouldDestroy = true;
8527250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray                mDestroyed = true;
8627250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray            }
8727250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray        }
8827250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray
8927250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray        if (shouldDestroy) {
9027250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray            // must include nObjDestroy in the critical section
9127250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray            ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock();
9227250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray            rlock.lock();
9327250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray            if(mRS.isAlive()) {
9498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                mRS.nObjDestroy(mID);
9598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            }
9627250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray            rlock.unlock();
9798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            mRS = null;
9898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            mID = 0;
9998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
10027250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray    }
10127250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray
10227250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray
10327250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray    protected void finalize() throws Throwable {
10427250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray        helpDestroy();
10598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        super.finalize();
10698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
10798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
10898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
1097d435ae5ba100be5710b685653cc351cab159c11Stephen Hines     * Frees any native resources associated with this object.  The
1107d435ae5ba100be5710b685653cc351cab159c11Stephen Hines     * primary use is to force immediate cleanup of resources when it is
1117d435ae5ba100be5710b685653cc351cab159c11Stephen Hines     * believed the GC will not respond quickly enough.
11298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     */
11327250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray    public void destroy() {
11498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        if(mDestroyed) {
11598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            throw new RSInvalidStateException("Object already destroyed.");
11698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
11727250e121155f570d1d0db7a1b09fcbaa1361aa4Tim Murray        helpDestroy();
11898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
11998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
12098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
12198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     * Calculates the hash code value for a BaseObj.
12298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     *
12398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     * @return int
12498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     */
12598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    @Override
12698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public int hashCode() {
1273d9b60c9ae71c4c09df0b4e59c825a5d631e1254Miao Wang        return (int)((mID & 0xfffffff) ^ (mID >> 32));
12898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
12998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
13098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
13198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     * Compare the current BaseObj with another BaseObj for equality.
13298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     *
13398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     * @param obj The object to check equality with.
13498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     *
13598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     * @return boolean
13698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams     */
13798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    @Override
13898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public boolean equals(Object obj) {
13998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        // Early-out check to see if both BaseObjs are actually the same
14098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        if (this == obj)
14198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            return true;
14298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
1438b33529b03912efab1aedd30ca5bd818ddbe3713Tim Murray        if (obj == null) {
1448b33529b03912efab1aedd30ca5bd818ddbe3713Tim Murray            return false;
1458b33529b03912efab1aedd30ca5bd818ddbe3713Tim Murray        }
1468b33529b03912efab1aedd30ca5bd818ddbe3713Tim Murray
14798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        if (getClass() != obj.getClass()) {
14898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            return false;
14998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
15098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
15198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        BaseObj b = (BaseObj) obj;
15298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        return mID == b.mID;
15398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
15498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams}
15598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
156