Script.java revision 8919a441f977cb787d244aa42cc2d4dda1cbfa11
1/*
2 * Copyright (C) 2012 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
17package android.support.v8.renderscript;
18
19import android.util.SparseArray;
20
21/**
22 * The parent class for all executable scripts. This should not be used by
23 * applications.
24 **/
25public class Script extends BaseObj {
26    /**
27     * Determine if Incremental Intrinsic Support is needed
28     *
29     */
30    private boolean mUseIncSupp;
31    protected void setIncSupp(boolean useInc) {
32        mUseIncSupp = useInc;
33    }
34    protected boolean isIncSupp() {
35        return mUseIncSupp;
36    }
37    /**
38     * An allocation for the compat context will be created when needed
39     * e.g. foreach(ain, aout), setVar(ain);
40     *
41     */
42    long getDummyAlloc(Allocation ain) {
43        long dInElement = 0;
44        long dInType = 0;
45        long dummyAlloc = 0;
46        if (ain != null) {
47            dInElement = ain.getType().getElement().getDummyElement(mRS);
48            dInType = ain.getType().getDummyType(mRS, dInElement);
49            dummyAlloc = mRS.nIncAllocationCreateTyped(ain.getID(mRS), dInType);
50            ain.setIncAllocID(dummyAlloc);
51        }
52
53        return dummyAlloc;
54    }
55    /**
56     * KernelID is an identifier for a Script + root function pair. It is used
57     * as an identifier for ScriptGroup creation.
58     *
59     * This class should not be directly created. Instead use the method in the
60     * reflected or intrinsic code "getKernelID_funcname()".
61     *
62     */
63    public static final class KernelID extends BaseObj {
64        android.renderscript.Script.KernelID mN;
65        Script mScript;
66        int mSlot;
67        int mSig;
68        KernelID(long id, RenderScript rs, Script s, int slot, int sig) {
69            super(id, rs);
70            mScript = s;
71            mSlot = slot;
72            mSig = sig;
73        }
74    }
75
76    private final SparseArray<KernelID> mKIDs = new SparseArray<KernelID>();
77    /**
78     * Only to be used by generated reflected classes.
79     *
80     *
81     * @param slot
82     * @param sig
83     * @param ein
84     * @param eout
85     *
86     * @return KernelID
87     */
88    protected KernelID createKernelID(int slot, int sig, Element ein, Element eout) {
89        KernelID k = mKIDs.get(slot);
90        if (k != null) {
91            return k;
92        }
93
94        long id = mRS.nScriptKernelIDCreate(getID(mRS), slot, sig, mUseIncSupp);
95        if (id == 0) {
96            throw new RSDriverException("Failed to create KernelID");
97        }
98
99        k = new KernelID(id, mRS, this, slot, sig);
100
101        mKIDs.put(slot, k);
102        return k;
103    }
104
105    /**
106     * InvokeID is an identifier for a invoke function. It is used
107     * as an identifier for ScriptGroup creation.
108     *
109     * This class should not be directly created. Instead use the method in the
110     * reflected or intrinsic code "getInvokeID_funcname()".
111     *
112     * @hide
113     */
114    public static final class InvokeID extends BaseObj {
115        Script mScript;
116        int mSlot;
117        InvokeID(long id, RenderScript rs, Script s, int slot) {
118            super(id, rs);
119            mScript = s;
120            mSlot = slot;
121        }
122    }
123
124    private final SparseArray<InvokeID> mIIDs = new SparseArray<InvokeID>();
125    /**
126     * Only to be used by generated reflected classes.
127     */
128    protected InvokeID createInvokeID(int slot) {
129        InvokeID i = mIIDs.get(slot);
130        if (i != null) {
131            return i;
132        }
133
134        long id = mRS.nScriptInvokeIDCreate(getID(mRS), slot);
135        if (id == 0) {
136            throw new RSDriverException("Failed to create KernelID");
137        }
138
139        i = new InvokeID(id, mRS, this, slot);
140        mIIDs.put(slot, i);
141        return i;
142    }
143
144    /**
145     * FieldID is an identifier for a Script + exported field pair. It is used
146     * as an identifier for ScriptGroup creation.
147     *
148     * This class should not be directly created. Instead use the method in the
149     * reflected or intrinsic code "getFieldID_funcname()".
150     *
151     */
152    public static final class FieldID extends BaseObj {
153        android.renderscript.Script.FieldID mN;
154        Script mScript;
155        int mSlot;
156        FieldID(long id, RenderScript rs, Script s, int slot) {
157            super(id, rs);
158            mScript = s;
159            mSlot = slot;
160        }
161    }
162
163    private final SparseArray<FieldID> mFIDs = new SparseArray();
164    /**
165     * Only to be used by generated reflected classes.
166     *
167     * @param slot
168     * @param e
169     *
170     * @return FieldID
171     */
172    protected FieldID createFieldID(int slot, Element e) {
173        FieldID f = mFIDs.get(slot);
174        if (f != null) {
175            return f;
176        }
177
178        long id = mRS.nScriptFieldIDCreate(getID(mRS), slot, mUseIncSupp);
179        if (id == 0) {
180            throw new RSDriverException("Failed to create FieldID");
181        }
182
183        f = new FieldID(id, mRS, this, slot);
184        mFIDs.put(slot, f);
185        return f;
186    }
187
188    /**
189     * Only intended for use by generated reflected code.
190     *
191     * @param slot
192     */
193    protected void invoke(int slot) {
194        mRS.nScriptInvoke(getID(mRS), slot, mUseIncSupp);
195    }
196
197    /**
198     * Only intended for use by generated reflected code.
199     *
200     * @param slot
201     * @param v
202     */
203    protected void invoke(int slot, FieldPacker v) {
204        if (v != null) {
205            mRS.nScriptInvokeV(getID(mRS), slot, v.getData(), mUseIncSupp);
206        } else {
207            mRS.nScriptInvoke(getID(mRS), slot, mUseIncSupp);
208        }
209    }
210
211    /**
212     * Only intended for use by generated reflected code.
213     *
214     * @param va
215     * @param slot
216     */
217    public void bindAllocation(Allocation va, int slot) {
218        mRS.validate();
219        if (va != null) {
220            mRS.nScriptBindAllocation(getID(mRS), va.getID(mRS), slot, mUseIncSupp);
221        } else {
222            mRS.nScriptBindAllocation(getID(mRS), 0, slot, mUseIncSupp);
223        }
224    }
225
226    public void setTimeZone(String timeZone) {
227        mRS.validate();
228        try {
229            mRS.nScriptSetTimeZone(getID(mRS), timeZone.getBytes("UTF-8"), mUseIncSupp);
230        } catch (java.io.UnsupportedEncodingException e) {
231            throw new RuntimeException(e);
232        }
233    }
234
235
236    /**
237     * Only intended for use by generated reflected code.
238     *
239     * @param slot
240     * @param ain
241     * @param aout
242     * @param v
243     */
244    protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v) {
245        if (ain == null && aout == null) {
246            throw new RSIllegalArgumentException(
247                "At least one of ain or aout is required to be non-null.");
248        }
249        long in_id = 0;
250        long out_id = 0;
251        if (ain != null) {
252            in_id = ain.getID(mRS);
253        }
254        if (aout != null) {
255            out_id = aout.getID(mRS);
256        }
257
258        byte[] params = null;
259        if (v != null) {
260            params = v.getData();
261        }
262
263        if (mUseIncSupp) {
264            long ainInc = getDummyAlloc(ain);
265            long aoutInc = getDummyAlloc(aout);
266            mRS.nScriptForEach(getID(mRS), slot, ainInc, aoutInc, params, mUseIncSupp);
267        } else {
268            mRS.nScriptForEach(getID(mRS), slot, in_id, out_id, params, mUseIncSupp);
269        }
270    }
271
272    /**
273     * Only intended for use by generated reflected code.
274     *
275     * @param slot
276     * @param ain
277     * @param aout
278     * @param v
279     * @param sc
280     */
281    protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v, LaunchOptions sc) {
282        if (ain == null && aout == null) {
283            throw new RSIllegalArgumentException(
284                "At least one of ain or aout is required to be non-null.");
285        }
286
287        if (sc == null) {
288            forEach(slot, ain, aout, v);
289            return;
290        }
291        long in_id = 0;
292        long out_id = 0;
293        if (ain != null) {
294            in_id = ain.getID(mRS);
295        }
296        if (aout != null) {
297            out_id = aout.getID(mRS);
298        }
299
300        byte[] params = null;
301        if (v != null) {
302            params = v.getData();
303        }
304        if (mUseIncSupp) {
305            long ainInc = getDummyAlloc(ain);
306            long aoutInc = getDummyAlloc(aout);
307            mRS.nScriptForEachClipped(getID(mRS), slot, ainInc, aoutInc, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend, mUseIncSupp);
308        } else {
309            mRS.nScriptForEachClipped(getID(mRS), slot, in_id, out_id, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend, mUseIncSupp);
310        }
311    }
312
313    Script(long id, RenderScript rs) {
314        super(id, rs);
315        mUseIncSupp = false;
316    }
317
318    /**
319     * Only intended for use by generated reflected code.
320     *
321     * @param index
322     * @param v
323     */
324    public void setVar(int index, float v) {
325        mRS.nScriptSetVarF(getID(mRS), index, v, mUseIncSupp);
326    }
327
328    /**
329     * Only intended for use by generated reflected code.
330     *
331     * @param index
332     * @param v
333     */
334    public void setVar(int index, double v) {
335        mRS.nScriptSetVarD(getID(mRS), index, v, mUseIncSupp);
336    }
337
338    /**
339     * Only intended for use by generated reflected code.
340     *
341     * @param index
342     * @param v
343     */
344    public void setVar(int index, int v) {
345        mRS.nScriptSetVarI(getID(mRS), index, v, mUseIncSupp);
346    }
347
348    /**
349     * Only intended for use by generated reflected code.
350     *
351     * @param index
352     * @param v
353     */
354    public void setVar(int index, long v) {
355        mRS.nScriptSetVarJ(getID(mRS), index, v, mUseIncSupp);
356    }
357
358    /**
359     * Only intended for use by generated reflected code.
360     *
361     * @param index
362     * @param v
363     */
364    public void setVar(int index, boolean v) {
365        mRS.nScriptSetVarI(getID(mRS), index, v ? 1 : 0, mUseIncSupp);
366    }
367
368    /**
369     * Only intended for use by generated reflected code.
370     *
371     * @param index
372     * @param o
373     */
374    public void setVar(int index, BaseObj o) {
375        if (mUseIncSupp) {
376            long oInc = getDummyAlloc((Allocation)o);
377            mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : oInc, mUseIncSupp);
378        } else {
379            mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : o.getID(mRS), mUseIncSupp);
380        }
381    }
382
383    /**
384     * Only intended for use by generated reflected code.
385     *
386     * @param index
387     * @param v
388     */
389    public void setVar(int index, FieldPacker v) {
390        mRS.nScriptSetVarV(getID(mRS), index, v.getData(), mUseIncSupp);
391    }
392
393    /**
394     * Only intended for use by generated reflected code.
395     *
396     * @param index
397     * @param v
398     * @param e
399     * @param dims
400     */
401    public void setVar(int index, FieldPacker v, Element e, int[] dims) {
402        if (mUseIncSupp) {
403            long dElement = e.getDummyElement(mRS);
404            mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), dElement, dims, mUseIncSupp);
405        } else {
406            mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), e.getID(mRS), dims, mUseIncSupp);
407        }
408    }
409
410    /**
411     * Only intended for use by generated reflected code.
412     *
413     */
414    public static class Builder {
415        RenderScript mRS;
416
417        Builder(RenderScript rs) {
418            mRS = rs;
419        }
420    }
421
422
423    /**
424     * Only intended for use by generated reflected code.
425     *
426     */
427    public static class FieldBase {
428        protected Element mElement;
429        protected Allocation mAllocation;
430
431        protected void init(RenderScript rs, int dimx) {
432            mAllocation = Allocation.createSized(rs, mElement, dimx, Allocation.USAGE_SCRIPT);
433        }
434
435        protected void init(RenderScript rs, int dimx, int usages) {
436            mAllocation = Allocation.createSized(rs, mElement, dimx, Allocation.USAGE_SCRIPT | usages);
437        }
438
439        protected FieldBase() {
440        }
441
442        public Element getElement() {
443            return mElement;
444        }
445
446        public Type getType() {
447            return mAllocation.getType();
448        }
449
450        public Allocation getAllocation() {
451            return mAllocation;
452        }
453
454        //@Override
455        public void updateAllocation() {
456        }
457    }
458
459
460    /**
461     * Class used to specify clipping for a kernel launch.
462     *
463     */
464    public static final class LaunchOptions {
465        private int xstart = 0;
466        private int ystart = 0;
467        private int xend = 0;
468        private int yend = 0;
469        private int zstart = 0;
470        private int zend = 0;
471        private int strategy;
472
473        /**
474         * Set the X range.  If the end value is set to 0 the X dimension is not
475         * clipped.
476         *
477         * @param xstartArg Must be >= 0
478         * @param xendArg Must be >= xstartArg
479         *
480         * @return LaunchOptions
481         */
482        public LaunchOptions setX(int xstartArg, int xendArg) {
483            if (xstartArg < 0 || xendArg <= xstartArg) {
484                throw new RSIllegalArgumentException("Invalid dimensions");
485            }
486            xstart = xstartArg;
487            xend = xendArg;
488            return this;
489        }
490
491        /**
492         * Set the Y range.  If the end value is set to 0 the Y dimension is not
493         * clipped.
494         *
495         * @param ystartArg Must be >= 0
496         * @param yendArg Must be >= ystartArg
497         *
498         * @return LaunchOptions
499         */
500        public LaunchOptions setY(int ystartArg, int yendArg) {
501            if (ystartArg < 0 || yendArg <= ystartArg) {
502                throw new RSIllegalArgumentException("Invalid dimensions");
503            }
504            ystart = ystartArg;
505            yend = yendArg;
506            return this;
507        }
508
509        /**
510         * Set the Z range.  If the end value is set to 0 the Z dimension is not
511         * clipped.
512         *
513         * @param zstartArg Must be >= 0
514         * @param zendArg Must be >= zstartArg
515         *
516         * @return LaunchOptions
517         */
518        public LaunchOptions setZ(int zstartArg, int zendArg) {
519            if (zstartArg < 0 || zendArg <= zstartArg) {
520                throw new RSIllegalArgumentException("Invalid dimensions");
521            }
522            zstart = zstartArg;
523            zend = zendArg;
524            return this;
525        }
526
527
528        /**
529         * Returns the current X start
530         *
531         * @return int current value
532         */
533        public int getXStart() {
534            return xstart;
535        }
536        /**
537         * Returns the current X end
538         *
539         * @return int current value
540         */
541        public int getXEnd() {
542            return xend;
543        }
544        /**
545         * Returns the current Y start
546         *
547         * @return int current value
548         */
549        public int getYStart() {
550            return ystart;
551        }
552        /**
553         * Returns the current Y end
554         *
555         * @return int current value
556         */
557        public int getYEnd() {
558            return yend;
559        }
560        /**
561         * Returns the current Z start
562         *
563         * @return int current value
564         */
565        public int getZStart() {
566            return zstart;
567        }
568        /**
569         * Returns the current Z end
570         *
571         * @return int current value
572         */
573        public int getZEnd() {
574            return zend;
575        }
576
577    }
578}
579