Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2010 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 com.android.gallery3d.ui;
     18 
     19 import java.nio.Buffer;
     20 import java.nio.ByteBuffer;
     21 import java.nio.ByteOrder;
     22 import java.nio.CharBuffer;
     23 import java.nio.DoubleBuffer;
     24 import java.nio.FloatBuffer;
     25 import java.nio.IntBuffer;
     26 import java.nio.LongBuffer;
     27 import java.nio.ShortBuffer;
     28 
     29 import javax.microedition.khronos.opengles.GL10;
     30 
     31 public class PointerInfo {
     32 
     33     /**
     34      * The number of coordinates per vertex. 1..4
     35      */
     36     public int mSize;
     37 
     38     /**
     39      * The type of each coordinate.
     40      */
     41     public int mType;
     42 
     43     /**
     44      * The byte offset between consecutive vertices. 0 means mSize *
     45      * sizeof(mType)
     46      */
     47     public int mStride;
     48     public Buffer mPointer;
     49     public ByteBuffer mTempByteBuffer;
     50 
     51     public PointerInfo(int size, int type, int stride, Buffer pointer) {
     52         mSize = size;
     53         mType = type;
     54         mStride = stride;
     55         mPointer = pointer;
     56     }
     57 
     58     private int getStride() {
     59         return mStride > 0 ? mStride : sizeof(mType) * mSize;
     60     }
     61 
     62     public void bindByteBuffer() {
     63         mTempByteBuffer = mPointer == null ? null : toByteBuffer(-1, mPointer);
     64     }
     65 
     66     public void unbindByteBuffer() {
     67         mTempByteBuffer = null;
     68     }
     69 
     70     private static int sizeof(int type) {
     71         switch (type) {
     72         case GL10.GL_UNSIGNED_BYTE:
     73             return 1;
     74         case GL10.GL_BYTE:
     75             return 1;
     76         case GL10.GL_SHORT:
     77             return 2;
     78         case GL10.GL_FIXED:
     79             return 4;
     80         case GL10.GL_FLOAT:
     81             return 4;
     82         default:
     83             return 0;
     84         }
     85     }
     86 
     87     private static ByteBuffer toByteBuffer(int byteCount, Buffer input) {
     88         ByteBuffer result = null;
     89         boolean convertWholeBuffer = (byteCount < 0);
     90         if (input instanceof ByteBuffer) {
     91             ByteBuffer input2 = (ByteBuffer) input;
     92             int position = input2.position();
     93             if (convertWholeBuffer) {
     94                 byteCount = input2.limit() - position;
     95             }
     96             result = ByteBuffer.allocate(byteCount).order(input2.order());
     97             for (int i = 0; i < byteCount; i++) {
     98                 result.put(input2.get());
     99             }
    100             input2.position(position);
    101         } else if (input instanceof CharBuffer) {
    102             CharBuffer input2 = (CharBuffer) input;
    103             int position = input2.position();
    104             if (convertWholeBuffer) {
    105                 byteCount = (input2.limit() - position) * 2;
    106             }
    107             result = ByteBuffer.allocate(byteCount).order(input2.order());
    108             CharBuffer result2 = result.asCharBuffer();
    109             for (int i = 0; i < byteCount / 2; i++) {
    110                 result2.put(input2.get());
    111             }
    112             input2.position(position);
    113         } else if (input instanceof ShortBuffer) {
    114             ShortBuffer input2 = (ShortBuffer) input;
    115             int position = input2.position();
    116             if (convertWholeBuffer) {
    117                 byteCount = (input2.limit() - position)* 2;
    118             }
    119             result = ByteBuffer.allocate(byteCount).order(input2.order());
    120             ShortBuffer result2 = result.asShortBuffer();
    121             for (int i = 0; i < byteCount / 2; i++) {
    122                 result2.put(input2.get());
    123             }
    124             input2.position(position);
    125         } else if (input instanceof IntBuffer) {
    126             IntBuffer input2 = (IntBuffer) input;
    127             int position = input2.position();
    128             if (convertWholeBuffer) {
    129                 byteCount = (input2.limit() - position) * 4;
    130             }
    131             result = ByteBuffer.allocate(byteCount).order(input2.order());
    132             IntBuffer result2 = result.asIntBuffer();
    133             for (int i = 0; i < byteCount / 4; i++) {
    134                 result2.put(input2.get());
    135             }
    136             input2.position(position);
    137         } else if (input instanceof FloatBuffer) {
    138             FloatBuffer input2 = (FloatBuffer) input;
    139             int position = input2.position();
    140             if (convertWholeBuffer) {
    141                 byteCount = (input2.limit() - position) * 4;
    142             }
    143             result = ByteBuffer.allocate(byteCount).order(input2.order());
    144             FloatBuffer result2 = result.asFloatBuffer();
    145             for (int i = 0; i < byteCount / 4; i++) {
    146                 result2.put(input2.get());
    147             }
    148             input2.position(position);
    149         } else if (input instanceof DoubleBuffer) {
    150             DoubleBuffer input2 = (DoubleBuffer) input;
    151             int position = input2.position();
    152             if (convertWholeBuffer) {
    153                 byteCount = (input2.limit() - position) * 8;
    154             }
    155             result = ByteBuffer.allocate(byteCount).order(input2.order());
    156             DoubleBuffer result2 = result.asDoubleBuffer();
    157             for (int i = 0; i < byteCount / 8; i++) {
    158                 result2.put(input2.get());
    159             }
    160             input2.position(position);
    161         } else if (input instanceof LongBuffer) {
    162             LongBuffer input2 = (LongBuffer) input;
    163             int position = input2.position();
    164             if (convertWholeBuffer) {
    165                 byteCount = (input2.limit() - position) * 8;
    166             }
    167             result = ByteBuffer.allocate(byteCount).order(input2.order());
    168             LongBuffer result2 = result.asLongBuffer();
    169             for (int i = 0; i < byteCount / 8; i++) {
    170                 result2.put(input2.get());
    171             }
    172             input2.position(position);
    173         } else {
    174             throw new RuntimeException("Unimplemented Buffer subclass.");
    175         }
    176         result.rewind();
    177         // The OpenGL API will interpret the result in hardware byte order,
    178         // so we better do that as well:
    179         result.order(ByteOrder.nativeOrder());
    180         return result;
    181     }
    182 
    183     public void getArrayElement(int index, double[] result) {
    184         if (mTempByteBuffer == null) {
    185             throw new IllegalArgumentException("undefined pointer");
    186         }
    187         if (mStride < 0) {
    188             throw new IllegalArgumentException("invalid stride");
    189         }
    190 
    191         int stride = getStride();
    192         ByteBuffer byteBuffer = mTempByteBuffer;
    193         int size = mSize;
    194         int type = mType;
    195         int sizeofType = sizeof(type);
    196         int byteOffset = stride * index;
    197 
    198         for (int i = 0; i < size; i++) {
    199             switch (type) {
    200             case GL10.GL_BYTE:
    201             case GL10.GL_UNSIGNED_BYTE:
    202                 result[i] = byteBuffer.get(byteOffset);
    203                 break;
    204             case GL10.GL_SHORT:
    205                 ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
    206                 result[i] = shortBuffer.get(byteOffset / 2);
    207                 break;
    208             case GL10.GL_FIXED:
    209                 IntBuffer intBuffer = byteBuffer.asIntBuffer();
    210                 result[i] = intBuffer.get(byteOffset / 4);
    211                 break;
    212             case GL10.GL_FLOAT:
    213                 FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
    214                 result[i] = floatBuffer.get(byteOffset / 4);
    215                 break;
    216             default:
    217                 throw new UnsupportedOperationException("unknown type");
    218             }
    219             byteOffset += sizeofType;
    220         }
    221     }
    222 }
    223