Home | History | Annotate | Download | only in renderscript
      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 
     17 package android.renderscript;
     18 
     19 import 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  **/
     30 public 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     static FieldPacker createFromArray(Object[] args) {
     51         FieldPacker fp = new FieldPacker(RenderScript.sPointerSize * 8);
     52         for (Object arg : args) {
     53             fp.addSafely(arg);
     54         }
     55         fp.resize(fp.mPos);
     56         return fp;
     57     }
     58 
     59     public void align(int v) {
     60         if ((v <= 0) || ((v & (v - 1)) != 0)) {
     61             throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v);
     62         }
     63 
     64         while ((mPos & (v - 1)) != 0) {
     65             mAlignment.flip(mPos);
     66             mData[mPos++] = 0;
     67         }
     68     }
     69 
     70     public void subalign(int v) {
     71         if ((v & (v - 1)) != 0) {
     72             throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v);
     73         }
     74 
     75         while ((mPos & (v - 1)) != 0) {
     76             mPos--;
     77         }
     78 
     79         if (mPos > 0) {
     80             while (mAlignment.get(mPos - 1) == true) {
     81                 mPos--;
     82                 mAlignment.flip(mPos);
     83             }
     84         }
     85 
     86     }
     87 
     88     public void reset() {
     89         mPos = 0;
     90     }
     91     public void reset(int i) {
     92         if ((i < 0) || (i > mLen)) {
     93             throw new RSIllegalArgumentException("out of range argument: " + i);
     94         }
     95         mPos = i;
     96     }
     97 
     98     public void skip(int i) {
     99         int res = mPos + i;
    100         if ((res < 0) || (res > mLen)) {
    101             throw new RSIllegalArgumentException("out of range argument: " + i);
    102         }
    103         mPos = res;
    104     }
    105 
    106     public void addI8(byte v) {
    107         mData[mPos++] = v;
    108     }
    109 
    110     public byte subI8() {
    111         subalign(1);
    112         return mData[--mPos];
    113     }
    114 
    115     public void addI16(short v) {
    116         align(2);
    117         mData[mPos++] = (byte)(v & 0xff);
    118         mData[mPos++] = (byte)(v >> 8);
    119     }
    120 
    121     public short subI16() {
    122         subalign(2);
    123         short v = 0;
    124         v = (short)((mData[--mPos] & 0xff) << 8);
    125         v = (short)(v | (short)(mData[--mPos] & 0xff));
    126         return v;
    127     }
    128 
    129 
    130     public void addI32(int v) {
    131         align(4);
    132         mData[mPos++] = (byte)(v & 0xff);
    133         mData[mPos++] = (byte)((v >> 8) & 0xff);
    134         mData[mPos++] = (byte)((v >> 16) & 0xff);
    135         mData[mPos++] = (byte)((v >> 24) & 0xff);
    136     }
    137 
    138     public int subI32() {
    139         subalign(4);
    140         int v = 0;
    141         v = ((mData[--mPos] & 0xff) << 24);
    142         v = v | ((mData[--mPos] & 0xff) << 16);
    143         v = v | ((mData[--mPos] & 0xff) << 8);
    144         v = v | ((mData[--mPos] & 0xff));
    145         return v;
    146     }
    147 
    148 
    149     public void addI64(long v) {
    150         align(8);
    151         mData[mPos++] = (byte)(v & 0xff);
    152         mData[mPos++] = (byte)((v >> 8) & 0xff);
    153         mData[mPos++] = (byte)((v >> 16) & 0xff);
    154         mData[mPos++] = (byte)((v >> 24) & 0xff);
    155         mData[mPos++] = (byte)((v >> 32) & 0xff);
    156         mData[mPos++] = (byte)((v >> 40) & 0xff);
    157         mData[mPos++] = (byte)((v >> 48) & 0xff);
    158         mData[mPos++] = (byte)((v >> 56) & 0xff);
    159     }
    160 
    161     public long subI64() {
    162         subalign(8);
    163         long v = 0;
    164         byte x = 0;
    165         x = ((mData[--mPos]));
    166         v = (long)(v | (((long)x) & 0xff) << 56l);
    167         x = ((mData[--mPos]));
    168         v = (long)(v | (((long)x) & 0xff) << 48l);
    169         x = ((mData[--mPos]));
    170         v = (long)(v | (((long)x) & 0xff) << 40l);
    171         x = ((mData[--mPos]));
    172         v = (long)(v | (((long)x) & 0xff) << 32l);
    173         x = ((mData[--mPos]));
    174         v = (long)(v | (((long)x) & 0xff) << 24l);
    175         x = ((mData[--mPos]));
    176         v = (long)(v | (((long)x) & 0xff) << 16l);
    177         x = ((mData[--mPos]));
    178         v = (long)(v | (((long)x) & 0xff) << 8l);
    179         x = ((mData[--mPos]));
    180         v = (long)(v | (((long)x) & 0xff));
    181         return v;
    182     }
    183 
    184     public void addU8(short v) {
    185         if ((v < 0) || (v > 0xff)) {
    186             android.util.Log.e("rs", "FieldPacker.addU8( " + v + " )");
    187             throw new IllegalArgumentException("Saving value out of range for type");
    188         }
    189         mData[mPos++] = (byte)v;
    190     }
    191 
    192     public void addU16(int v) {
    193         if ((v < 0) || (v > 0xffff)) {
    194             android.util.Log.e("rs", "FieldPacker.addU16( " + v + " )");
    195             throw new IllegalArgumentException("Saving value out of range for type");
    196         }
    197         align(2);
    198         mData[mPos++] = (byte)(v & 0xff);
    199         mData[mPos++] = (byte)(v >> 8);
    200     }
    201 
    202     public void addU32(long v) {
    203         if ((v < 0) || (v > 0xffffffffL)) {
    204             android.util.Log.e("rs", "FieldPacker.addU32( " + v + " )");
    205             throw new IllegalArgumentException("Saving value out of range for type");
    206         }
    207         align(4);
    208         mData[mPos++] = (byte)(v & 0xff);
    209         mData[mPos++] = (byte)((v >> 8) & 0xff);
    210         mData[mPos++] = (byte)((v >> 16) & 0xff);
    211         mData[mPos++] = (byte)((v >> 24) & 0xff);
    212     }
    213 
    214     public void addU64(long v) {
    215         if (v < 0) {
    216             android.util.Log.e("rs", "FieldPacker.addU64( " + v + " )");
    217             throw new IllegalArgumentException("Saving value out of range for type");
    218         }
    219         align(8);
    220         mData[mPos++] = (byte)(v & 0xff);
    221         mData[mPos++] = (byte)((v >> 8) & 0xff);
    222         mData[mPos++] = (byte)((v >> 16) & 0xff);
    223         mData[mPos++] = (byte)((v >> 24) & 0xff);
    224         mData[mPos++] = (byte)((v >> 32) & 0xff);
    225         mData[mPos++] = (byte)((v >> 40) & 0xff);
    226         mData[mPos++] = (byte)((v >> 48) & 0xff);
    227         mData[mPos++] = (byte)((v >> 56) & 0xff);
    228     }
    229 
    230     public void addF32(float v) {
    231         addI32(Float.floatToRawIntBits(v));
    232     }
    233 
    234     public float subF32() {
    235         return Float.intBitsToFloat(subI32());
    236     }
    237 
    238     public void addF64(double v) {
    239         addI64(Double.doubleToRawLongBits(v));
    240     }
    241 
    242     public double subF64() {
    243         return Double.longBitsToDouble(subI64());
    244     }
    245 
    246     public void addObj(BaseObj obj) {
    247         if (obj != null) {
    248             if (RenderScript.sPointerSize == 8) {
    249                 addI64(obj.getID(null));
    250                 addI64(0);
    251                 addI64(0);
    252                 addI64(0);
    253             } else {
    254                 addI32((int)obj.getID(null));
    255             }
    256         } else {
    257             if (RenderScript.sPointerSize == 8) {
    258                 addI64(0);
    259                 addI64(0);
    260                 addI64(0);
    261                 addI64(0);
    262             } else {
    263                 addI32(0);
    264             }
    265         }
    266     }
    267 
    268     public void addF32(Float2 v) {
    269         addF32(v.x);
    270         addF32(v.y);
    271     }
    272     public void addF32(Float3 v) {
    273         addF32(v.x);
    274         addF32(v.y);
    275         addF32(v.z);
    276     }
    277     public void addF32(Float4 v) {
    278         addF32(v.x);
    279         addF32(v.y);
    280         addF32(v.z);
    281         addF32(v.w);
    282     }
    283 
    284     public void addF64(Double2 v) {
    285         addF64(v.x);
    286         addF64(v.y);
    287     }
    288     public void addF64(Double3 v) {
    289         addF64(v.x);
    290         addF64(v.y);
    291         addF64(v.z);
    292     }
    293     public void addF64(Double4 v) {
    294         addF64(v.x);
    295         addF64(v.y);
    296         addF64(v.z);
    297         addF64(v.w);
    298     }
    299 
    300     public void addI8(Byte2 v) {
    301         addI8(v.x);
    302         addI8(v.y);
    303     }
    304     public void addI8(Byte3 v) {
    305         addI8(v.x);
    306         addI8(v.y);
    307         addI8(v.z);
    308     }
    309     public void addI8(Byte4 v) {
    310         addI8(v.x);
    311         addI8(v.y);
    312         addI8(v.z);
    313         addI8(v.w);
    314     }
    315 
    316     public void addU8(Short2 v) {
    317         addU8(v.x);
    318         addU8(v.y);
    319     }
    320     public void addU8(Short3 v) {
    321         addU8(v.x);
    322         addU8(v.y);
    323         addU8(v.z);
    324     }
    325     public void addU8(Short4 v) {
    326         addU8(v.x);
    327         addU8(v.y);
    328         addU8(v.z);
    329         addU8(v.w);
    330     }
    331 
    332     public void addI16(Short2 v) {
    333         addI16(v.x);
    334         addI16(v.y);
    335     }
    336     public void addI16(Short3 v) {
    337         addI16(v.x);
    338         addI16(v.y);
    339         addI16(v.z);
    340     }
    341     public void addI16(Short4 v) {
    342         addI16(v.x);
    343         addI16(v.y);
    344         addI16(v.z);
    345         addI16(v.w);
    346     }
    347 
    348     public void addU16(Int2 v) {
    349         addU16(v.x);
    350         addU16(v.y);
    351     }
    352     public void addU16(Int3 v) {
    353         addU16(v.x);
    354         addU16(v.y);
    355         addU16(v.z);
    356     }
    357     public void addU16(Int4 v) {
    358         addU16(v.x);
    359         addU16(v.y);
    360         addU16(v.z);
    361         addU16(v.w);
    362     }
    363 
    364     public void addI32(Int2 v) {
    365         addI32(v.x);
    366         addI32(v.y);
    367     }
    368     public void addI32(Int3 v) {
    369         addI32(v.x);
    370         addI32(v.y);
    371         addI32(v.z);
    372     }
    373     public void addI32(Int4 v) {
    374         addI32(v.x);
    375         addI32(v.y);
    376         addI32(v.z);
    377         addI32(v.w);
    378     }
    379 
    380     public void addU32(Long2 v) {
    381         addU32(v.x);
    382         addU32(v.y);
    383     }
    384     public void addU32(Long3 v) {
    385         addU32(v.x);
    386         addU32(v.y);
    387         addU32(v.z);
    388     }
    389     public void addU32(Long4 v) {
    390         addU32(v.x);
    391         addU32(v.y);
    392         addU32(v.z);
    393         addU32(v.w);
    394     }
    395 
    396     public void addI64(Long2 v) {
    397         addI64(v.x);
    398         addI64(v.y);
    399     }
    400     public void addI64(Long3 v) {
    401         addI64(v.x);
    402         addI64(v.y);
    403         addI64(v.z);
    404     }
    405     public void addI64(Long4 v) {
    406         addI64(v.x);
    407         addI64(v.y);
    408         addI64(v.z);
    409         addI64(v.w);
    410     }
    411 
    412     public void addU64(Long2 v) {
    413         addU64(v.x);
    414         addU64(v.y);
    415     }
    416     public void addU64(Long3 v) {
    417         addU64(v.x);
    418         addU64(v.y);
    419         addU64(v.z);
    420     }
    421     public void addU64(Long4 v) {
    422         addU64(v.x);
    423         addU64(v.y);
    424         addU64(v.z);
    425         addU64(v.w);
    426     }
    427 
    428 
    429     public Float2 subFloat2() {
    430         Float2 v = new Float2();
    431         v.y = subF32();
    432         v.x = subF32();
    433         return v;
    434     }
    435     public Float3 subFloat3() {
    436         Float3 v = new Float3();
    437         v.z = subF32();
    438         v.y = subF32();
    439         v.x = subF32();
    440         return v;
    441     }
    442     public Float4 subFloat4() {
    443         Float4 v = new Float4();
    444         v.w = subF32();
    445         v.z = subF32();
    446         v.y = subF32();
    447         v.x = subF32();
    448         return v;
    449     }
    450 
    451     public Double2 subDouble2() {
    452         Double2 v = new Double2();
    453         v.y = subF64();
    454         v.x = subF64();
    455         return v;
    456     }
    457     public Double3 subDouble3() {
    458         Double3 v = new Double3();
    459         v.z = subF64();
    460         v.y = subF64();
    461         v.x = subF64();
    462         return v;
    463     }
    464     public Double4 subDouble4() {
    465         Double4 v = new Double4();
    466         v.w = subF64();
    467         v.z = subF64();
    468         v.y = subF64();
    469         v.x = subF64();
    470         return v;
    471     }
    472 
    473     public Byte2 subByte2() {
    474         Byte2 v = new Byte2();
    475         v.y = subI8();
    476         v.x = subI8();
    477         return v;
    478     }
    479     public Byte3 subByte3() {
    480         Byte3 v = new Byte3();
    481         v.z = subI8();
    482         v.y = subI8();
    483         v.x = subI8();
    484         return v;
    485     }
    486     public Byte4 subByte4() {
    487         Byte4 v = new Byte4();
    488         v.w = subI8();
    489         v.z = subI8();
    490         v.y = subI8();
    491         v.x = subI8();
    492         return v;
    493     }
    494 
    495     public Short2 subShort2() {
    496         Short2 v = new Short2();
    497         v.y = subI16();
    498         v.x = subI16();
    499         return v;
    500     }
    501     public Short3 subShort3() {
    502         Short3 v = new Short3();
    503         v.z = subI16();
    504         v.y = subI16();
    505         v.x = subI16();
    506         return v;
    507     }
    508     public Short4 subShort4() {
    509         Short4 v = new Short4();
    510         v.w = subI16();
    511         v.z = subI16();
    512         v.y = subI16();
    513         v.x = subI16();
    514         return v;
    515     }
    516 
    517     public Int2 subInt2() {
    518         Int2 v = new Int2();
    519         v.y = subI32();
    520         v.x = subI32();
    521         return v;
    522     }
    523     public Int3 subInt3() {
    524         Int3 v = new Int3();
    525         v.z = subI32();
    526         v.y = subI32();
    527         v.x = subI32();
    528         return v;
    529     }
    530     public Int4 subInt4() {
    531         Int4 v = new Int4();
    532         v.w = subI32();
    533         v.z = subI32();
    534         v.y = subI32();
    535         v.x = subI32();
    536         return v;
    537     }
    538 
    539     public Long2 subLong2() {
    540         Long2 v = new Long2();
    541         v.y = subI64();
    542         v.x = subI64();
    543         return v;
    544     }
    545     public Long3 subLong3() {
    546         Long3 v = new Long3();
    547         v.z = subI64();
    548         v.y = subI64();
    549         v.x = subI64();
    550         return v;
    551     }
    552     public Long4 subLong4() {
    553         Long4 v = new Long4();
    554         v.w = subI64();
    555         v.z = subI64();
    556         v.y = subI64();
    557         v.x = subI64();
    558         return v;
    559     }
    560 
    561 
    562 
    563     public void addMatrix(Matrix4f v) {
    564         for (int i=0; i < v.mMat.length; i++) {
    565             addF32(v.mMat[i]);
    566         }
    567     }
    568 
    569     public Matrix4f subMatrix4f() {
    570         Matrix4f v = new Matrix4f();
    571         for (int i = v.mMat.length - 1; i >= 0; i--) {
    572             v.mMat[i] = subF32();
    573         }
    574         return v;
    575     }
    576 
    577     public void addMatrix(Matrix3f v) {
    578         for (int i=0; i < v.mMat.length; i++) {
    579             addF32(v.mMat[i]);
    580         }
    581     }
    582 
    583     public Matrix3f subMatrix3f() {
    584         Matrix3f v = new Matrix3f();
    585         for (int i = v.mMat.length - 1; i >= 0; i--) {
    586             v.mMat[i] = subF32();
    587         }
    588         return v;
    589     }
    590 
    591     public void addMatrix(Matrix2f v) {
    592         for (int i=0; i < v.mMat.length; i++) {
    593             addF32(v.mMat[i]);
    594         }
    595     }
    596 
    597     public Matrix2f subMatrix2f() {
    598         Matrix2f v = new Matrix2f();
    599         for (int i = v.mMat.length - 1; i >= 0; i--) {
    600             v.mMat[i] = subF32();
    601         }
    602         return v;
    603     }
    604 
    605     public void addBoolean(boolean v) {
    606         addI8((byte)(v ? 1 : 0));
    607     }
    608 
    609     public boolean subBoolean() {
    610         byte v = subI8();
    611         if (v == 1) {
    612             return true;
    613         }
    614         return false;
    615     }
    616 
    617     public final byte[] getData() {
    618         return mData;
    619     }
    620 
    621     /**
    622      * Get the actual length used for the FieldPacker.
    623      *
    624      * @hide
    625      */
    626     public int getPos() {
    627         return mPos;
    628     }
    629 
    630     private void add(Object obj) {
    631         if (obj instanceof Boolean) {
    632             addBoolean((Boolean)obj);
    633             return;
    634         }
    635 
    636         if (obj instanceof Byte) {
    637             addI8((Byte)obj);
    638             return;
    639         }
    640 
    641         if (obj instanceof Short) {
    642             addI16((Short)obj);
    643             return;
    644         }
    645 
    646         if (obj instanceof Integer) {
    647             addI32((Integer)obj);
    648             return;
    649         }
    650 
    651         if (obj instanceof Long) {
    652             addI64((Long)obj);
    653             return;
    654         }
    655 
    656         if (obj instanceof Float) {
    657             addF32((Float)obj);
    658             return;
    659         }
    660 
    661         if (obj instanceof Double) {
    662             addF64((Double)obj);
    663             return;
    664         }
    665 
    666         if (obj instanceof Byte2) {
    667             addI8((Byte2)obj);
    668             return;
    669         }
    670 
    671         if (obj instanceof Byte3) {
    672             addI8((Byte3)obj);
    673             return;
    674         }
    675 
    676         if (obj instanceof Byte4) {
    677             addI8((Byte4)obj);
    678             return;
    679         }
    680 
    681         if (obj instanceof Short2) {
    682             addI16((Short2)obj);
    683             return;
    684         }
    685 
    686         if (obj instanceof Short3) {
    687             addI16((Short3)obj);
    688             return;
    689         }
    690 
    691         if (obj instanceof Short4) {
    692             addI16((Short4)obj);
    693             return;
    694         }
    695 
    696         if (obj instanceof Int2) {
    697             addI32((Int2)obj);
    698             return;
    699         }
    700 
    701         if (obj instanceof Int3) {
    702             addI32((Int3)obj);
    703             return;
    704         }
    705 
    706         if (obj instanceof Int4) {
    707             addI32((Int4)obj);
    708             return;
    709         }
    710 
    711         if (obj instanceof Long2) {
    712             addI64((Long2)obj);
    713             return;
    714         }
    715 
    716         if (obj instanceof Long3) {
    717             addI64((Long3)obj);
    718             return;
    719         }
    720 
    721         if (obj instanceof Long4) {
    722             addI64((Long4)obj);
    723             return;
    724         }
    725 
    726         if (obj instanceof Float2) {
    727             addF32((Float2)obj);
    728             return;
    729         }
    730 
    731         if (obj instanceof Float3) {
    732             addF32((Float3)obj);
    733             return;
    734         }
    735 
    736         if (obj instanceof Float4) {
    737             addF32((Float4)obj);
    738             return;
    739         }
    740 
    741         if (obj instanceof Double2) {
    742             addF64((Double2)obj);
    743             return;
    744         }
    745 
    746         if (obj instanceof Double3) {
    747             addF64((Double3)obj);
    748             return;
    749         }
    750 
    751         if (obj instanceof Double4) {
    752             addF64((Double4)obj);
    753             return;
    754         }
    755 
    756         if (obj instanceof Matrix2f) {
    757             addMatrix((Matrix2f)obj);
    758             return;
    759         }
    760 
    761         if (obj instanceof Matrix3f) {
    762             addMatrix((Matrix3f)obj);
    763             return;
    764         }
    765 
    766         if (obj instanceof Matrix4f) {
    767             addMatrix((Matrix4f)obj);
    768             return;
    769         }
    770 
    771         if (obj instanceof BaseObj) {
    772             addObj((BaseObj)obj);
    773             return;
    774         }
    775     }
    776 
    777     private boolean resize(int newSize) {
    778         if (newSize == mLen) {
    779             return false;
    780         }
    781 
    782         byte[] newData = new byte[newSize];
    783         System.arraycopy(mData, 0, newData, 0, mPos);
    784         mData = newData;
    785         mLen = newSize;
    786         return true;
    787     }
    788 
    789     private void addSafely(Object obj) {
    790         boolean retry;
    791         final int oldPos = mPos;
    792         do {
    793             retry = false;
    794             try {
    795                 add(obj);
    796             } catch (ArrayIndexOutOfBoundsException e) {
    797                 mPos = oldPos;
    798                 resize(mLen * 2);
    799                 retry = true;
    800             }
    801         } while (retry);
    802     }
    803 
    804     private byte mData[];
    805     private int mPos;
    806     private int mLen;
    807     private BitSet mAlignment;
    808 }
    809