FieldPacker.java revision 7f22d0154532a2b65a3f300a25369bf66e3f6cf4
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                addI64(0);
237                addI64(0);
238                addI64(0);
239            }
240            else {
241                addI32((int)obj.getID(null));
242            }
243        } else {
244            if (RenderScript.sPointerSize == 8) {
245                addI64(0);
246                addI64(0);
247                addI64(0);
248                addI64(0);
249            } else {
250                addI32(0);
251            }
252        }
253    }
254
255    public void addF32(Float2 v) {
256        addF32(v.x);
257        addF32(v.y);
258    }
259    public void addF32(Float3 v) {
260        addF32(v.x);
261        addF32(v.y);
262        addF32(v.z);
263    }
264    public void addF32(Float4 v) {
265        addF32(v.x);
266        addF32(v.y);
267        addF32(v.z);
268        addF32(v.w);
269    }
270
271    public void addF64(Double2 v) {
272        addF64(v.x);
273        addF64(v.y);
274    }
275    public void addF64(Double3 v) {
276        addF64(v.x);
277        addF64(v.y);
278        addF64(v.z);
279    }
280    public void addF64(Double4 v) {
281        addF64(v.x);
282        addF64(v.y);
283        addF64(v.z);
284        addF64(v.w);
285    }
286
287    public void addI8(Byte2 v) {
288        addI8(v.x);
289        addI8(v.y);
290    }
291    public void addI8(Byte3 v) {
292        addI8(v.x);
293        addI8(v.y);
294        addI8(v.z);
295    }
296    public void addI8(Byte4 v) {
297        addI8(v.x);
298        addI8(v.y);
299        addI8(v.z);
300        addI8(v.w);
301    }
302
303    public void addU8(Short2 v) {
304        addU8(v.x);
305        addU8(v.y);
306    }
307    public void addU8(Short3 v) {
308        addU8(v.x);
309        addU8(v.y);
310        addU8(v.z);
311    }
312    public void addU8(Short4 v) {
313        addU8(v.x);
314        addU8(v.y);
315        addU8(v.z);
316        addU8(v.w);
317    }
318
319    public void addI16(Short2 v) {
320        addI16(v.x);
321        addI16(v.y);
322    }
323    public void addI16(Short3 v) {
324        addI16(v.x);
325        addI16(v.y);
326        addI16(v.z);
327    }
328    public void addI16(Short4 v) {
329        addI16(v.x);
330        addI16(v.y);
331        addI16(v.z);
332        addI16(v.w);
333    }
334
335    public void addU16(Int2 v) {
336        addU16(v.x);
337        addU16(v.y);
338    }
339    public void addU16(Int3 v) {
340        addU16(v.x);
341        addU16(v.y);
342        addU16(v.z);
343    }
344    public void addU16(Int4 v) {
345        addU16(v.x);
346        addU16(v.y);
347        addU16(v.z);
348        addU16(v.w);
349    }
350
351    public void addI32(Int2 v) {
352        addI32(v.x);
353        addI32(v.y);
354    }
355    public void addI32(Int3 v) {
356        addI32(v.x);
357        addI32(v.y);
358        addI32(v.z);
359    }
360    public void addI32(Int4 v) {
361        addI32(v.x);
362        addI32(v.y);
363        addI32(v.z);
364        addI32(v.w);
365    }
366
367    public void addU32(Long2 v) {
368        addU32(v.x);
369        addU32(v.y);
370    }
371    public void addU32(Long3 v) {
372        addU32(v.x);
373        addU32(v.y);
374        addU32(v.z);
375    }
376    public void addU32(Long4 v) {
377        addU32(v.x);
378        addU32(v.y);
379        addU32(v.z);
380        addU32(v.w);
381    }
382
383    public void addI64(Long2 v) {
384        addI64(v.x);
385        addI64(v.y);
386    }
387    public void addI64(Long3 v) {
388        addI64(v.x);
389        addI64(v.y);
390        addI64(v.z);
391    }
392    public void addI64(Long4 v) {
393        addI64(v.x);
394        addI64(v.y);
395        addI64(v.z);
396        addI64(v.w);
397    }
398
399    public void addU64(Long2 v) {
400        addU64(v.x);
401        addU64(v.y);
402    }
403    public void addU64(Long3 v) {
404        addU64(v.x);
405        addU64(v.y);
406        addU64(v.z);
407    }
408    public void addU64(Long4 v) {
409        addU64(v.x);
410        addU64(v.y);
411        addU64(v.z);
412        addU64(v.w);
413    }
414
415
416    public Float2 subFloat2() {
417        Float2 v = new Float2();
418        v.y = subF32();
419        v.x = subF32();
420        return v;
421    }
422    public Float3 subFloat3() {
423        Float3 v = new Float3();
424        v.z = subF32();
425        v.y = subF32();
426        v.x = subF32();
427        return v;
428    }
429    public Float4 subFloat4() {
430        Float4 v = new Float4();
431        v.w = subF32();
432        v.z = subF32();
433        v.y = subF32();
434        v.x = subF32();
435        return v;
436    }
437
438    public Double2 subDouble2() {
439        Double2 v = new Double2();
440        v.y = subF64();
441        v.x = subF64();
442        return v;
443    }
444    public Double3 subDouble3() {
445        Double3 v = new Double3();
446        v.z = subF64();
447        v.y = subF64();
448        v.x = subF64();
449        return v;
450    }
451    public Double4 subDouble4() {
452        Double4 v = new Double4();
453        v.w = subF64();
454        v.z = subF64();
455        v.y = subF64();
456        v.x = subF64();
457        return v;
458    }
459
460    public Byte2 subByte2() {
461        Byte2 v = new Byte2();
462        v.y = subI8();
463        v.x = subI8();
464        return v;
465    }
466    public Byte3 subByte3() {
467        Byte3 v = new Byte3();
468        v.z = subI8();
469        v.y = subI8();
470        v.x = subI8();
471        return v;
472    }
473    public Byte4 subByte4() {
474        Byte4 v = new Byte4();
475        v.w = subI8();
476        v.z = subI8();
477        v.y = subI8();
478        v.x = subI8();
479        return v;
480    }
481
482    public Short2 subShort2() {
483        Short2 v = new Short2();
484        v.y = subI16();
485        v.x = subI16();
486        return v;
487    }
488    public Short3 subShort3() {
489        Short3 v = new Short3();
490        v.z = subI16();
491        v.y = subI16();
492        v.x = subI16();
493        return v;
494    }
495    public Short4 subShort4() {
496        Short4 v = new Short4();
497        v.w = subI16();
498        v.z = subI16();
499        v.y = subI16();
500        v.x = subI16();
501        return v;
502    }
503
504    public Int2 subInt2() {
505        Int2 v = new Int2();
506        v.y = subI32();
507        v.x = subI32();
508        return v;
509    }
510    public Int3 subInt3() {
511        Int3 v = new Int3();
512        v.z = subI32();
513        v.y = subI32();
514        v.x = subI32();
515        return v;
516    }
517    public Int4 subInt4() {
518        Int4 v = new Int4();
519        v.w = subI32();
520        v.z = subI32();
521        v.y = subI32();
522        v.x = subI32();
523        return v;
524    }
525
526    public Long2 subLong2() {
527        Long2 v = new Long2();
528        v.y = subI64();
529        v.x = subI64();
530        return v;
531    }
532    public Long3 subLong3() {
533        Long3 v = new Long3();
534        v.z = subI64();
535        v.y = subI64();
536        v.x = subI64();
537        return v;
538    }
539    public Long4 subLong4() {
540        Long4 v = new Long4();
541        v.w = subI64();
542        v.z = subI64();
543        v.y = subI64();
544        v.x = subI64();
545        return v;
546    }
547
548
549
550    public void addMatrix(Matrix4f v) {
551        for (int i=0; i < v.mMat.length; i++) {
552            addF32(v.mMat[i]);
553        }
554    }
555
556    public Matrix4f subMatrix4f() {
557        Matrix4f v = new Matrix4f();
558        for (int i = v.mMat.length - 1; i >= 0; i--) {
559            v.mMat[i] = subF32();
560        }
561        return v;
562    }
563
564    public void addMatrix(Matrix3f v) {
565        for (int i=0; i < v.mMat.length; i++) {
566            addF32(v.mMat[i]);
567        }
568    }
569
570    public Matrix3f subMatrix3f() {
571        Matrix3f v = new Matrix3f();
572        for (int i = v.mMat.length - 1; i >= 0; i--) {
573            v.mMat[i] = subF32();
574        }
575        return v;
576    }
577
578    public void addMatrix(Matrix2f v) {
579        for (int i=0; i < v.mMat.length; i++) {
580            addF32(v.mMat[i]);
581        }
582    }
583
584    public Matrix2f subMatrix2f() {
585        Matrix2f v = new Matrix2f();
586        for (int i = v.mMat.length - 1; i >= 0; i--) {
587            v.mMat[i] = subF32();
588        }
589        return v;
590    }
591
592    public void addBoolean(boolean v) {
593        addI8((byte)(v ? 1 : 0));
594    }
595
596    public boolean subBoolean() {
597        byte v = subI8();
598        if (v == 1) {
599            return true;
600        }
601        return false;
602    }
603
604    public final byte[] getData() {
605        return mData;
606    }
607
608    /**
609     * Get the actual length used for the FieldPacker.
610     *
611     * @hide
612     */
613    public int getPos() {
614        return mPos;
615    }
616
617    private final byte mData[];
618    private int mPos;
619    private int mLen;
620    private BitSet mAlignment;
621
622}
623
624
625