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