| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.gallery3d.ui; |
| |
| import java.nio.Buffer; |
| import java.nio.ByteBuffer; |
| import java.nio.ByteOrder; |
| import java.nio.CharBuffer; |
| import java.nio.DoubleBuffer; |
| import java.nio.FloatBuffer; |
| import java.nio.IntBuffer; |
| import java.nio.LongBuffer; |
| import java.nio.ShortBuffer; |
| |
| import javax.microedition.khronos.opengles.GL10; |
| |
| public class PointerInfo { |
| |
| /** |
| * The number of coordinates per vertex. 1..4 |
| */ |
| public int mSize; |
| |
| /** |
| * The type of each coordinate. |
| */ |
| public int mType; |
| |
| /** |
| * The byte offset between consecutive vertices. 0 means mSize * |
| * sizeof(mType) |
| */ |
| public int mStride; |
| public Buffer mPointer; |
| public ByteBuffer mTempByteBuffer; |
| |
| public PointerInfo(int size, int type, int stride, Buffer pointer) { |
| mSize = size; |
| mType = type; |
| mStride = stride; |
| mPointer = pointer; |
| } |
| |
| private int getStride() { |
| return mStride > 0 ? mStride : sizeof(mType) * mSize; |
| } |
| |
| public void bindByteBuffer() { |
| mTempByteBuffer = mPointer == null ? null : toByteBuffer(-1, mPointer); |
| } |
| |
| public void unbindByteBuffer() { |
| mTempByteBuffer = null; |
| } |
| |
| private static int sizeof(int type) { |
| switch (type) { |
| case GL10.GL_UNSIGNED_BYTE: |
| return 1; |
| case GL10.GL_BYTE: |
| return 1; |
| case GL10.GL_SHORT: |
| return 2; |
| case GL10.GL_FIXED: |
| return 4; |
| case GL10.GL_FLOAT: |
| return 4; |
| default: |
| return 0; |
| } |
| } |
| |
| private static ByteBuffer toByteBuffer(int byteCount, Buffer input) { |
| ByteBuffer result = null; |
| boolean convertWholeBuffer = (byteCount < 0); |
| if (input instanceof ByteBuffer) { |
| ByteBuffer input2 = (ByteBuffer) input; |
| int position = input2.position(); |
| if (convertWholeBuffer) { |
| byteCount = input2.limit() - position; |
| } |
| result = ByteBuffer.allocate(byteCount).order(input2.order()); |
| for (int i = 0; i < byteCount; i++) { |
| result.put(input2.get()); |
| } |
| input2.position(position); |
| } else if (input instanceof CharBuffer) { |
| CharBuffer input2 = (CharBuffer) input; |
| int position = input2.position(); |
| if (convertWholeBuffer) { |
| byteCount = (input2.limit() - position) * 2; |
| } |
| result = ByteBuffer.allocate(byteCount).order(input2.order()); |
| CharBuffer result2 = result.asCharBuffer(); |
| for (int i = 0; i < byteCount / 2; i++) { |
| result2.put(input2.get()); |
| } |
| input2.position(position); |
| } else if (input instanceof ShortBuffer) { |
| ShortBuffer input2 = (ShortBuffer) input; |
| int position = input2.position(); |
| if (convertWholeBuffer) { |
| byteCount = (input2.limit() - position)* 2; |
| } |
| result = ByteBuffer.allocate(byteCount).order(input2.order()); |
| ShortBuffer result2 = result.asShortBuffer(); |
| for (int i = 0; i < byteCount / 2; i++) { |
| result2.put(input2.get()); |
| } |
| input2.position(position); |
| } else if (input instanceof IntBuffer) { |
| IntBuffer input2 = (IntBuffer) input; |
| int position = input2.position(); |
| if (convertWholeBuffer) { |
| byteCount = (input2.limit() - position) * 4; |
| } |
| result = ByteBuffer.allocate(byteCount).order(input2.order()); |
| IntBuffer result2 = result.asIntBuffer(); |
| for (int i = 0; i < byteCount / 4; i++) { |
| result2.put(input2.get()); |
| } |
| input2.position(position); |
| } else if (input instanceof FloatBuffer) { |
| FloatBuffer input2 = (FloatBuffer) input; |
| int position = input2.position(); |
| if (convertWholeBuffer) { |
| byteCount = (input2.limit() - position) * 4; |
| } |
| result = ByteBuffer.allocate(byteCount).order(input2.order()); |
| FloatBuffer result2 = result.asFloatBuffer(); |
| for (int i = 0; i < byteCount / 4; i++) { |
| result2.put(input2.get()); |
| } |
| input2.position(position); |
| } else if (input instanceof DoubleBuffer) { |
| DoubleBuffer input2 = (DoubleBuffer) input; |
| int position = input2.position(); |
| if (convertWholeBuffer) { |
| byteCount = (input2.limit() - position) * 8; |
| } |
| result = ByteBuffer.allocate(byteCount).order(input2.order()); |
| DoubleBuffer result2 = result.asDoubleBuffer(); |
| for (int i = 0; i < byteCount / 8; i++) { |
| result2.put(input2.get()); |
| } |
| input2.position(position); |
| } else if (input instanceof LongBuffer) { |
| LongBuffer input2 = (LongBuffer) input; |
| int position = input2.position(); |
| if (convertWholeBuffer) { |
| byteCount = (input2.limit() - position) * 8; |
| } |
| result = ByteBuffer.allocate(byteCount).order(input2.order()); |
| LongBuffer result2 = result.asLongBuffer(); |
| for (int i = 0; i < byteCount / 8; i++) { |
| result2.put(input2.get()); |
| } |
| input2.position(position); |
| } else { |
| throw new RuntimeException("Unimplemented Buffer subclass."); |
| } |
| result.rewind(); |
| // The OpenGL API will interpret the result in hardware byte order, |
| // so we better do that as well: |
| result.order(ByteOrder.nativeOrder()); |
| return result; |
| } |
| |
| public void getArrayElement(int index, double[] result) { |
| if (mTempByteBuffer == null) { |
| throw new IllegalArgumentException("undefined pointer"); |
| } |
| if (mStride < 0) { |
| throw new IllegalArgumentException("invalid stride"); |
| } |
| |
| int stride = getStride(); |
| ByteBuffer byteBuffer = mTempByteBuffer; |
| int size = mSize; |
| int type = mType; |
| int sizeofType = sizeof(type); |
| int byteOffset = stride * index; |
| |
| for (int i = 0; i < size; i++) { |
| switch (type) { |
| case GL10.GL_BYTE: |
| case GL10.GL_UNSIGNED_BYTE: |
| result[i] = byteBuffer.get(byteOffset); |
| break; |
| case GL10.GL_SHORT: |
| ShortBuffer shortBuffer = byteBuffer.asShortBuffer(); |
| result[i] = shortBuffer.get(byteOffset / 2); |
| break; |
| case GL10.GL_FIXED: |
| IntBuffer intBuffer = byteBuffer.asIntBuffer(); |
| result[i] = intBuffer.get(byteOffset / 4); |
| break; |
| case GL10.GL_FLOAT: |
| FloatBuffer floatBuffer = byteBuffer.asFloatBuffer(); |
| result[i] = floatBuffer.get(byteOffset / 4); |
| break; |
| default: |
| throw new UnsupportedOperationException("unknown type"); |
| } |
| byteOffset += sizeofType; |
| } |
| } |
| } |