1 /*
2  * Copyright (C) 2013 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 java.util.BitSet;
20 
21 /**
22  * Utility class for packing arguments and structures from Android system objects to
23  * RenderScript objects.
24  *
25  * This class is only intended to be used to support the
26  * reflected code generated by the RS tool chain.  It should not
27  * be called directly.
28  *
29  **/
30 public class FieldPacker {
FieldPacker(int len)31     public FieldPacker(int len) {
32         mPos = 0;
33         mLen = len;
34         mData = new byte[len];
35         mAlignment = new BitSet();
36     }
37 
FieldPacker(byte[] data)38     public FieldPacker(byte[] data) {
39         // Advance mPos to the end of the buffer, since we are copying in the
40         // full data input.
41         mPos = data.length;
42         mLen = data.length;
43         mData = data;
44         mAlignment = new BitSet();
45         // TODO: We should either have an actual FieldPacker copy constructor
46         // or drop support for computing alignment like this. As it stands,
47         // subAlign() can never work correctly for copied FieldPacker objects.
48     }
49 
createFromArray(Object[] args)50     static FieldPacker createFromArray(Object[] args) {
51         FieldPacker fp = new FieldPacker(RenderScript.sPointerSize * 8);
52         for (Object arg : args) {
53             fp.addSafely(arg);
54         }
55         fp.resize(fp.mPos);
56         return fp;
57     }
58 
align(int v)59     public void align(int v) {
60         if ((v <= 0) || ((v & (v - 1)) != 0)) {
61             throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v);
62         }
63 
64         while ((mPos & (v - 1)) != 0) {
65             mAlignment.flip(mPos);
66             mData[mPos++] = 0;
67         }
68     }
69 
subalign(int v)70     public void subalign(int v) {
71         if ((v & (v - 1)) != 0) {
72             throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v);
73         }
74 
75         while ((mPos & (v - 1)) != 0) {
76             mPos--;
77         }
78 
79         if (mPos > 0) {
80             while (mAlignment.get(mPos - 1) == true) {
81                 mPos--;
82                 mAlignment.flip(mPos);
83             }
84         }
85 
86     }
87 
reset()88     public void reset() {
89         mPos = 0;
90     }
reset(int i)91     public void reset(int i) {
92         if ((i < 0) || (i > mLen)) {
93             throw new RSIllegalArgumentException("out of range argument: " + i);
94         }
95         mPos = i;
96     }
97 
skip(int i)98     public void skip(int i) {
99         int res = mPos + i;
100         if ((res < 0) || (res > mLen)) {
101             throw new RSIllegalArgumentException("out of range argument: " + i);
102         }
103         mPos = res;
104     }
105 
addI8(byte v)106     public void addI8(byte v) {
107         mData[mPos++] = v;
108     }
109 
subI8()110     public byte subI8() {
111         subalign(1);
112         return mData[--mPos];
113     }
114 
addI16(short v)115     public void addI16(short v) {
116         align(2);
117         mData[mPos++] = (byte)(v & 0xff);
118         mData[mPos++] = (byte)(v >> 8);
119     }
120 
subI16()121     public short subI16() {
122         subalign(2);
123         short v = 0;
124         v = (short)((mData[--mPos] & 0xff) << 8);
125         v = (short)(v | (short)(mData[--mPos] & 0xff));
126         return v;
127     }
128 
129 
addI32(int v)130     public void addI32(int v) {
131         align(4);
132         mData[mPos++] = (byte)(v & 0xff);
133         mData[mPos++] = (byte)((v >> 8) & 0xff);
134         mData[mPos++] = (byte)((v >> 16) & 0xff);
135         mData[mPos++] = (byte)((v >> 24) & 0xff);
136     }
137 
subI32()138     public int subI32() {
139         subalign(4);
140         int v = 0;
141         v = ((mData[--mPos] & 0xff) << 24);
142         v = v | ((mData[--mPos] & 0xff) << 16);
143         v = v | ((mData[--mPos] & 0xff) << 8);
144         v = v | ((mData[--mPos] & 0xff));
145         return v;
146     }
147 
148 
addI64(long v)149     public void addI64(long v) {
150         align(8);
151         mData[mPos++] = (byte)(v & 0xff);
152         mData[mPos++] = (byte)((v >> 8) & 0xff);
153         mData[mPos++] = (byte)((v >> 16) & 0xff);
154         mData[mPos++] = (byte)((v >> 24) & 0xff);
155         mData[mPos++] = (byte)((v >> 32) & 0xff);
156         mData[mPos++] = (byte)((v >> 40) & 0xff);
157         mData[mPos++] = (byte)((v >> 48) & 0xff);
158         mData[mPos++] = (byte)((v >> 56) & 0xff);
159     }
160 
subI64()161     public long subI64() {
162         subalign(8);
163         long v = 0;
164         byte x = 0;
165         x = ((mData[--mPos]));
166         v = (long)(v | (((long)x) & 0xff) << 56l);
167         x = ((mData[--mPos]));
168         v = (long)(v | (((long)x) & 0xff) << 48l);
169         x = ((mData[--mPos]));
170         v = (long)(v | (((long)x) & 0xff) << 40l);
171         x = ((mData[--mPos]));
172         v = (long)(v | (((long)x) & 0xff) << 32l);
173         x = ((mData[--mPos]));
174         v = (long)(v | (((long)x) & 0xff) << 24l);
175         x = ((mData[--mPos]));
176         v = (long)(v | (((long)x) & 0xff) << 16l);
177         x = ((mData[--mPos]));
178         v = (long)(v | (((long)x) & 0xff) << 8l);
179         x = ((mData[--mPos]));
180         v = (long)(v | (((long)x) & 0xff));
181         return v;
182     }
183 
addU8(short v)184     public void addU8(short v) {
185         if ((v < 0) || (v > 0xff)) {
186             android.util.Log.e("rs", "FieldPacker.addU8( " + v + " )");
187             throw new IllegalArgumentException("Saving value out of range for type");
188         }
189         mData[mPos++] = (byte)v;
190     }
191 
addU16(int v)192     public void addU16(int v) {
193         if ((v < 0) || (v > 0xffff)) {
194             android.util.Log.e("rs", "FieldPacker.addU16( " + v + " )");
195             throw new IllegalArgumentException("Saving value out of range for type");
196         }
197         align(2);
198         mData[mPos++] = (byte)(v & 0xff);
199         mData[mPos++] = (byte)(v >> 8);
200     }
201 
addU32(long v)202     public void addU32(long v) {
203         if ((v < 0) || (v > 0xffffffffL)) {
204             android.util.Log.e("rs", "FieldPacker.addU32( " + v + " )");
205             throw new IllegalArgumentException("Saving value out of range for type");
206         }
207         align(4);
208         mData[mPos++] = (byte)(v & 0xff);
209         mData[mPos++] = (byte)((v >> 8) & 0xff);
210         mData[mPos++] = (byte)((v >> 16) & 0xff);
211         mData[mPos++] = (byte)((v >> 24) & 0xff);
212     }
213 
addU64(long v)214     public void addU64(long v) {
215         if (v < 0) {
216             android.util.Log.e("rs", "FieldPacker.addU64( " + v + " )");
217             throw new IllegalArgumentException("Saving value out of range for type");
218         }
219         align(8);
220         mData[mPos++] = (byte)(v & 0xff);
221         mData[mPos++] = (byte)((v >> 8) & 0xff);
222         mData[mPos++] = (byte)((v >> 16) & 0xff);
223         mData[mPos++] = (byte)((v >> 24) & 0xff);
224         mData[mPos++] = (byte)((v >> 32) & 0xff);
225         mData[mPos++] = (byte)((v >> 40) & 0xff);
226         mData[mPos++] = (byte)((v >> 48) & 0xff);
227         mData[mPos++] = (byte)((v >> 56) & 0xff);
228     }
229 
addF32(float v)230     public void addF32(float v) {
231         addI32(Float.floatToRawIntBits(v));
232     }
233 
subF32()234     public float subF32() {
235         return Float.intBitsToFloat(subI32());
236     }
237 
addF64(double v)238     public void addF64(double v) {
239         addI64(Double.doubleToRawLongBits(v));
240     }
241 
subF64()242     public double subF64() {
243         return Double.longBitsToDouble(subI64());
244     }
245 
addObj(BaseObj obj)246     public void addObj(BaseObj obj) {
247         if (obj != null) {
248             if (RenderScript.sPointerSize == 8) {
249                 addI64(obj.getID(null));
250                 addI64(0);
251                 addI64(0);
252                 addI64(0);
253             } else {
254                 addI32((int)obj.getID(null));
255             }
256         } else {
257             if (RenderScript.sPointerSize == 8) {
258                 addI64(0);
259                 addI64(0);
260                 addI64(0);
261                 addI64(0);
262             } else {
263                 addI32(0);
264             }
265         }
266     }
267 
addF32(Float2 v)268     public void addF32(Float2 v) {
269         addF32(v.x);
270         addF32(v.y);
271     }
addF32(Float3 v)272     public void addF32(Float3 v) {
273         addF32(v.x);
274         addF32(v.y);
275         addF32(v.z);
276     }
addF32(Float4 v)277     public void addF32(Float4 v) {
278         addF32(v.x);
279         addF32(v.y);
280         addF32(v.z);
281         addF32(v.w);
282     }
283 
addF64(Double2 v)284     public void addF64(Double2 v) {
285         addF64(v.x);
286         addF64(v.y);
287     }
addF64(Double3 v)288     public void addF64(Double3 v) {
289         addF64(v.x);
290         addF64(v.y);
291         addF64(v.z);
292     }
addF64(Double4 v)293     public void addF64(Double4 v) {
294         addF64(v.x);
295         addF64(v.y);
296         addF64(v.z);
297         addF64(v.w);
298     }
299 
addI8(Byte2 v)300     public void addI8(Byte2 v) {
301         addI8(v.x);
302         addI8(v.y);
303     }
addI8(Byte3 v)304     public void addI8(Byte3 v) {
305         addI8(v.x);
306         addI8(v.y);
307         addI8(v.z);
308     }
addI8(Byte4 v)309     public void addI8(Byte4 v) {
310         addI8(v.x);
311         addI8(v.y);
312         addI8(v.z);
313         addI8(v.w);
314     }
315 
addU8(Short2 v)316     public void addU8(Short2 v) {
317         addU8(v.x);
318         addU8(v.y);
319     }
addU8(Short3 v)320     public void addU8(Short3 v) {
321         addU8(v.x);
322         addU8(v.y);
323         addU8(v.z);
324     }
addU8(Short4 v)325     public void addU8(Short4 v) {
326         addU8(v.x);
327         addU8(v.y);
328         addU8(v.z);
329         addU8(v.w);
330     }
331 
addI16(Short2 v)332     public void addI16(Short2 v) {
333         addI16(v.x);
334         addI16(v.y);
335     }
addI16(Short3 v)336     public void addI16(Short3 v) {
337         addI16(v.x);
338         addI16(v.y);
339         addI16(v.z);
340     }
addI16(Short4 v)341     public void addI16(Short4 v) {
342         addI16(v.x);
343         addI16(v.y);
344         addI16(v.z);
345         addI16(v.w);
346     }
347 
addU16(Int2 v)348     public void addU16(Int2 v) {
349         addU16(v.x);
350         addU16(v.y);
351     }
addU16(Int3 v)352     public void addU16(Int3 v) {
353         addU16(v.x);
354         addU16(v.y);
355         addU16(v.z);
356     }
addU16(Int4 v)357     public void addU16(Int4 v) {
358         addU16(v.x);
359         addU16(v.y);
360         addU16(v.z);
361         addU16(v.w);
362     }
363 
addI32(Int2 v)364     public void addI32(Int2 v) {
365         addI32(v.x);
366         addI32(v.y);
367     }
addI32(Int3 v)368     public void addI32(Int3 v) {
369         addI32(v.x);
370         addI32(v.y);
371         addI32(v.z);
372     }
addI32(Int4 v)373     public void addI32(Int4 v) {
374         addI32(v.x);
375         addI32(v.y);
376         addI32(v.z);
377         addI32(v.w);
378     }
379 
addU32(Long2 v)380     public void addU32(Long2 v) {
381         addU32(v.x);
382         addU32(v.y);
383     }
addU32(Long3 v)384     public void addU32(Long3 v) {
385         addU32(v.x);
386         addU32(v.y);
387         addU32(v.z);
388     }
addU32(Long4 v)389     public void addU32(Long4 v) {
390         addU32(v.x);
391         addU32(v.y);
392         addU32(v.z);
393         addU32(v.w);
394     }
395 
addI64(Long2 v)396     public void addI64(Long2 v) {
397         addI64(v.x);
398         addI64(v.y);
399     }
addI64(Long3 v)400     public void addI64(Long3 v) {
401         addI64(v.x);
402         addI64(v.y);
403         addI64(v.z);
404     }
addI64(Long4 v)405     public void addI64(Long4 v) {
406         addI64(v.x);
407         addI64(v.y);
408         addI64(v.z);
409         addI64(v.w);
410     }
411 
addU64(Long2 v)412     public void addU64(Long2 v) {
413         addU64(v.x);
414         addU64(v.y);
415     }
addU64(Long3 v)416     public void addU64(Long3 v) {
417         addU64(v.x);
418         addU64(v.y);
419         addU64(v.z);
420     }
addU64(Long4 v)421     public void addU64(Long4 v) {
422         addU64(v.x);
423         addU64(v.y);
424         addU64(v.z);
425         addU64(v.w);
426     }
427 
428 
subFloat2()429     public Float2 subFloat2() {
430         Float2 v = new Float2();
431         v.y = subF32();
432         v.x = subF32();
433         return v;
434     }
subFloat3()435     public Float3 subFloat3() {
436         Float3 v = new Float3();
437         v.z = subF32();
438         v.y = subF32();
439         v.x = subF32();
440         return v;
441     }
subFloat4()442     public Float4 subFloat4() {
443         Float4 v = new Float4();
444         v.w = subF32();
445         v.z = subF32();
446         v.y = subF32();
447         v.x = subF32();
448         return v;
449     }
450 
subDouble2()451     public Double2 subDouble2() {
452         Double2 v = new Double2();
453         v.y = subF64();
454         v.x = subF64();
455         return v;
456     }
subDouble3()457     public Double3 subDouble3() {
458         Double3 v = new Double3();
459         v.z = subF64();
460         v.y = subF64();
461         v.x = subF64();
462         return v;
463     }
subDouble4()464     public Double4 subDouble4() {
465         Double4 v = new Double4();
466         v.w = subF64();
467         v.z = subF64();
468         v.y = subF64();
469         v.x = subF64();
470         return v;
471     }
472 
subByte2()473     public Byte2 subByte2() {
474         Byte2 v = new Byte2();
475         v.y = subI8();
476         v.x = subI8();
477         return v;
478     }
subByte3()479     public Byte3 subByte3() {
480         Byte3 v = new Byte3();
481         v.z = subI8();
482         v.y = subI8();
483         v.x = subI8();
484         return v;
485     }
subByte4()486     public Byte4 subByte4() {
487         Byte4 v = new Byte4();
488         v.w = subI8();
489         v.z = subI8();
490         v.y = subI8();
491         v.x = subI8();
492         return v;
493     }
494 
subShort2()495     public Short2 subShort2() {
496         Short2 v = new Short2();
497         v.y = subI16();
498         v.x = subI16();
499         return v;
500     }
subShort3()501     public Short3 subShort3() {
502         Short3 v = new Short3();
503         v.z = subI16();
504         v.y = subI16();
505         v.x = subI16();
506         return v;
507     }
subShort4()508     public Short4 subShort4() {
509         Short4 v = new Short4();
510         v.w = subI16();
511         v.z = subI16();
512         v.y = subI16();
513         v.x = subI16();
514         return v;
515     }
516 
subInt2()517     public Int2 subInt2() {
518         Int2 v = new Int2();
519         v.y = subI32();
520         v.x = subI32();
521         return v;
522     }
subInt3()523     public Int3 subInt3() {
524         Int3 v = new Int3();
525         v.z = subI32();
526         v.y = subI32();
527         v.x = subI32();
528         return v;
529     }
subInt4()530     public Int4 subInt4() {
531         Int4 v = new Int4();
532         v.w = subI32();
533         v.z = subI32();
534         v.y = subI32();
535         v.x = subI32();
536         return v;
537     }
538 
subLong2()539     public Long2 subLong2() {
540         Long2 v = new Long2();
541         v.y = subI64();
542         v.x = subI64();
543         return v;
544     }
subLong3()545     public Long3 subLong3() {
546         Long3 v = new Long3();
547         v.z = subI64();
548         v.y = subI64();
549         v.x = subI64();
550         return v;
551     }
subLong4()552     public Long4 subLong4() {
553         Long4 v = new Long4();
554         v.w = subI64();
555         v.z = subI64();
556         v.y = subI64();
557         v.x = subI64();
558         return v;
559     }
560 
561 
562 
addMatrix(Matrix4f v)563     public void addMatrix(Matrix4f v) {
564         for (int i=0; i < v.mMat.length; i++) {
565             addF32(v.mMat[i]);
566         }
567     }
568 
subMatrix4f()569     public Matrix4f subMatrix4f() {
570         Matrix4f v = new Matrix4f();
571         for (int i = v.mMat.length - 1; i >= 0; i--) {
572             v.mMat[i] = subF32();
573         }
574         return v;
575     }
576 
addMatrix(Matrix3f v)577     public void addMatrix(Matrix3f v) {
578         for (int i=0; i < v.mMat.length; i++) {
579             addF32(v.mMat[i]);
580         }
581     }
582 
subMatrix3f()583     public Matrix3f subMatrix3f() {
584         Matrix3f v = new Matrix3f();
585         for (int i = v.mMat.length - 1; i >= 0; i--) {
586             v.mMat[i] = subF32();
587         }
588         return v;
589     }
590 
addMatrix(Matrix2f v)591     public void addMatrix(Matrix2f v) {
592         for (int i=0; i < v.mMat.length; i++) {
593             addF32(v.mMat[i]);
594         }
595     }
596 
subMatrix2f()597     public Matrix2f subMatrix2f() {
598         Matrix2f v = new Matrix2f();
599         for (int i = v.mMat.length - 1; i >= 0; i--) {
600             v.mMat[i] = subF32();
601         }
602         return v;
603     }
604 
addBoolean(boolean v)605     public void addBoolean(boolean v) {
606         addI8((byte)(v ? 1 : 0));
607     }
608 
subBoolean()609     public boolean subBoolean() {
610         byte v = subI8();
611         if (v == 1) {
612             return true;
613         }
614         return false;
615     }
616 
getData()617     public final byte[] getData() {
618         return mData;
619     }
620 
621     /**
622      * Get the actual length used for the FieldPacker.
623      *
624      * @hide
625      */
getPos()626     public int getPos() {
627         return mPos;
628     }
629 
add(Object obj)630     private void add(Object obj) {
631         if (obj instanceof Boolean) {
632             addBoolean((Boolean)obj);
633             return;
634         }
635 
636         if (obj instanceof Byte) {
637             addI8((Byte)obj);
638             return;
639         }
640 
641         if (obj instanceof Short) {
642             addI16((Short)obj);
643             return;
644         }
645 
646         if (obj instanceof Integer) {
647             addI32((Integer)obj);
648             return;
649         }
650 
651         if (obj instanceof Long) {
652             addI64((Long)obj);
653             return;
654         }
655 
656         if (obj instanceof Float) {
657             addF32((Float)obj);
658             return;
659         }
660 
661         if (obj instanceof Double) {
662             addF64((Double)obj);
663             return;
664         }
665 
666         if (obj instanceof Byte2) {
667             addI8((Byte2)obj);
668             return;
669         }
670 
671         if (obj instanceof Byte3) {
672             addI8((Byte3)obj);
673             return;
674         }
675 
676         if (obj instanceof Byte4) {
677             addI8((Byte4)obj);
678             return;
679         }
680 
681         if (obj instanceof Short2) {
682             addI16((Short2)obj);
683             return;
684         }
685 
686         if (obj instanceof Short3) {
687             addI16((Short3)obj);
688             return;
689         }
690 
691         if (obj instanceof Short4) {
692             addI16((Short4)obj);
693             return;
694         }
695 
696         if (obj instanceof Int2) {
697             addI32((Int2)obj);
698             return;
699         }
700 
701         if (obj instanceof Int3) {
702             addI32((Int3)obj);
703             return;
704         }
705 
706         if (obj instanceof Int4) {
707             addI32((Int4)obj);
708             return;
709         }
710 
711         if (obj instanceof Long2) {
712             addI64((Long2)obj);
713             return;
714         }
715 
716         if (obj instanceof Long3) {
717             addI64((Long3)obj);
718             return;
719         }
720 
721         if (obj instanceof Long4) {
722             addI64((Long4)obj);
723             return;
724         }
725 
726         if (obj instanceof Float2) {
727             addF32((Float2)obj);
728             return;
729         }
730 
731         if (obj instanceof Float3) {
732             addF32((Float3)obj);
733             return;
734         }
735 
736         if (obj instanceof Float4) {
737             addF32((Float4)obj);
738             return;
739         }
740 
741         if (obj instanceof Double2) {
742             addF64((Double2)obj);
743             return;
744         }
745 
746         if (obj instanceof Double3) {
747             addF64((Double3)obj);
748             return;
749         }
750 
751         if (obj instanceof Double4) {
752             addF64((Double4)obj);
753             return;
754         }
755 
756         if (obj instanceof Matrix2f) {
757             addMatrix((Matrix2f)obj);
758             return;
759         }
760 
761         if (obj instanceof Matrix3f) {
762             addMatrix((Matrix3f)obj);
763             return;
764         }
765 
766         if (obj instanceof Matrix4f) {
767             addMatrix((Matrix4f)obj);
768             return;
769         }
770 
771         if (obj instanceof BaseObj) {
772             addObj((BaseObj)obj);
773             return;
774         }
775     }
776 
resize(int newSize)777     private boolean resize(int newSize) {
778         if (newSize == mLen) {
779             return false;
780         }
781 
782         byte[] newData = new byte[newSize];
783         System.arraycopy(mData, 0, newData, 0, mPos);
784         mData = newData;
785         mLen = newSize;
786         return true;
787     }
788 
addSafely(Object obj)789     private void addSafely(Object obj) {
790         boolean retry;
791         final int oldPos = mPos;
792         do {
793             retry = false;
794             try {
795                 add(obj);
796             } catch (ArrayIndexOutOfBoundsException e) {
797                 mPos = oldPos;
798                 resize(mLen * 2);
799                 retry = true;
800             }
801         } while (retry);
802     }
803 
804     private byte mData[];
805     private int mPos;
806     private int mLen;
807     private BitSet mAlignment;
808 }
809