ScriptGroup.java revision 423ebcb4dc4881c3a83e8121d5212466287d0d0c
1423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams/*
2423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * Copyright (C) 2012 The Android Open Source Project
3423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams *
4423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * you may not use this file except in compliance with the License.
6423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * You may obtain a copy of the License at
7423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams *
8423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams *
10423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * Unless required by applicable law or agreed to in writing, software
11423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * See the License for the specific language governing permissions and
14423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * limitations under the License.
15423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams */
16423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
17423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Samspackage android.renderscript;
18423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
19423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Samsimport java.lang.reflect.Method;
20423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
21423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams/**
22423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams * @hide
23423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams **/
24423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Samspublic class ScriptGroup extends BaseObj {
25423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    Node mNodes[];
26423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    Connection mConnections[];
27423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    Node mFirstNode;
28423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    IO mOutputs[];
29423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    IO mInputs[];
30423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
31423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    static class IO {
32423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Script mScript;
33423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Allocation mAllocation;
34423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        String mName;
35423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
36423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        IO(Script s) {
37423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mScript = s;
38423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
39423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        IO(Script s, String n) {
40423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mScript = s;
41423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mName = n;
42423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
43423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
44423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
45423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    static class Connection {
46423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Node mTo[];
47423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        String mToName[];
48423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Node mFrom;
49423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Type mAllocationType;
50423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Allocation mInternalAllocation;
51423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
52423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Connection(Node out, Type t) {
53423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mFrom = out;
54423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mAllocationType = t;
55423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
56423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
57423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        void addTo(Node n, String name) {
58423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            if (mTo == null) {
59423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mTo = new Node[1];
60423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mToName = new String[1];
61423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            } else {
62423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                Node nt[] = new Node[mTo.length + 1];
63423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                String ns[] = new String[mTo.length + 1];
64423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                System.arraycopy(mTo, 0, nt, 0, mTo.length);
65423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                System.arraycopy(mToName, 0, ns, 0, mTo.length);
66423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mTo = nt;
67423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mToName = ns;
68423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
69423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mTo[mTo.length - 1] = n;
70423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mToName[mTo.length - 1] = name;
71423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
72423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
73423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
74423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    static class Node {
75423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Script mScript;
76423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Connection mInput[] = new Connection[8];
77423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Connection mOutput[] = new Connection[1];
78423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        int mInputCount;
79423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        int mOutputCount;
80423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        int mDepth;
81423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        boolean mSeen;
82423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
83423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Node mNext;
84423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
85423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Node(Script s) {
86423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mScript = s;
87423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
88423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
89423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        void addInput(Connection c) {
90423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            if (mInput.length <= mInputCount) {
91423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                Connection[] nc = new Connection[mInput.length + 8];
92423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                System.arraycopy(mInput, 0, nc, 0, mInputCount);
93423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mInput = nc;
94423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
95423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mInput[mInputCount++] = c;
96423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
97423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
98423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        void addOutput(Connection c) {
99423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            if (mOutput.length <= mOutputCount) {
100423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                Connection[] nc = new Connection[mOutput.length + 8];
101423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                System.arraycopy(mOutput, 0, nc, 0, mOutputCount);
102423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mOutput = nc;
103423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
104423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mOutput[mOutputCount++] = c;
105423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
106423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
107423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
108423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
109423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    ScriptGroup(int id, RenderScript rs) {
110423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        super(id, rs);
111423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
112423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
113423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    void init(int nodeCount, int connectionCount) {
114423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        mNodes = new Node[nodeCount];
115423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        mConnections = new Connection[connectionCount];
116423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
117423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        android.util.Log.v("RSR", "init" + nodeCount + ", " + connectionCount);
118423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
119423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        // Count outputs and create array.
120423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Node n = mFirstNode;
121423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        int outputCount = 0;
122423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        int inputCount = 0;
123423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        int connectionIndex = 0;
124423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        int nodeNum = 0;
125423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        while (n != null) {
126423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mNodes[nodeNum++] = n;
127423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
128423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            // Look for unattached kernel inputs
129423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            boolean hasInput = false;
130423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            for (int ct=0; ct < n.mInput.length; ct++) {
131423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                if (n.mInput[ct] != null) {
132423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    if (n.mInput[ct].mToName == null) {
133423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        hasInput = true;
134423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    }
135423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
136423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
137423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            if (!hasInput) {
138423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                if (mInputs == null) {
139423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    mInputs = new IO[1];
140423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
141423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                if (mInputs.length <= inputCount) {
142423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    IO t[] = new IO[mInputs.length + 1];
143423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    System.arraycopy(mInputs, 0, t, 0, mInputs.length);
144423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    mInputs = t;
145423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
146423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mInputs[inputCount++] = new IO(n.mScript);
147423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
148423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
149423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            // Look for unattached kernel outputs
150423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            boolean hasOutput = false;
151423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            for (int ct=0; ct < n.mOutput.length; ct++) {
152423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                if (n.mOutput[ct] != null) {
153423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    hasOutput = true;
154423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
155423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
156423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            if (!hasOutput) {
157423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                if (mOutputs == null) {
158423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    mOutputs = new IO[1];
159423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
160423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                if (mOutputs.length <= outputCount) {
161423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    IO t[] = new IO[mOutputs.length + 1];
162423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    System.arraycopy(mOutputs, 0, t, 0, mOutputs.length);
163423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    mOutputs = t;
164423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
165423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mOutputs[outputCount++] = new IO(n.mScript);
166423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
167423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
168423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            // Make allocations for internal connections
169423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            // Since script outputs are unique, use those to avoid duplicates.
170423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            for (int ct=0; ct < n.mOutput.length; ct++) {
171423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                android.util.Log.v("RSR", "init out2 " + n.mOutput[ct]);
172423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                if (n.mOutput[ct] != null) {
173423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    Connection t = n.mOutput[ct];
174423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    mConnections[connectionIndex++] = t;
175423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    t.mInternalAllocation = Allocation.createTyped(mRS, t.mAllocationType);
176423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
177423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
178423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
179423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            n = n.mNext;
180423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
181423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
182423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
183423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    public void setInput(Script s, Allocation a) {
184423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        for (int ct=0; ct < mInputs.length; ct++) {
185423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            if (mInputs[ct].mScript == s) {
186423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mInputs[ct].mAllocation = a;
187423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                return;
188423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
189423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
190423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        throw new RSIllegalArgumentException("Script not found");
191423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
192423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
193423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    public void setOutput(Script s, Allocation a) {
194423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        for (int ct=0; ct < mOutputs.length; ct++) {
195423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            if (mOutputs[ct].mScript == s) {
196423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mOutputs[ct].mAllocation = a;
197423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                return;
198423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
199423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
200423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        throw new RSIllegalArgumentException("Script not found");
201423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
202423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
203423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    public void execute() {
204423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        android.util.Log.v("RSR", "execute");
205423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        boolean more = true;
206423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        int depth = 0;
207423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        while (more) {
208423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            more = false;
209423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            for (int ct=0; ct < mNodes.length; ct++) {
210423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                if (mNodes[ct].mDepth == depth) {
211423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    more = true;
212423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
213423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    Allocation kernelIn = null;
214423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    for (int ct2=0; ct2 < mNodes[ct].mInputCount; ct2++) {
215423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        android.util.Log.v("RSR", " kin " + ct2 + ", to " + mNodes[ct].mInput[ct2].mTo[0] + ", name " + mNodes[ct].mInput[ct2].mToName[0]);
216423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        if (mNodes[ct].mInput[ct2].mToName[0] == null) {
217423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                            kernelIn = mNodes[ct].mInput[ct2].mInternalAllocation;
218423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                            break;
219423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        }
220423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    }
221423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
222423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    Allocation kernelOut= null;
223423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    for (int ct2=0; ct2 < mNodes[ct].mOutputCount; ct2++) {
224423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        android.util.Log.v("RSR", " kout " + ct2 + ", from " + mNodes[ct].mOutput[ct2].mFrom);
225423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        if (mNodes[ct].mOutput[ct2].mFrom != null) {
226423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                            kernelOut = mNodes[ct].mOutput[ct2].mInternalAllocation;
227423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                            break;
228423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        }
229423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    }
230423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    if (kernelOut == null) {
231423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        for (int ct2=0; ct2 < mOutputs.length; ct2++) {
232423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                            if (mOutputs[ct2].mScript == mNodes[ct].mScript) {
233423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                                kernelOut = mOutputs[ct2].mAllocation;
234423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                                break;
235423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                            }
236423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        }
237423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    }
238423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
239423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    android.util.Log.v("RSR", "execute calling " + mNodes[ct] + ", with " + kernelIn);
240423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    if (kernelIn != null) {
241423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        try {
242423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
243423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                            Method m = mNodes[ct].mScript.getClass().getMethod("forEach_root",
244423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                                          new Class[] { Allocation.class, Allocation.class });
245423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                            m.invoke(mNodes[ct].mScript, new Object[] {kernelIn, kernelOut} );
246423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        } catch (Throwable t) {
247423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                            android.util.Log.e("RSR", "execute error " + t);
248423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        }
249423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    } else {
250423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        try {
251423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                            Method m = mNodes[ct].mScript.getClass().getMethod("forEach_root",
252423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                                          new Class[] { Allocation.class });
253423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                            m.invoke(mNodes[ct].mScript, new Object[] {kernelOut} );
254423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        } catch (Throwable t) {
255423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                            android.util.Log.e("RSR", "execute error " + t);
256423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        }
257423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    }
258423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
259423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
260423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
261423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            depth ++;
262423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
263423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
264423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
265423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
266423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
267423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    public static class Builder {
268423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        RenderScript mRS;
269423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        Node mFirstNode;
270423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        int mConnectionCount = 0;
271423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        int mNodeCount = 0;
272423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
273423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        public Builder(RenderScript rs) {
274423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mRS = rs;
275423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
276423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
277423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        private void validateRecurse(Node n, int depth) {
278423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            n.mSeen = true;
279423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            if (depth > n.mDepth) {
280423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                n.mDepth = depth;
281423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
282423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
283423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            android.util.Log.v("RSR", " validateRecurse outputCount " + n.mOutputCount);
284423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            for (int ct=0; ct < n.mOutputCount; ct++) {
285423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                for (int ct2=0; ct2 < n.mOutput[ct].mTo.length; ct2++) {
286423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    if (n.mOutput[ct].mTo[ct2].mSeen) {
287423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        throw new RSInvalidStateException("Loops in group not allowed.");
288423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    }
289423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    validateRecurse(n.mOutput[ct].mTo[ct2], depth + 1);
290423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
291423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
292423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
293423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
294423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        private void validate() {
295423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            android.util.Log.v("RSR", "validate");
296423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            Node n = mFirstNode;
297423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            while (n != null) {
298423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                n.mSeen = false;
299423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                n.mDepth = 0;
300423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                n = n.mNext;
301423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
302423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
303423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            n = mFirstNode;
304423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            while (n != null) {
305423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                android.util.Log.v("RSR", "validate n= " + n);
306423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                if ((n.mSeen == false) && (n.mInputCount == 0)) {
307423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    android.util.Log.v("RSR", " recursing " + n);
308423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    validateRecurse(n, 0);
309423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
310423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                n = n.mNext;
311423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
312423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
313423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
314423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        private Node findScript(Script s) {
315423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            Node n = mFirstNode;
316423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            while (n != null) {
317423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                if (n.mScript == s) {
318423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    return n;
319423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
320423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                n = n.mNext;
321423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
322423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            return null;
323423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
324423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
325423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        private void addNode(Node n) {
326423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            n.mNext = mFirstNode;
327423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mFirstNode = n;
328423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
329423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
330423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        public Builder addConnection(Type t, Script output, Script input, String inputName) {
331423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            android.util.Log.v("RSR", "addConnection " + t +", " + output + ", " + input);
332423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
333423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            // Look for existing output
334423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            Node nout = findScript(output);
335423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            Connection c;
336423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            if (nout == null) {
337423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                // Make new node
338423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                android.util.Log.v("RSR", "addConnection new output node");
339423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                nout = new Node(output);
340423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mNodeCount++;
341423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                c = new Connection(nout, t);
342423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mConnectionCount++;
343423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                nout.addOutput(c);
344423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                addNode(nout);
345423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            } else {
346423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                // Add to existing node
347423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                android.util.Log.v("RSR", "addConnection reuse output node");
348423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                if (nout.mOutput[0] != null) {
349423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    if (nout.mOutput[0].mFrom.mScript != output) {
350423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        throw new RSInvalidStateException("Changed output of existing node");
351423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    }
352423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    if (nout.mOutput[0].mAllocationType != t) {
353423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                        throw new RSInvalidStateException("Changed output type of existing node");
354423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                    }
355423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                }
356423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                c = nout.mOutput[0];
357423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
358423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            // At this point we should have a connection attached to a script ouput.
359423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
360423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            // Find input
361423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            Node nin = findScript(input);
362423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            if (nin == null) {
363423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                android.util.Log.v("RSR", "addConnection new input node");
364423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                nin = new Node(input);
365423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                mNodeCount++;
366423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams                addNode(nin);
367423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            }
368423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            c.addTo(nin, inputName);
369423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            nin.addInput(c);
370423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
371423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            validate();
372423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            return this;
373423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
374423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
375423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        public ScriptGroup create() {
376423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            ScriptGroup sg = new ScriptGroup(0, mRS);
377423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            sg.mFirstNode = mFirstNode;
378423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            mFirstNode = null;
379423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
380423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            android.util.Log.v("RSR", "create nodes= " + mNodeCount + ", Connections= " + mConnectionCount);
381423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
382423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            sg.init(mNodeCount, mConnectionCount);
383423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams            return sg;
384423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams        }
385423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
386423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams    }
387423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
388423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
389423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams}
390423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
391423ebcb4dc4881c3a83e8121d5212466287d0d0cJason Sams
392