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