FieldPacker.java revision 56f9e6f8d5436d50530807950661e66ca5efe2bb
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
17package android.renderscript;
18
19import 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 **/
30public class FieldPacker {
31    public FieldPacker(int len) {
32        mPos = 0;
33        mLen = len;
34        mData = new byte[len];
35        mAlignment = new BitSet();
36    }
37
38    public FieldPacker(byte[] data) {
39        mPos = 0;
40        mLen = data.length;
41        mData = data;
42        mAlignment = new BitSet();
43    }
44
45    public void align(int v) {
46        if ((v <= 0) || ((v & (v - 1)) != 0)) {
47            throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v);
48        }
49
50        while ((mPos & (v - 1)) != 0) {
51            mAlignment.flip(mPos);
52            mData[mPos++] = 0;
53        }
54    }
55
56    public void subalign(int v) {
57        if ((v & (v - 1)) != 0) {
58            throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v);
59        }
60
61        while ((mPos & (v - 1)) != 0) {
62            mPos--;
63        }
64
65        if (mPos > 0) {
66            while (mAlignment.get(mPos - 1) == true) {
67                mPos--;
68                mAlignment.flip(mPos);
69            }
70        }
71
72    }
73
74    public void reset() {
75        mPos = 0;
76    }
77    public void reset(int i) {
78        if ((i < 0) || (i >= mLen)) {
79            throw new RSIllegalArgumentException("out of range argument: " + i);
80        }
81        mPos = i;
82    }
83
84    public void skip(int i) {
85        int res = mPos + i;
86        if ((res < 0) || (res > mLen)) {
87            throw new RSIllegalArgumentException("out of range argument: " + i);
88        }
89        mPos = res;
90    }
91
92    public void addI8(byte v) {
93        mData[mPos++] = v;
94    }
95
96    public byte subI8() {
97        subalign(1);
98        return mData[--mPos];
99    }
100
101    public void addI16(short v) {
102        align(2);
103        mData[mPos++] = (byte)(v & 0xff);
104        mData[mPos++] = (byte)(v >> 8);
105    }
106
107    public short subI16() {
108        subalign(2);
109        short v = 0;
110        v = (short)((mData[--mPos] & 0xff) << 8);
111        v = (short)(v | (short)(mData[--mPos] & 0xff));
112        return v;
113    }
114
115
116    public void addI32(int v) {
117        align(4);
118        mData[mPos++] = (byte)(v & 0xff);
119        mData[mPos++] = (byte)((v >> 8) & 0xff);
120        mData[mPos++] = (byte)((v >> 16) & 0xff);
121        mData[mPos++] = (byte)((v >> 24) & 0xff);
122    }
123
124    public int subI32() {
125        subalign(4);
126        int v = 0;
127        v = ((mData[--mPos] & 0xff) << 24);
128        v = v | ((mData[--mPos] & 0xff) << 16);
129        v = v | ((mData[--mPos] & 0xff) << 8);
130        v = v | ((mData[--mPos] & 0xff));
131        return v;
132    }
133
134
135    public void addI64(long v) {
136        align(8);
137        mData[mPos++] = (byte)(v & 0xff);
138        mData[mPos++] = (byte)((v >> 8) & 0xff);
139        mData[mPos++] = (byte)((v >> 16) & 0xff);
140        mData[mPos++] = (byte)((v >> 24) & 0xff);
141        mData[mPos++] = (byte)((v >> 32) & 0xff);
142        mData[mPos++] = (byte)((v >> 40) & 0xff);
143        mData[mPos++] = (byte)((v >> 48) & 0xff);
144        mData[mPos++] = (byte)((v >> 56) & 0xff);
145    }
146
147    public long subI64() {
148        subalign(8);
149        long v = 0;
150        byte x = 0;
151        x = ((mData[--mPos]));
152        v = (long)(v | (((long)x) & 0xff) << 56l);
153        x = ((mData[--mPos]));
154        v = (long)(v | (((long)x) & 0xff) << 48l);
155        x = ((mData[--mPos]));
156        v = (long)(v | (((long)x) & 0xff) << 40l);
157        x = ((mData[--mPos]));
158        v = (long)(v | (((long)x) & 0xff) << 32l);
159        x = ((mData[--mPos]));
160        v = (long)(v | (((long)x) & 0xff) << 24l);
161        x = ((mData[--mPos]));
162        v = (long)(v | (((long)x) & 0xff) << 16l);
163        x = ((mData[--mPos]));
164        v = (long)(v | (((long)x) & 0xff) << 8l);
165        x = ((mData[--mPos]));
166        v = (long)(v | (((long)x) & 0xff));
167        return v;
168    }
169
170    public void addU8(short v) {
171        if ((v < 0) || (v > 0xff)) {
172            android.util.Log.e("rs", "FieldPacker.addU8( " + v + " )");
173            throw new IllegalArgumentException("Saving value out of range for type");
174        }
175        mData[mPos++] = (byte)v;
176    }
177
178    public void addU16(int v) {
179        if ((v < 0) || (v > 0xffff)) {
180            android.util.Log.e("rs", "FieldPacker.addU16( " + v + " )");
181            throw new IllegalArgumentException("Saving value out of range for type");
182        }
183        align(2);
184        mData[mPos++] = (byte)(v & 0xff);
185        mData[mPos++] = (byte)(v >> 8);
186    }
187
188    public void addU32(long v) {
189        if ((v < 0) || (v > 0xffffffffL)) {
190            android.util.Log.e("rs", "FieldPacker.addU32( " + v + " )");
191            throw new IllegalArgumentException("Saving value out of range for type");
192        }
193        align(4);
194        mData[mPos++] = (byte)(v & 0xff);
195        mData[mPos++] = (byte)((v >> 8) & 0xff);
196        mData[mPos++] = (byte)((v >> 16) & 0xff);
197        mData[mPos++] = (byte)((v >> 24) & 0xff);
198    }
199
200    public void addU64(long v) {
201        if (v < 0) {
202            android.util.Log.e("rs", "FieldPacker.addU64( " + v + " )");
203            throw new IllegalArgumentException("Saving value out of range for type");
204        }
205        align(8);
206        mData[mPos++] = (byte)(v & 0xff);
207        mData[mPos++] = (byte)((v >> 8) & 0xff);
208        mData[mPos++] = (byte)((v >> 16) & 0xff);
209        mData[mPos++] = (byte)((v >> 24) & 0xff);
210        mData[mPos++] = (byte)((v >> 32) & 0xff);
211        mData[mPos++] = (byte)((v >> 40) & 0xff);
212        mData[mPos++] = (byte)((v >> 48) & 0xff);
213        mData[mPos++] = (byte)((v >> 56) & 0xff);
214    }
215
216    public void addF32(float v) {
217        addI32(Float.floatToRawIntBits(v));
218    }
219
220    public float subF32() {
221        return Float.intBitsToFloat(subI32());
222    }
223
224    public void addF64(double v) {
225        addI64(Double.doubleToRawLongBits(v));
226    }
227
228    public double subF64() {
229        return Double.longBitsToDouble(subI64());
230    }
231
232    public void addObj(BaseObj obj) {
233        if (obj != null) {
234            if (RenderScript.sPointerSize == 8) {
235                addI64(obj.getID(null));
236            }
237            else {
238                addI32((int)obj.getID(null));
239            }
240        } else {
241            if (RenderScript.sPointerSize == 8) {
242                addI64(0);
243            } else {
244                addI32(0);
245            }
246        }
247    }
248
249    public void addF32(Float2 v) {
250        addF32(v.x);
251        addF32(v.y);
252    }
253    public void addF32(Float3 v) {
254        addF32(v.x);
255        addF32(v.y);
256        addF32(v.z);
257    }
258    public void addF32(Float4 v) {
259        addF32(v.x);
260        addF32(v.y);
261        addF32(v.z);
262        addF32(v.w);
263    }
264
265    public void addF64(Double2 v) {
266        addF64(v.x);
267        addF64(v.y);
268    }
269    public void addF64(Double3 v) {
270        addF64(v.x);
271        addF64(v.y);
272        addF64(v.z);
273    }
274    public void addF64(Double4 v) {
275        addF64(v.x);
276        addF64(v.y);
277        addF64(v.z);
278        addF64(v.w);
279    }
280
281    public void addI8(Byte2 v) {
282        addI8(v.x);
283        addI8(v.y);
284    }
285    public void addI8(Byte3 v) {
286        addI8(v.x);
287        addI8(v.y);
288        addI8(v.z);
289    }
290    public void addI8(Byte4 v) {
291        addI8(v.x);
292        addI8(v.y);
293        addI8(v.z);
294        addI8(v.w);
295    }
296
297    public void addU8(Short2 v) {
298        addU8(v.x);
299        addU8(v.y);
300    }
301    public void addU8(Short3 v) {
302        addU8(v.x);
303        addU8(v.y);
304        addU8(v.z);
305    }
306    public void addU8(Short4 v) {
307        addU8(v.x);
308        addU8(v.y);
309        addU8(v.z);
310        addU8(v.w);
311    }
312
313    public void addI16(Short2 v) {
314        addI16(v.x);
315        addI16(v.y);
316    }
317    public void addI16(Short3 v) {
318        addI16(v.x);
319        addI16(v.y);
320        addI16(v.z);
321    }
322    public void addI16(Short4 v) {
323        addI16(v.x);
324        addI16(v.y);
325        addI16(v.z);
326        addI16(v.w);
327    }
328
329    public void addU16(Int2 v) {
330        addU16(v.x);
331        addU16(v.y);
332    }
333    public void addU16(Int3 v) {
334        addU16(v.x);
335        addU16(v.y);
336        addU16(v.z);
337    }
338    public void addU16(Int4 v) {
339        addU16(v.x);
340        addU16(v.y);
341        addU16(v.z);
342        addU16(v.w);
343    }
344
345    public void addI32(Int2 v) {
346        addI32(v.x);
347        addI32(v.y);
348    }
349    public void addI32(Int3 v) {
350        addI32(v.x);
351        addI32(v.y);
352        addI32(v.z);
353    }
354    public void addI32(Int4 v) {
355        addI32(v.x);
356        addI32(v.y);
357        addI32(v.z);
358        addI32(v.w);
359    }
360
361    public void addU32(Long2 v) {
362        addU32(v.x);
363        addU32(v.y);
364    }
365    public void addU32(Long3 v) {
366        addU32(v.x);
367        addU32(v.y);
368        addU32(v.z);
369    }
370    public void addU32(Long4 v) {
371        addU32(v.x);
372        addU32(v.y);
373        addU32(v.z);
374        addU32(v.w);
375    }
376
377    public void addI64(Long2 v) {
378        addI64(v.x);
379        addI64(v.y);
380    }
381    public void addI64(Long3 v) {
382        addI64(v.x);
383        addI64(v.y);
384        addI64(v.z);
385    }
386    public void addI64(Long4 v) {
387        addI64(v.x);
388        addI64(v.y);
389        addI64(v.z);
390        addI64(v.w);
391    }
392
393    public void addU64(Long2 v) {
394        addU64(v.x);
395        addU64(v.y);
396    }
397    public void addU64(Long3 v) {
398        addU64(v.x);
399        addU64(v.y);
400        addU64(v.z);
401    }
402    public void addU64(Long4 v) {
403        addU64(v.x);
404        addU64(v.y);
405        addU64(v.z);
406        addU64(v.w);
407    }
408
409
410    public Float2 subFloat2() {
411        Float2 v = new Float2();
412        v.y = subF32();
413        v.x = subF32();
414        return v;
415    }
416    public Float3 subFloat3() {
417        Float3 v = new Float3();
418        v.z = subF32();
419        v.y = subF32();
420        v.x = subF32();
421        return v;
422    }
423    public Float4 subFloat4() {
424        Float4 v = new Float4();
425        v.w = subF32();
426        v.z = subF32();
427        v.y = subF32();
428        v.x = subF32();
429        return v;
430    }
431
432    public Double2 subDouble2() {
433        Double2 v = new Double2();
434        v.y = subF64();
435        v.x = subF64();
436        return v;
437    }
438    public Double3 subDouble3() {
439        Double3 v = new Double3();
440        v.z = subF64();
441        v.y = subF64();
442        v.x = subF64();
443        return v;
444    }
445    public Double4 subDouble4() {
446        Double4 v = new Double4();
447        v.w = subF64();
448        v.z = subF64();
449        v.y = subF64();
450        v.x = subF64();
451        return v;
452    }
453
454    public Byte2 subByte2() {
455        Byte2 v = new Byte2();
456        v.y = subI8();
457        v.x = subI8();
458        return v;
459    }
460    public Byte3 subByte3() {
461        Byte3 v = new Byte3();
462        v.z = subI8();
463        v.y = subI8();
464        v.x = subI8();
465        return v;
466    }
467    public Byte4 subByte4() {
468        Byte4 v = new Byte4();
469        v.w = subI8();
470        v.z = subI8();
471        v.y = subI8();
472        v.x = subI8();
473        return v;
474    }
475
476    public Short2 subShort2() {
477        Short2 v = new Short2();
478        v.y = subI16();
479        v.x = subI16();
480        return v;
481    }
482    public Short3 subShort3() {
483        Short3 v = new Short3();
484        v.z = subI16();
485        v.y = subI16();
486        v.x = subI16();
487        return v;
488    }
489    public Short4 subShort4() {
490        Short4 v = new Short4();
491        v.w = subI16();
492        v.z = subI16();
493        v.y = subI16();
494        v.x = subI16();
495        return v;
496    }
497
498    public Int2 subInt2() {
499        Int2 v = new Int2();
500        v.y = subI32();
501        v.x = subI32();
502        return v;
503    }
504    public Int3 subInt3() {
505        Int3 v = new Int3();
506        v.z = subI32();
507        v.y = subI32();
508        v.x = subI32();
509        return v;
510    }
511    public Int4 subInt4() {
512        Int4 v = new Int4();
513        v.w = subI32();
514        v.z = subI32();
515        v.y = subI32();
516        v.x = subI32();
517        return v;
518    }
519
520    public Long2 subLong2() {
521        Long2 v = new Long2();
522        v.y = subI64();
523        v.x = subI64();
524        return v;
525    }
526    public Long3 subLong3() {
527        Long3 v = new Long3();
528        v.z = subI64();
529        v.y = subI64();
530        v.x = subI64();
531        return v;
532    }
533    public Long4 subLong4() {
534        Long4 v = new Long4();
535        v.w = subI64();
536        v.z = subI64();
537        v.y = subI64();
538        v.x = subI64();
539        return v;
540    }
541
542
543
544    public void addMatrix(Matrix4f v) {
545        for (int i=0; i < v.mMat.length; i++) {
546            addF32(v.mMat[i]);
547        }
548    }
549
550    public Matrix4f subMatrix4f() {
551        Matrix4f v = new Matrix4f();
552        for (int i = v.mMat.length - 1; i >= 0; i--) {
553            v.mMat[i] = subF32();
554        }
555        return v;
556    }
557
558    public void addMatrix(Matrix3f v) {
559        for (int i=0; i < v.mMat.length; i++) {
560            addF32(v.mMat[i]);
561        }
562    }
563
564    public Matrix3f subMatrix3f() {
565        Matrix3f v = new Matrix3f();
566        for (int i = v.mMat.length - 1; i >= 0; i--) {
567            v.mMat[i] = subF32();
568        }
569        return v;
570    }
571
572    public void addMatrix(Matrix2f v) {
573        for (int i=0; i < v.mMat.length; i++) {
574            addF32(v.mMat[i]);
575        }
576    }
577
578    public Matrix2f subMatrix2f() {
579        Matrix2f v = new Matrix2f();
580        for (int i = v.mMat.length - 1; i >= 0; i--) {
581            v.mMat[i] = subF32();
582        }
583        return v;
584    }
585
586    public void addBoolean(boolean v) {
587        addI8((byte)(v ? 1 : 0));
588    }
589
590    public boolean subBoolean() {
591        byte v = subI8();
592        if (v == 1) {
593            return true;
594        }
595        return false;
596    }
597
598    public final byte[] getData() {
599        return mData;
600    }
601
602    private final byte mData[];
603    private int mPos;
604    private int mLen;
605    private BitSet mAlignment;
606
607}
608
609
610