• 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     long[] mInIdsBuffer;
287 
Script(long id, RenderScript rs)288     Script(long id, RenderScript rs) {
289         super(id, rs);
290 
291         mInIdsBuffer = new long[1];
292     }
293 
294 
295     /**
296      * Only intended for use by generated reflected code.
297      *
298      */
bindAllocation(Allocation va, int slot)299     public void bindAllocation(Allocation va, int slot) {
300         mRS.validate();
301         mRS.validateObject(va);
302         if (va != null) {
303 
304             android.content.Context context = mRS.getApplicationContext();
305 
306             if (context.getApplicationInfo().targetSdkVersion >= 20) {
307                 final Type t = va.mType;
308                 if (t.hasMipmaps() || t.hasFaces() || (t.getY() != 0) ||
309                     (t.getZ() != 0)) {
310 
311                     throw new RSIllegalArgumentException(
312                         "API 20+ only allows simple 1D allocations to be " +
313                         "used with bind.");
314                 }
315             }
316             mRS.nScriptBindAllocation(getID(mRS), va.getID(mRS), slot);
317         } else {
318             mRS.nScriptBindAllocation(getID(mRS), 0, slot);
319         }
320     }
321 
322     /**
323      * Only intended for use by generated reflected code.
324      *
325      */
setVar(int index, float v)326     public void setVar(int index, float v) {
327         mRS.nScriptSetVarF(getID(mRS), index, v);
328     }
getVarF(int index)329     public float getVarF(int index) {
330         return mRS.nScriptGetVarF(getID(mRS), index);
331     }
332 
333     /**
334      * Only intended for use by generated reflected code.
335      *
336      */
setVar(int index, double v)337     public void setVar(int index, double v) {
338         mRS.nScriptSetVarD(getID(mRS), index, v);
339     }
getVarD(int index)340     public double getVarD(int index) {
341         return mRS.nScriptGetVarD(getID(mRS), index);
342     }
343 
344     /**
345      * Only intended for use by generated reflected code.
346      *
347      */
setVar(int index, int v)348     public void setVar(int index, int v) {
349         mRS.nScriptSetVarI(getID(mRS), index, v);
350     }
getVarI(int index)351     public int getVarI(int index) {
352         return mRS.nScriptGetVarI(getID(mRS), index);
353     }
354 
355 
356     /**
357      * Only intended for use by generated reflected code.
358      *
359      */
setVar(int index, long v)360     public void setVar(int index, long v) {
361         mRS.nScriptSetVarJ(getID(mRS), index, v);
362     }
getVarJ(int index)363     public long getVarJ(int index) {
364         return mRS.nScriptGetVarJ(getID(mRS), index);
365     }
366 
367 
368     /**
369      * Only intended for use by generated reflected code.
370      *
371      */
setVar(int index, boolean v)372     public void setVar(int index, boolean v) {
373         mRS.nScriptSetVarI(getID(mRS), index, v ? 1 : 0);
374     }
getVarB(int index)375     public boolean getVarB(int index) {
376         return mRS.nScriptGetVarI(getID(mRS), index) > 0 ? true : false;
377     }
378 
379     /**
380      * Only intended for use by generated reflected code.
381      *
382      */
setVar(int index, BaseObj o)383     public void setVar(int index, BaseObj o) {
384         mRS.validate();
385         mRS.validateObject(o);
386         mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : o.getID(mRS));
387     }
388 
389     /**
390      * Only intended for use by generated reflected code.
391      *
392      */
setVar(int index, FieldPacker v)393     public void setVar(int index, FieldPacker v) {
394         mRS.nScriptSetVarV(getID(mRS), index, v.getData());
395     }
396 
397     /**
398      * Only intended for use by generated reflected code.
399      *
400      */
setVar(int index, FieldPacker v, Element e, int[] dims)401     public void setVar(int index, FieldPacker v, Element e, int[] dims) {
402         mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), e.getID(mRS), dims);
403     }
404 
405     /**
406      * Only intended for use by generated reflected code.
407      *
408      */
getVarV(int index, FieldPacker v)409     public void getVarV(int index, FieldPacker v) {
410         mRS.nScriptGetVarV(getID(mRS), index, v.getData());
411     }
412 
setTimeZone(String timeZone)413     public void setTimeZone(String timeZone) {
414         mRS.validate();
415         try {
416             mRS.nScriptSetTimeZone(getID(mRS), timeZone.getBytes("UTF-8"));
417         } catch (java.io.UnsupportedEncodingException e) {
418             throw new RuntimeException(e);
419         }
420     }
421 
422     /**
423      * Only intended for use by generated reflected code.
424      *
425      */
426     public static class Builder {
427         RenderScript mRS;
428 
Builder(RenderScript rs)429         Builder(RenderScript rs) {
430             mRS = rs;
431         }
432     }
433 
434 
435     /**
436      * Only intended for use by generated reflected code.
437      *
438      */
439     public static class FieldBase {
440         protected Element mElement;
441         protected Allocation mAllocation;
442 
init(RenderScript rs, int dimx)443         protected void init(RenderScript rs, int dimx) {
444             mAllocation = Allocation.createSized(rs, mElement, dimx,
445                                                  Allocation.USAGE_SCRIPT);
446         }
447 
init(RenderScript rs, int dimx, int usages)448         protected void init(RenderScript rs, int dimx, int usages) {
449             mAllocation =
450                 Allocation.createSized(rs, mElement, dimx,
451                                        Allocation.USAGE_SCRIPT | usages);
452         }
453 
FieldBase()454         protected FieldBase() {
455         }
456 
getElement()457         public Element getElement() {
458             return mElement;
459         }
460 
getType()461         public Type getType() {
462             return mAllocation.getType();
463         }
464 
getAllocation()465         public Allocation getAllocation() {
466             return mAllocation;
467         }
468 
469         //@Override
updateAllocation()470         public void updateAllocation() {
471         }
472     }
473 
474 
475     /**
476      * Class for specifying the specifics about how a kernel will be
477      * launched
478      *
479      * This class can specify a potential range of cells on which to
480      * run a kernel.  If no set is called for a dimension then this
481      * class will have no impact on that dimension when the kernel
482      * is executed.
483      *
484      * The forEach launch will operate over the intersection of the
485      * dimensions.
486      *
487      * Example:
488      * LaunchOptions with setX(5, 15)
489      * Allocation with dimension X=10, Y=10
490      * The resulting forEach run would execute over x = 5 to 10 and
491      * y = 0 to 10.
492      *
493      *
494      */
495     public static final class LaunchOptions {
496         private int xstart = 0;
497         private int ystart = 0;
498         private int xend = 0;
499         private int yend = 0;
500         private int zstart = 0;
501         private int zend = 0;
502         private int strategy;
503 
504         /**
505          * Set the X range.  If the end value is set to 0 the X dimension is not
506          * clipped.
507          *
508          * @param xstartArg Must be >= 0
509          * @param xendArg Must be >= xstartArg
510          *
511          * @return LaunchOptions
512          */
setX(int xstartArg, int xendArg)513         public LaunchOptions setX(int xstartArg, int xendArg) {
514             if (xstartArg < 0 || xendArg <= xstartArg) {
515                 throw new RSIllegalArgumentException("Invalid dimensions");
516             }
517             xstart = xstartArg;
518             xend = xendArg;
519             return this;
520         }
521 
522         /**
523          * Set the Y range.  If the end value is set to 0 the Y dimension is not
524          * clipped.
525          *
526          * @param ystartArg Must be >= 0
527          * @param yendArg Must be >= ystartArg
528          *
529          * @return LaunchOptions
530          */
setY(int ystartArg, int yendArg)531         public LaunchOptions setY(int ystartArg, int yendArg) {
532             if (ystartArg < 0 || yendArg <= ystartArg) {
533                 throw new RSIllegalArgumentException("Invalid dimensions");
534             }
535             ystart = ystartArg;
536             yend = yendArg;
537             return this;
538         }
539 
540         /**
541          * Set the Z range.  If the end value is set to 0 the Z dimension is not
542          * clipped.
543          *
544          * @param zstartArg Must be >= 0
545          * @param zendArg Must be >= zstartArg
546          *
547          * @return LaunchOptions
548          */
setZ(int zstartArg, int zendArg)549         public LaunchOptions setZ(int zstartArg, int zendArg) {
550             if (zstartArg < 0 || zendArg <= zstartArg) {
551                 throw new RSIllegalArgumentException("Invalid dimensions");
552             }
553             zstart = zstartArg;
554             zend = zendArg;
555             return this;
556         }
557 
558 
559         /**
560          * Returns the current X start
561          *
562          * @return int current value
563          */
getXStart()564         public int getXStart() {
565             return xstart;
566         }
567         /**
568          * Returns the current X end
569          *
570          * @return int current value
571          */
getXEnd()572         public int getXEnd() {
573             return xend;
574         }
575         /**
576          * Returns the current Y start
577          *
578          * @return int current value
579          */
getYStart()580         public int getYStart() {
581             return ystart;
582         }
583         /**
584          * Returns the current Y end
585          *
586          * @return int current value
587          */
getYEnd()588         public int getYEnd() {
589             return yend;
590         }
591         /**
592          * Returns the current Z start
593          *
594          * @return int current value
595          */
getZStart()596         public int getZStart() {
597             return zstart;
598         }
599         /**
600          * Returns the current Z end
601          *
602          * @return int current value
603          */
getZEnd()604         public int getZEnd() {
605             return zend;
606         }
607 
608     }
609 }
610