OSDN Git Service

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