• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008-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 
17 package android.renderscript;
18 
19 import android.util.SparseArray;
20 
21 /**
22  * The parent class for all executable scripts. This should not be used by
23  * applications.
24  **/
25 public class Script extends BaseObj {
26 
27     /**
28      * KernelID is an identifier for a Script + root function pair. It is used
29      * as an identifier for ScriptGroup creation.
30      *
31      * This class should not be directly created. Instead use the method in the
32      * reflected or intrinsic code "getKernelID_funcname()".
33      *
34      */
35     public static final class KernelID extends BaseObj {
36         Script mScript;
37         int mSlot;
38         int mSig;
KernelID(long id, RenderScript rs, Script s, int slot, int sig)39         KernelID(long id, RenderScript rs, Script s, int slot, int sig) {
40             super(id, rs);
41             mScript = s;
42             mSlot = slot;
43             mSig = sig;
44             guard.open("destroy");
45         }
46     }
47 
48     private final SparseArray<KernelID> mKIDs = new SparseArray<KernelID>();
49     /**
50      * Only to be used by generated reflected classes.
51      */
createKernelID(int slot, int sig, Element ein, Element eout)52     protected KernelID createKernelID(int slot, int sig, Element ein,
53                                       Element eout) {
54         KernelID k = mKIDs.get(slot);
55         if (k != null) {
56             return k;
57         }
58 
59         long id = mRS.nScriptKernelIDCreate(getID(mRS), slot, sig);
60         if (id == 0) {
61             throw new RSDriverException("Failed to create KernelID");
62         }
63 
64         k = new KernelID(id, mRS, this, slot, sig);
65         mKIDs.put(slot, k);
66         return k;
67     }
68 
69     /**
70      * InvokeID is an identifier for an invoke function. It is used
71      * as an identifier for ScriptGroup creation.
72      *
73      * This class should not be directly created. Instead use the method in the
74      * reflected or intrinsic code "getInvokeID_funcname()".
75      *
76      */
77     public static final class InvokeID extends BaseObj {
78         Script mScript;
79         int mSlot;
InvokeID(long id, RenderScript rs, Script s, int slot)80         InvokeID(long id, RenderScript rs, Script s, int slot) {
81             super(id, rs);
82             mScript = s;
83             mSlot = slot;
84         }
85     }
86 
87     private final SparseArray<InvokeID> mIIDs = new SparseArray<InvokeID>();
88     /**
89      * Only to be used by generated reflected classes.
90      */
createInvokeID(int slot)91     protected InvokeID createInvokeID(int slot) {
92         InvokeID i = mIIDs.get(slot);
93         if (i != null) {
94             return i;
95         }
96 
97         long id = mRS.nScriptInvokeIDCreate(getID(mRS), slot);
98         if (id == 0) {
99             throw new RSDriverException("Failed to create KernelID");
100         }
101 
102         i = new InvokeID(id, mRS, this, slot);
103         mIIDs.put(slot, i);
104         return i;
105     }
106 
107     /**
108      * FieldID is an identifier for a Script + exported field pair. It is used
109      * as an identifier for ScriptGroup creation.
110      *
111      * This class should not be directly created. Instead use the method in the
112      * reflected or intrinsic code "getFieldID_funcname()".
113      *
114      */
115     public static final class FieldID extends BaseObj {
116         Script mScript;
117         int mSlot;
FieldID(long id, RenderScript rs, Script s, int slot)118         FieldID(long id, RenderScript rs, Script s, int slot) {
119             super(id, rs);
120             mScript = s;
121             mSlot = slot;
122             guard.open("destroy");
123         }
124     }
125 
126     private final SparseArray<FieldID> mFIDs = new SparseArray();
127     /**
128      * Only to be used by generated reflected classes.
129      */
createFieldID(int slot, Element e)130     protected FieldID createFieldID(int slot, Element e) {
131         FieldID f = mFIDs.get(slot);
132         if (f != null) {
133             return f;
134         }
135 
136         long id = mRS.nScriptFieldIDCreate(getID(mRS), slot);
137         if (id == 0) {
138             throw new RSDriverException("Failed to create FieldID");
139         }
140 
141         f = new FieldID(id, mRS, this, slot);
142         mFIDs.put(slot, f);
143         return f;
144     }
145 
146 
147     /**
148      * Only intended for use by generated reflected code.
149      *
150      */
invoke(int slot)151     protected void invoke(int slot) {
152         mRS.nScriptInvoke(getID(mRS), slot);
153     }
154 
155     /**
156      * Only intended for use by generated reflected code.
157      *
158      */
invoke(int slot, FieldPacker v)159     protected void invoke(int slot, FieldPacker v) {
160         if (v != null) {
161             mRS.nScriptInvokeV(getID(mRS), slot, v.getData());
162         } else {
163             mRS.nScriptInvoke(getID(mRS), slot);
164         }
165     }
166 
167     /**
168      * Only intended for use by generated reflected code.
169      *
170      */
forEach(int slot, Allocation ain, Allocation aout, FieldPacker v)171     protected void forEach(int slot, Allocation ain, Allocation aout,
172                            FieldPacker v) {
173         forEach(slot, ain, aout, v, null);
174     }
175 
176     /**
177      * Only intended for use by generated reflected code.
178      *
179      */
forEach(int slot, Allocation ain, Allocation aout, FieldPacker v, LaunchOptions sc)180     protected void forEach(int slot, Allocation ain, Allocation aout,
181                            FieldPacker v, LaunchOptions sc) {
182         // TODO: Is this necessary if nScriptForEach calls validate as well?
183         mRS.validate();
184         mRS.validateObject(ain);
185         mRS.validateObject(aout);
186 
187         if (ain == null && aout == null && sc == null) {
188             throw new RSIllegalArgumentException(
189                 "At least one of input allocation, output allocation, or LaunchOptions is required to be non-null.");
190         }
191 
192         long[] in_ids = null;
193         if (ain != null) {
194             in_ids    = mInIdsBuffer;
195             in_ids[0] = ain.getID(mRS);
196         }
197 
198         long out_id = 0;
199         if (aout != null) {
200             out_id = aout.getID(mRS);
201         }
202 
203         byte[] params = null;
204         if (v != null) {
205             params = v.getData();
206         }
207 
208         int[] limits = null;
209         if (sc != null) {
210             limits = new int[6];
211 
212             limits[0] = sc.xstart;
213             limits[1] = sc.xend;
214             limits[2] = sc.ystart;
215             limits[3] = sc.yend;
216             limits[4] = sc.zstart;
217             limits[5] = sc.zend;
218         }
219 
220         mRS.nScriptForEach(getID(mRS), slot, in_ids, out_id, params, limits);
221     }
222 
223     /**
224      * Only intended for use by generated reflected code.
225      */
forEach(int slot, Allocation[] ains, Allocation aout, FieldPacker v)226     protected void forEach(int slot, Allocation[] ains, Allocation aout,
227                            FieldPacker v) {
228 
229         // FieldPacker is kept here to support regular params in the future.
230         forEach(slot, ains, aout, v, null);
231     }
232 
233     /**
234      * Only intended for use by generated reflected code.
235      */
forEach(int slot, Allocation[] ains, Allocation aout, FieldPacker v, LaunchOptions sc)236     protected void forEach(int slot, Allocation[] ains, Allocation aout,
237                            FieldPacker v, LaunchOptions sc) {
238         // TODO: Is this necessary if nScriptForEach calls validate as well?
239         // FieldPacker is kept here to support regular params in the future.
240         mRS.validate();
241         if (ains != null) {
242             for (Allocation ain : ains) {
243                 mRS.validateObject(ain);
244             }
245         }
246         mRS.validateObject(aout);
247 
248         if (ains == null && aout == null) {
249             throw new RSIllegalArgumentException(
250                 "At least one of ain or aout is required to be non-null.");
251         }
252 
253         long[] in_ids;
254         if (ains != null) {
255             in_ids = new long[ains.length];
256             for (int index = 0; index < ains.length; ++index) {
257                 in_ids[index] = ains[index].getID(mRS);
258             }
259         } else {
260             in_ids = null;
261         }
262 
263         long out_id = 0;
264         if (aout != null) {
265             out_id = aout.getID(mRS);
266         }
267 
268         byte[] params = null;
269         if (v != null) {
270             params = v.getData();
271         }
272 
273         int[] limits = null;
274         if (sc != null) {
275             limits = new int[6];
276 
277             limits[0] = sc.xstart;
278             limits[1] = sc.xend;
279             limits[2] = sc.ystart;
280             limits[3] = sc.yend;
281             limits[4] = sc.zstart;
282             limits[5] = sc.zend;
283         }
284 
285         mRS.nScriptForEach(getID(mRS), slot, in_ids, out_id, params, limits);
286     }
287 
288     /**
289      * Only intended for use by generated reflected code.  (General reduction)
290      *
291      */
reduce(int slot, Allocation[] ains, Allocation aout, LaunchOptions sc)292     protected void reduce(int slot, Allocation[] ains, Allocation aout, LaunchOptions sc) {
293         mRS.validate();
294         if (ains == null || ains.length < 1) {
295             throw new RSIllegalArgumentException(
296                 "At least one input is required.");
297         }
298         if (aout == null) {
299             throw new RSIllegalArgumentException(
300                 "aout is required to be non-null.");
301         }
302         for (Allocation ain : ains) {
303             mRS.validateObject(ain);
304         }
305 
306         long[] in_ids = new long[ains.length];
307         for (int index = 0; index < ains.length; ++index) {
308             in_ids[index] = ains[index].getID(mRS);
309         }
310         long out_id = aout.getID(mRS);
311 
312         int[] limits = null;
313         if (sc != null) {
314             limits = new int[6];
315 
316             limits[0] = sc.xstart;
317             limits[1] = sc.xend;
318             limits[2] = sc.ystart;
319             limits[3] = sc.yend;
320             limits[4] = sc.zstart;
321             limits[5] = sc.zend;
322         }
323 
324         mRS.nScriptReduce(getID(mRS), slot, in_ids, out_id, limits);
325     }
326 
327     long[] mInIdsBuffer;
328 
Script(long id, RenderScript rs)329     Script(long id, RenderScript rs) {
330         super(id, rs);
331 
332         mInIdsBuffer = new long[1];
333 
334         /* The constructors for the derived classes (including ScriptIntrinsic
335          * derived classes and ScriptC derived classes generated by Slang
336          * reflection) seem to be simple enough, so we just put the guard.open()
337          * call here, rather than in the end of the constructor for the derived
338          * class. This, of course, assumes the derived constructor would not
339          * throw any exception after calling this constructor.
340          *
341          * If new derived classes are added with more complicated constructors
342          * that throw exceptions, this call has to be (duplicated and) moved
343          * to the end of each derived class constructor.
344          */
345         guard.open("destroy");
346     }
347 
348     /**
349      * Only intended for use by generated reflected code.
350      *
351      */
bindAllocation(Allocation va, int slot)352     public void bindAllocation(Allocation va, int slot) {
353         mRS.validate();
354         mRS.validateObject(va);
355         if (va != null) {
356 
357             android.content.Context context = mRS.getApplicationContext();
358 
359             if (context.getApplicationInfo().targetSdkVersion >= 20) {
360                 final Type t = va.mType;
361                 if (t.hasMipmaps() || t.hasFaces() || (t.getY() != 0) ||
362                     (t.getZ() != 0)) {
363 
364                     throw new RSIllegalArgumentException(
365                         "API 20+ only allows simple 1D allocations to be " +
366                         "used with bind.");
367                 }
368             }
369             mRS.nScriptBindAllocation(getID(mRS), va.getID(mRS), slot);
370         } else {
371             mRS.nScriptBindAllocation(getID(mRS), 0, slot);
372         }
373     }
374 
375     /**
376      * Only intended for use by generated reflected code.
377      *
378      */
setVar(int index, float v)379     public void setVar(int index, float v) {
380         mRS.nScriptSetVarF(getID(mRS), index, v);
381     }
getVarF(int index)382     public float getVarF(int index) {
383         return mRS.nScriptGetVarF(getID(mRS), index);
384     }
385 
386     /**
387      * Only intended for use by generated reflected code.
388      *
389      */
setVar(int index, double v)390     public void setVar(int index, double v) {
391         mRS.nScriptSetVarD(getID(mRS), index, v);
392     }
getVarD(int index)393     public double getVarD(int index) {
394         return mRS.nScriptGetVarD(getID(mRS), index);
395     }
396 
397     /**
398      * Only intended for use by generated reflected code.
399      *
400      */
setVar(int index, int v)401     public void setVar(int index, int v) {
402         mRS.nScriptSetVarI(getID(mRS), index, v);
403     }
getVarI(int index)404     public int getVarI(int index) {
405         return mRS.nScriptGetVarI(getID(mRS), index);
406     }
407 
408 
409     /**
410      * Only intended for use by generated reflected code.
411      *
412      */
setVar(int index, long v)413     public void setVar(int index, long v) {
414         mRS.nScriptSetVarJ(getID(mRS), index, v);
415     }
getVarJ(int index)416     public long getVarJ(int index) {
417         return mRS.nScriptGetVarJ(getID(mRS), index);
418     }
419 
420 
421     /**
422      * Only intended for use by generated reflected code.
423      *
424      */
setVar(int index, boolean v)425     public void setVar(int index, boolean v) {
426         mRS.nScriptSetVarI(getID(mRS), index, v ? 1 : 0);
427     }
getVarB(int index)428     public boolean getVarB(int index) {
429         return mRS.nScriptGetVarI(getID(mRS), index) > 0 ? true : false;
430     }
431 
432     /**
433      * Only intended for use by generated reflected code.
434      *
435      */
setVar(int index, BaseObj o)436     public void setVar(int index, BaseObj o) {
437         mRS.validate();
438         mRS.validateObject(o);
439         mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : o.getID(mRS));
440     }
441 
442     /**
443      * Only intended for use by generated reflected code.
444      *
445      */
setVar(int index, FieldPacker v)446     public void setVar(int index, FieldPacker v) {
447         mRS.nScriptSetVarV(getID(mRS), index, v.getData());
448     }
449 
450     /**
451      * Only intended for use by generated reflected code.
452      *
453      */
setVar(int index, FieldPacker v, Element e, int[] dims)454     public void setVar(int index, FieldPacker v, Element e, int[] dims) {
455         mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), e.getID(mRS), dims);
456     }
457 
458     /**
459      * Only intended for use by generated reflected code.
460      *
461      */
getVarV(int index, FieldPacker v)462     public void getVarV(int index, FieldPacker v) {
463         mRS.nScriptGetVarV(getID(mRS), index, v.getData());
464     }
465 
setTimeZone(String timeZone)466     public void setTimeZone(String timeZone) {
467         mRS.validate();
468         try {
469             mRS.nScriptSetTimeZone(getID(mRS), timeZone.getBytes("UTF-8"));
470         } catch (java.io.UnsupportedEncodingException e) {
471             throw new RuntimeException(e);
472         }
473     }
474 
475     /**
476      * Only intended for use by generated reflected code.
477      *
478      */
479     public static class Builder {
480         RenderScript mRS;
481 
Builder(RenderScript rs)482         Builder(RenderScript rs) {
483             mRS = rs;
484         }
485     }
486 
487 
488     /**
489      * Only intended for use by generated reflected code.
490      *
491      */
492     public static class FieldBase {
493         protected Element mElement;
494         protected Allocation mAllocation;
495 
init(RenderScript rs, int dimx)496         protected void init(RenderScript rs, int dimx) {
497             mAllocation = Allocation.createSized(rs, mElement, dimx,
498                                                  Allocation.USAGE_SCRIPT);
499         }
500 
init(RenderScript rs, int dimx, int usages)501         protected void init(RenderScript rs, int dimx, int usages) {
502             mAllocation =
503                 Allocation.createSized(rs, mElement, dimx,
504                                        Allocation.USAGE_SCRIPT | usages);
505         }
506 
FieldBase()507         protected FieldBase() {
508         }
509 
getElement()510         public Element getElement() {
511             return mElement;
512         }
513 
getType()514         public Type getType() {
515             return mAllocation.getType();
516         }
517 
getAllocation()518         public Allocation getAllocation() {
519             return mAllocation;
520         }
521 
522         //@Override
updateAllocation()523         public void updateAllocation() {
524         }
525     }
526 
527 
528     /**
529      * Class for specifying the specifics about how a kernel will be
530      * launched.
531      *
532      * This class can specify a potential range of cells on which to
533      * run a kernel.  If no set is called for a dimension then this
534      * class will have no impact on that dimension when the kernel
535      * is executed.
536      *
537      * The forEach kernel launch will operate over the intersection of
538      * the dimensions.
539      *
540      * Example:
541      * LaunchOptions with setX(5, 15)
542      * Allocation with dimension X=10, Y=10
543      * The resulting forEach run would execute over:
544      * x = 5 to 9 (inclusive) and
545      * y = 0 to 9 (inclusive).
546      *
547      *
548      */
549     public static final class LaunchOptions {
550         private int xstart = 0;
551         private int ystart = 0;
552         private int xend = 0;
553         private int yend = 0;
554         private int zstart = 0;
555         private int zend = 0;
556         private int strategy;
557 
558         /**
559          * Set the X range. xstartArg is the lowest coordinate of the range,
560          * and xendArg-1 is the highest coordinate of the range.
561          *
562          * @param xstartArg Must be >= 0
563          * @param xendArg Must be > xstartArg
564          *
565          * @return LaunchOptions
566          */
setX(int xstartArg, int xendArg)567         public LaunchOptions setX(int xstartArg, int xendArg) {
568             if (xstartArg < 0 || xendArg <= xstartArg) {
569                 throw new RSIllegalArgumentException("Invalid dimensions");
570             }
571             xstart = xstartArg;
572             xend = xendArg;
573             return this;
574         }
575 
576         /**
577          * Set the Y range. ystartArg is the lowest coordinate of the range,
578          * and yendArg-1 is the highest coordinate of the range.
579          *
580          * @param ystartArg Must be >= 0
581          * @param yendArg Must be > ystartArg
582          *
583          * @return LaunchOptions
584          */
setY(int ystartArg, int yendArg)585         public LaunchOptions setY(int ystartArg, int yendArg) {
586             if (ystartArg < 0 || yendArg <= ystartArg) {
587                 throw new RSIllegalArgumentException("Invalid dimensions");
588             }
589             ystart = ystartArg;
590             yend = yendArg;
591             return this;
592         }
593 
594         /**
595          * Set the Z range. zstartArg is the lowest coordinate of the range,
596          * and zendArg-1 is the highest coordinate of the range.
597          *
598          * @param zstartArg Must be >= 0
599          * @param zendArg Must be > zstartArg
600          *
601          * @return LaunchOptions
602          */
setZ(int zstartArg, int zendArg)603         public LaunchOptions setZ(int zstartArg, int zendArg) {
604             if (zstartArg < 0 || zendArg <= zstartArg) {
605                 throw new RSIllegalArgumentException("Invalid dimensions");
606             }
607             zstart = zstartArg;
608             zend = zendArg;
609             return this;
610         }
611 
612 
613         /**
614          * Returns the current X start
615          *
616          * @return int current value
617          */
getXStart()618         public int getXStart() {
619             return xstart;
620         }
621         /**
622          * Returns the current X end
623          *
624          * @return int current value
625          */
getXEnd()626         public int getXEnd() {
627             return xend;
628         }
629         /**
630          * Returns the current Y start
631          *
632          * @return int current value
633          */
getYStart()634         public int getYStart() {
635             return ystart;
636         }
637         /**
638          * Returns the current Y end
639          *
640          * @return int current value
641          */
getYEnd()642         public int getYEnd() {
643             return yend;
644         }
645         /**
646          * Returns the current Z start
647          *
648          * @return int current value
649          */
getZStart()650         public int getZStart() {
651             return zstart;
652         }
653         /**
654          * Returns the current Z end
655          *
656          * @return int current value
657          */
getZEnd()658         public int getZEnd() {
659             return zend;
660         }
661 
662     }
663 }
664