• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
PointerInfo(int size, int type, int stride, Buffer pointer)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 
getStride()58     private int getStride() {
59         return mStride > 0 ? mStride : sizeof(mType) * mSize;
60     }
61 
bindByteBuffer()62     public void bindByteBuffer() {
63         mTempByteBuffer = mPointer == null ? null : toByteBuffer(-1, mPointer);
64     }
65 
unbindByteBuffer()66     public void unbindByteBuffer() {
67         mTempByteBuffer = null;
68     }
69 
sizeof(int type)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 
toByteBuffer(int byteCount, Buffer input)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 
getArrayElement(int index, double[] result)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