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