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