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