blob: 6c78556e1f1b04575db28eea3541bb4e0d018af8 [file] [log] [blame]
/*
* 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;
}
}
}