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