1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/* 2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project 3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License. 6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at 7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * http://www.apache.org/licenses/LICENSE-2.0 9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software 11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS, 12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and 14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License. 15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.ui; 18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.nio.Buffer; 20f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.nio.ByteBuffer; 21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.nio.ByteOrder; 22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.nio.CharBuffer; 23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.nio.DoubleBuffer; 24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.nio.FloatBuffer; 25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.nio.IntBuffer; 26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.nio.LongBuffer; 27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.nio.ShortBuffer; 28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.opengles.GL10; 30f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class PointerInfo { 32f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin /** 34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * The number of coordinates per vertex. 1..4 35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int mSize; 37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin /** 39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * The type of each coordinate. 40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int mType; 42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin /** 44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * The byte offset between consecutive vertices. 0 means mSize * 45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * sizeof(mType) 46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int mStride; 48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Buffer mPointer; 49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public ByteBuffer mTempByteBuffer; 50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public PointerInfo(int size, int type, int stride, Buffer pointer) { 52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSize = size; 53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mType = type; 54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mStride = stride; 55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mPointer = pointer; 56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int getStride() { 59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mStride > 0 ? mStride : sizeof(mType) * mSize; 60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void bindByteBuffer() { 63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mTempByteBuffer = mPointer == null ? null : toByteBuffer(-1, mPointer); 64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void unbindByteBuffer() { 67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mTempByteBuffer = null; 68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static int sizeof(int type) { 71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin switch (type) { 72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin case GL10.GL_UNSIGNED_BYTE: 73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return 1; 74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin case GL10.GL_BYTE: 75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return 1; 76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin case GL10.GL_SHORT: 77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return 2; 78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin case GL10.GL_FIXED: 79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return 4; 80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin case GL10.GL_FLOAT: 81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return 4; 82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin default: 83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return 0; 84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static ByteBuffer toByteBuffer(int byteCount, Buffer input) { 88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ByteBuffer result = null; 89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin boolean convertWholeBuffer = (byteCount < 0); 90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (input instanceof ByteBuffer) { 91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ByteBuffer input2 = (ByteBuffer) input; 92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int position = input2.position(); 93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (convertWholeBuffer) { 94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin byteCount = input2.limit() - position; 95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result = ByteBuffer.allocate(byteCount).order(input2.order()); 97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0; i < byteCount; i++) { 98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result.put(input2.get()); 99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin input2.position(position); 101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if (input instanceof CharBuffer) { 102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin CharBuffer input2 = (CharBuffer) input; 103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int position = input2.position(); 104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (convertWholeBuffer) { 105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin byteCount = (input2.limit() - position) * 2; 106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result = ByteBuffer.allocate(byteCount).order(input2.order()); 108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin CharBuffer result2 = result.asCharBuffer(); 109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0; i < byteCount / 2; i++) { 110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result2.put(input2.get()); 111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin input2.position(position); 113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if (input instanceof ShortBuffer) { 114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ShortBuffer input2 = (ShortBuffer) input; 115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int position = input2.position(); 116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (convertWholeBuffer) { 117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin byteCount = (input2.limit() - position)* 2; 118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result = ByteBuffer.allocate(byteCount).order(input2.order()); 120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ShortBuffer result2 = result.asShortBuffer(); 121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0; i < byteCount / 2; i++) { 122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result2.put(input2.get()); 123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin input2.position(position); 125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if (input instanceof IntBuffer) { 126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin IntBuffer input2 = (IntBuffer) input; 127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int position = input2.position(); 128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (convertWholeBuffer) { 129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin byteCount = (input2.limit() - position) * 4; 130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result = ByteBuffer.allocate(byteCount).order(input2.order()); 132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin IntBuffer result2 = result.asIntBuffer(); 133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0; i < byteCount / 4; i++) { 134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result2.put(input2.get()); 135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin input2.position(position); 137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if (input instanceof FloatBuffer) { 138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin FloatBuffer input2 = (FloatBuffer) input; 139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int position = input2.position(); 140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (convertWholeBuffer) { 141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin byteCount = (input2.limit() - position) * 4; 142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result = ByteBuffer.allocate(byteCount).order(input2.order()); 144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin FloatBuffer result2 = result.asFloatBuffer(); 145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0; i < byteCount / 4; i++) { 146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result2.put(input2.get()); 147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin input2.position(position); 149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if (input instanceof DoubleBuffer) { 150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin DoubleBuffer input2 = (DoubleBuffer) input; 151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int position = input2.position(); 152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (convertWholeBuffer) { 153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin byteCount = (input2.limit() - position) * 8; 154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result = ByteBuffer.allocate(byteCount).order(input2.order()); 156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin DoubleBuffer result2 = result.asDoubleBuffer(); 157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0; i < byteCount / 8; i++) { 158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result2.put(input2.get()); 159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin input2.position(position); 161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if (input instanceof LongBuffer) { 162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin LongBuffer input2 = (LongBuffer) input; 163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int position = input2.position(); 164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (convertWholeBuffer) { 165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin byteCount = (input2.limit() - position) * 8; 166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result = ByteBuffer.allocate(byteCount).order(input2.order()); 168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin LongBuffer result2 = result.asLongBuffer(); 169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0; i < byteCount / 8; i++) { 170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result2.put(input2.get()); 171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin input2.position(position); 173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin throw new RuntimeException("Unimplemented Buffer subclass."); 175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result.rewind(); 177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // The OpenGL API will interpret the result in hardware byte order, 178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // so we better do that as well: 179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result.order(ByteOrder.nativeOrder()); 180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return result; 181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void getArrayElement(int index, double[] result) { 184f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mTempByteBuffer == null) { 185f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin throw new IllegalArgumentException("undefined pointer"); 186f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 187f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mStride < 0) { 188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin throw new IllegalArgumentException("invalid stride"); 189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 190f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int stride = getStride(); 192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ByteBuffer byteBuffer = mTempByteBuffer; 193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int size = mSize; 194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int type = mType; 195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int sizeofType = sizeof(type); 196f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int byteOffset = stride * index; 197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 198f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0; i < size; i++) { 199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin switch (type) { 200f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin case GL10.GL_BYTE: 201f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin case GL10.GL_UNSIGNED_BYTE: 202f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result[i] = byteBuffer.get(byteOffset); 203f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin break; 204f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin case GL10.GL_SHORT: 205f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ShortBuffer shortBuffer = byteBuffer.asShortBuffer(); 206f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result[i] = shortBuffer.get(byteOffset / 2); 207f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin break; 208f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin case GL10.GL_FIXED: 209f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin IntBuffer intBuffer = byteBuffer.asIntBuffer(); 210f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result[i] = intBuffer.get(byteOffset / 4); 211f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin break; 212f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin case GL10.GL_FLOAT: 213f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin FloatBuffer floatBuffer = byteBuffer.asFloatBuffer(); 214f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result[i] = floatBuffer.get(byteOffset / 4); 215f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin break; 216f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin default: 217f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin throw new UnsupportedOperationException("unknown type"); 218f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 219f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin byteOffset += sizeofType; 220f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 221f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 222f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin} 223