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