• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  ** Copyright 2011, 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.ide.eclipse.gldebugger;
18 
19 import com.android.ide.eclipse.gldebugger.DebuggerMessage.Message;
20 import com.android.sdklib.util.SparseArray;
21 
22 import java.nio.ByteBuffer;
23 
24 class GLBuffer implements Cloneable {
25     public final int name;
26     public GLEnum usage;
27     public GLEnum target;
28     /** in SampleView.targetByteOrder */
29     public ByteBuffer data;
30 
GLBuffer(final int name)31     public GLBuffer(final int name) {
32         this.name = name;
33     }
34 
35     /** deep copy */
36     @Override
clone()37     public GLBuffer clone() {
38         try {
39             GLBuffer copy = (GLBuffer) super.clone();
40             if (data != null) {
41                 copy.data = ByteBuffer.allocate(data.capacity());
42                 copy.data.order(GLFramesView.TARGET_BYTE_ORDER);
43                 data.position(0);
44                 copy.data.put(data);
45             }
46             return copy;
47         } catch (CloneNotSupportedException e) {
48             e.printStackTrace();
49             assert false;
50             return null;
51         }
52     }
53 }
54 
55 class GLAttribPointer implements Cloneable {
56     public int size; // number of values per vertex
57     public GLEnum type; // data type
58     public int stride; // bytes
59     /**
60      * element stride in bytes, used when fetching from buffer; not for fetching
61      * from user pointer since server already packed elements
62      */
63     int elemStride; // in bytes
64     /** element size in bytes */
65     int elemSize;
66     public int ptr; // pointer in debugger server or byte offset into buffer
67     public GLBuffer buffer;
68     public boolean normalized;
69     public boolean enabled;
70 
71     /** deep copy, re-maps buffer into copyBuffers */
clone(SparseArray<GLBuffer> copyBuffers)72     public GLAttribPointer clone(SparseArray<GLBuffer> copyBuffers) {
73         try {
74             GLAttribPointer copy = (GLAttribPointer) super.clone();
75             if (buffer != null)
76                 copy.buffer = copyBuffers.get(buffer.name);
77             return copy;
78         } catch (CloneNotSupportedException e) {
79             e.printStackTrace();
80             assert false;
81             return null;
82         }
83     }
84 }
85 
86 public class GLServerVertex implements Cloneable {
87     public SparseArray<GLBuffer> buffers = new SparseArray<GLBuffer>();
88     public GLBuffer attribBuffer, indexBuffer; // current binding
89     public GLAttribPointer attribPointers[];
90     public float defaultAttribs[][];
91 
GLServerVertex(final int MAX_VERTEX_ATTRIBS)92     public GLServerVertex(final int MAX_VERTEX_ATTRIBS) {
93         buffers.append(0, null);
94         attribPointers = new GLAttribPointer[MAX_VERTEX_ATTRIBS];
95         for (int i = 0; i < attribPointers.length; i++)
96             attribPointers[i] = new GLAttribPointer();
97         defaultAttribs = new float[MAX_VERTEX_ATTRIBS][4];
98         for (int i = 0; i < defaultAttribs.length; i++) {
99             defaultAttribs[i][0] = 0;
100             defaultAttribs[i][1] = 0;
101             defaultAttribs[i][2] = 0;
102             defaultAttribs[i][3] = 1;
103         }
104     }
105 
106     /** deep copy */
107     @Override
clone()108     public GLServerVertex clone() {
109         try {
110             GLServerVertex copy = (GLServerVertex) super.clone();
111 
112             copy.buffers = new SparseArray<GLBuffer>(buffers.size());
113             for (int i = 0; i < buffers.size(); i++)
114                 if (buffers.valueAt(i) != null)
115                     copy.buffers.append(buffers.keyAt(i), buffers.valueAt(i).clone());
116                 else
117                     copy.buffers.append(buffers.keyAt(i), null);
118 
119             if (attribBuffer != null)
120                 copy.attribBuffer = copy.buffers.get(attribBuffer.name);
121             if (indexBuffer != null)
122                 copy.indexBuffer = copy.buffers.get(indexBuffer.name);
123 
124             copy.attribPointers = new GLAttribPointer[attribPointers.length];
125             for (int i = 0; i < attribPointers.length; i++)
126                 copy.attribPointers[i] = attribPointers[i].clone(copy.buffers);
127 
128             copy.defaultAttribs = defaultAttribs.clone();
129 
130             return copy;
131         } catch (CloneNotSupportedException e) {
132             e.printStackTrace();
133             assert false;
134             return null;
135         }
136     }
137 
138     /** returns true if processed */
process(final Message msg)139     public boolean process(final Message msg) {
140         switch (msg.getFunction()) {
141             case glBindBuffer:
142                 glBindBuffer(msg);
143                 return true;
144             case glBufferData:
145                 glBufferData(msg);
146                 return true;
147             case glBufferSubData:
148                 glBufferSubData(msg);
149                 return true;
150             case glDeleteBuffers:
151                 glDeleteBuffers(msg);
152                 return true;
153             case glDrawArrays:
154             case glDrawElements:
155                 return true;
156             case glDisableVertexAttribArray:
157                 glDisableVertexAttribArray(msg);
158                 return true;
159             case glEnableVertexAttribArray:
160                 glEnableVertexAttribArray(msg);
161                 return true;
162             case glGenBuffers:
163                 glGenBuffers(msg);
164                 return true;
165             case glVertexAttribPointer:
166                 glVertexAttribPointer(msg);
167                 return true;
168             case glVertexAttrib1f:
169                 glVertexAttrib1f(msg);
170                 return true;
171             case glVertexAttrib1fv:
172                 glVertexAttrib1fv(msg);
173                 return true;
174             case glVertexAttrib2f:
175                 glVertexAttrib2f(msg);
176                 return true;
177             case glVertexAttrib2fv:
178                 glVertexAttrib2fv(msg);
179                 return true;
180             case glVertexAttrib3f:
181                 glVertexAttrib3f(msg);
182                 return true;
183             case glVertexAttrib3fv:
184                 glVertexAttrib3fv(msg);
185                 return true;
186             case glVertexAttrib4f:
187                 glVertexAttrib4f(msg);
188                 return true;
189             case glVertexAttrib4fv:
190                 glVertexAttrib4fv(msg);
191                 return true;
192             default:
193                 return false;
194         }
195     }
196 
197     // void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer)
glBindBuffer(Message msg)198     public void glBindBuffer(Message msg) {
199         if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ARRAY_BUFFER) {
200             attribBuffer = buffers.get(msg.getArg1());
201             if (null != attribBuffer)
202                 attribBuffer.target = GLEnum.GL_ARRAY_BUFFER;
203         } else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ELEMENT_ARRAY_BUFFER) {
204             indexBuffer = buffers.get(msg.getArg1());
205             if (null != indexBuffer)
206                 indexBuffer.target = GLEnum.GL_ELEMENT_ARRAY_BUFFER;
207         } else
208             assert false;
209     }
210 
211     // void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const
212     // GLvoid:size:in data, GLenum usage)
glBufferData(Message msg)213     public void glBufferData(Message msg) {
214         if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ARRAY_BUFFER) {
215             attribBuffer.usage = GLEnum.valueOf(msg.getArg3());
216             attribBuffer.data = msg.getData().asReadOnlyByteBuffer();
217             attribBuffer.data.order(GLFramesView.TARGET_BYTE_ORDER);
218         } else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ELEMENT_ARRAY_BUFFER) {
219             indexBuffer.usage = GLEnum.valueOf(msg.getArg3());
220             indexBuffer.data = msg.getData().asReadOnlyByteBuffer();
221             indexBuffer.data.order(GLFramesView.TARGET_BYTE_ORDER);
222         } else
223             assert false;
224     }
225 
226     // void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset,
227     // GLsizeiptr size, const GLvoid:size:in data)
glBufferSubData(Message msg)228     public void glBufferSubData(Message msg) {
229         if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ARRAY_BUFFER) {
230             if (attribBuffer.data.isReadOnly()) {
231                 ByteBuffer buffer = ByteBuffer.allocate(attribBuffer.data.capacity());
232                 buffer.order(GLFramesView.TARGET_BYTE_ORDER);
233                 buffer.put(attribBuffer.data);
234                 attribBuffer.data = buffer;
235             }
236             attribBuffer.data.position(msg.getArg1());
237             attribBuffer.data.put(msg.getData().asReadOnlyByteBuffer());
238         } else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ELEMENT_ARRAY_BUFFER) {
239             if (indexBuffer.data.isReadOnly()) {
240                 ByteBuffer buffer = ByteBuffer.allocate(indexBuffer.data.capacity());
241                 buffer.order(GLFramesView.TARGET_BYTE_ORDER);
242                 buffer.put(indexBuffer.data);
243                 indexBuffer.data = buffer;
244             }
245             indexBuffer.data.position(msg.getArg1());
246             indexBuffer.data.put(msg.getData().asReadOnlyByteBuffer());
247         } else
248             assert false;
249     }
250 
251     // void glDeleteBuffers(GLsizei n, const GLuint* buffers)
glDeleteBuffers(Message msg)252     public void glDeleteBuffers(Message msg) {
253         final int n = msg.getArg0();
254         final ByteBuffer names = msg.getData().asReadOnlyByteBuffer();
255         names.order(GLFramesView.TARGET_BYTE_ORDER);
256         for (int i = 0; i < n; i++) {
257             final int name = names.getInt();
258             final GLBuffer buffer = buffers.get(name);
259             for (int j = 0; j < attribPointers.length; j++)
260                 if (attribPointers[j].buffer == buffer) {
261                     attribPointers[j].buffer = null;
262                     attribPointers[j].enabled = false;
263                 }
264             if (attribBuffer == buffer)
265                 attribBuffer = null;
266             if (indexBuffer == buffer)
267                 indexBuffer = null;
268             buffers.remove(name);
269         }
270     }
271 
272     // void glDisableVertexAttribArray(GLuint index)
glDisableVertexAttribArray(Message msg)273     public void glDisableVertexAttribArray(Message msg) {
274         if (msg.getArg0() >= 0 && msg.getArg0() < attribPointers.length)
275             attribPointers[msg.getArg0()].enabled = false;
276     }
277 
fetchConvert(final ByteBuffer src, final GLEnum type, final boolean normalized)278     float fetchConvert(final ByteBuffer src, final GLEnum type, final boolean normalized) {
279         if (GLEnum.GL_FLOAT == type)
280             return Float.intBitsToFloat(src.getInt());
281         else if (GLEnum.GL_UNSIGNED_INT == type)
282             if (normalized)
283                 return (src.getInt() & 0xffffffffL) / (2e32f - 1);
284             else
285                 return src.getInt() & 0xffffffffL;
286         else if (GLEnum.GL_INT == type)
287             if (normalized)
288                 return (src.getInt() * 2 + 1) / (2e32f - 1);
289             else
290                 return src.getInt();
291         else if (GLEnum.GL_UNSIGNED_SHORT == type)
292             if (normalized)
293                 return (src.getShort() & 0xffff) / (2e16f - 1);
294             else
295                 return src.getShort() & 0xffff;
296         else if (GLEnum.GL_SHORT == type)
297             if (normalized)
298                 return (src.getShort() * 2 + 1) / (2e16f - 1);
299             else
300                 return src.getShort();
301         else if (GLEnum.GL_UNSIGNED_BYTE == type)
302             if (normalized)
303                 return (src.get() & 0xff) / (2e8f - 1);
304             else
305                 return src.get() & 0xff;
306         else if (GLEnum.GL_BYTE == type)
307             if (normalized)
308                 return (src.get() * 2 + 1) / (2e8f - 1);
309             else
310                 return src.get();
311         else if (GLEnum.GL_FIXED == type)
312             if (normalized)
313                 return (src.getInt() * 2 + 1) / (2e32f - 1);
314             else
315                 return src.getInt() / (2e16f);
316         else
317             assert false;
318         return 0;
319     }
320 
typeSize(final GLEnum type)321     static int typeSize(final GLEnum type) {
322         switch (type) {
323             case GL_FLOAT:
324             case GL_UNSIGNED_INT:
325             case GL_INT:
326             case GL_FIXED:
327                 return 4;
328             case GL_UNSIGNED_SHORT:
329             case GL_SHORT:
330                 return 2;
331             case GL_UNSIGNED_BYTE:
332             case GL_BYTE:
333                 return 1;
334             default:
335                 assert false;
336                 return 0;
337         }
338     }
339 
fetch(final int maxAttrib, final int index, final int dstIdx, final ByteBuffer nonVBO, final float[][] fetchedAttribs)340     void fetch(final int maxAttrib, final int index, final int dstIdx, final ByteBuffer nonVBO,
341             final float[][] fetchedAttribs) {
342         for (int i = 0; i < maxAttrib; i++) {
343             final GLAttribPointer attrib = attribPointers[i];
344             int size = 0;
345             if (attrib.enabled) {
346                 size = attrib.size;
347                 if (null != attrib.buffer) {
348                     final ByteBuffer src = attrib.buffer.data;
349                     src.position(attrib.ptr + index * attrib.elemStride);
350                     for (int j = 0; j < size; j++)
351                         fetchedAttribs[i][dstIdx * 4 + j] = fetchConvert(src, attrib.type,
352                                 attrib.normalized);
353                 } else
354                     for (int j = 0; j < size; j++)
355                         fetchedAttribs[i][dstIdx * 4 + j] = fetchConvert(nonVBO, attrib.type,
356                                 attrib.normalized);
357             }
358             if (size < 1)
359                 fetchedAttribs[i][dstIdx * 4 + 0] = defaultAttribs[i][0];
360             if (size < 2)
361                 fetchedAttribs[i][dstIdx * 4 + 1] = defaultAttribs[i][1];
362             if (size < 3)
363                 fetchedAttribs[i][dstIdx * 4 + 2] = defaultAttribs[i][2];
364             if (size < 4)
365                 fetchedAttribs[i][dstIdx * 4 + 3] = defaultAttribs[i][3];
366         }
367     }
368 
369     /**
370      * fetches and converts vertex data from buffers, defaults and user pointers
371      * into MessageData; mainly for display use
372      */
glDrawArrays(MessageData msgData)373     public void glDrawArrays(MessageData msgData) {
374         final Message msg = msgData.msg;
375         if (!msg.hasArg7())
376             return;
377         final int maxAttrib = msg.getArg7();
378         final int first = msg.getArg1(), count = msg.getArg2();
379         msgData.attribs = new float[maxAttrib][count * 4];
380         ByteBuffer arrays = null;
381         if (msg.hasData()) // server sends user pointer attribs
382         {
383             arrays = msg.getData().asReadOnlyByteBuffer();
384             arrays.order(GLFramesView.TARGET_BYTE_ORDER);
385         }
386         for (int i = 0; i < count; i++)
387             fetch(maxAttrib, first + i, i, arrays, msgData.attribs);
388         assert null == arrays || arrays.remaining() == 0;
389     }
390 
391     // void glDrawElements(GLenum mode, GLsizei count, GLenum type, const
392     // GLvoid* indices)
393     /**
394      * fetches and converts vertex data from buffers, defaults and user pointers
395      * and indices from buffer/pointer into MessageData; mainly for display use
396      */
glDrawElements(MessageData msgData)397     public void glDrawElements(MessageData msgData) {
398         final Message msg = msgData.msg;
399         if (!msg.hasArg7())
400             return;
401         final int maxAttrib = msg.getArg7();
402         final int count = msg.getArg1();
403         final GLEnum type = GLEnum.valueOf(msg.getArg2());
404         msgData.attribs = new float[maxAttrib][count * 4];
405         msgData.indices = new short[count];
406         ByteBuffer arrays = null, index = null;
407         if (msg.hasData()) // server sends user pointer attribs
408         {
409             arrays = msg.getData().asReadOnlyByteBuffer();
410             arrays.order(GLFramesView.TARGET_BYTE_ORDER);
411         }
412         if (null == indexBuffer)
413             index = arrays; // server also interleaves user pointer indices
414         else {
415             index = indexBuffer.data;
416             index.position(msg.getArg3());
417         }
418         if (GLEnum.GL_UNSIGNED_SHORT == type) {
419             for (int i = 0; i < count; i++) {
420                 msgData.indices[i] = index.getShort();
421                 fetch(maxAttrib, msgData.indices[i] & 0xffff, i, arrays, msgData.attribs);
422             }
423         } else if (GLEnum.GL_UNSIGNED_BYTE == type) {
424             for (int i = 0; i < count; i++) {
425                 msgData.indices[i] = (short) (index.get() & 0xff);
426                 fetch(maxAttrib, msgData.indices[i], i, arrays, msgData.attribs);
427             }
428         } else
429             assert false;
430         assert null == arrays || arrays.remaining() == 0;
431     }
432 
433     // void glEnableVertexAttribArray(GLuint index)
glEnableVertexAttribArray(Message msg)434     public void glEnableVertexAttribArray(Message msg) {
435         if (msg.getArg0() >= 0 && msg.getArg0() < attribPointers.length)
436             attribPointers[msg.getArg0()].enabled = true;
437     }
438 
439     // void API_ENTRY(glGenBuffers)(GLsizei n, GLuint:n:out buffers)
glGenBuffers(Message msg)440     public void glGenBuffers(Message msg) {
441         final int n = msg.getArg0();
442         final ByteBuffer buffer = msg.getData().asReadOnlyByteBuffer();
443         buffer.order(GLFramesView.TARGET_BYTE_ORDER);
444         for (int i = 0; i < n; i++) {
445             final int name = buffer.getInt();
446             final int index = buffers.indexOfKey(name);
447             if (index < 0)
448                 buffers.append(name, new GLBuffer(name));
449         }
450     }
451 
452     // void glVertexAttribPointer(GLuint index, GLint size, GLenum type,
453     // GLboolean normalized, GLsizei stride, const GLvoid* ptr)
glVertexAttribPointer(Message msg)454     public void glVertexAttribPointer(Message msg) {
455         GLAttribPointer attrib = attribPointers[msg.getArg0()];
456         attrib.size = msg.getArg1();
457         attrib.type = GLEnum.valueOf(msg.getArg2());
458         attrib.normalized = msg.getArg3() != 0;
459         attrib.stride = msg.getArg4();
460         attrib.elemSize = attrib.size * typeSize(attrib.type);
461         if (attrib.stride == 0)
462             attrib.elemStride = attrib.elemSize;
463         else
464             attrib.elemStride = attrib.stride;
465         attrib.ptr = msg.getArg5();
466         attrib.buffer = attribBuffer;
467     }
468 
469     // void glVertexAttrib1f(GLuint indx, GLfloat x)
glVertexAttrib1f(Message msg)470     public void glVertexAttrib1f(Message msg) {
471         glVertexAttrib4f(msg.getArg0(), Float.intBitsToFloat(msg.getArg1()),
472                 0, 0, 1);
473     }
474 
475     // void glVertexAttrib1fv(GLuint indx, const GLfloat* values)
glVertexAttrib1fv(Message msg)476     public void glVertexAttrib1fv(Message msg) {
477         final ByteBuffer values = msg.getData().asReadOnlyByteBuffer();
478         values.order(GLFramesView.TARGET_BYTE_ORDER);
479         glVertexAttrib4f(msg.getArg0(),
480                 Float.intBitsToFloat(values.getInt()),
481                 0, 0, 1);
482     }
483 
484     // void glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
glVertexAttrib2f(Message msg)485     public void glVertexAttrib2f(Message msg) {
486         glVertexAttrib4f(msg.getArg0(), Float.intBitsToFloat(msg.getArg1()),
487                 Float.intBitsToFloat(msg.getArg2()), 0, 1);
488     }
489 
490     // void glVertexAttrib2fv(GLuint indx, const GLfloat* values)
glVertexAttrib2fv(Message msg)491     public void glVertexAttrib2fv(Message msg) {
492         final ByteBuffer values = msg.getData().asReadOnlyByteBuffer();
493         values.order(GLFramesView.TARGET_BYTE_ORDER);
494         glVertexAttrib4f(msg.getArg0(),
495                 Float.intBitsToFloat(values.getInt()),
496                 Float.intBitsToFloat(values.getInt()), 0, 1);
497     }
498 
499     // void glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
glVertexAttrib3f(Message msg)500     public void glVertexAttrib3f(Message msg) {
501         glVertexAttrib4f(msg.getArg0(), Float.intBitsToFloat(msg.getArg1()),
502                 Float.intBitsToFloat(msg.getArg2()),
503                 Float.intBitsToFloat(msg.getArg3()), 1);
504     }
505 
506     // void glVertexAttrib3fv(GLuint indx, const GLfloat* values)
glVertexAttrib3fv(Message msg)507     public void glVertexAttrib3fv(Message msg) {
508         final ByteBuffer values = msg.getData().asReadOnlyByteBuffer();
509         values.order(GLFramesView.TARGET_BYTE_ORDER);
510         glVertexAttrib4f(msg.getArg0(),
511                 Float.intBitsToFloat(values.getInt()),
512                 Float.intBitsToFloat(values.getInt()),
513                 Float.intBitsToFloat(values.getInt()), 1);
514     }
515 
glVertexAttrib4f(Message msg)516     public void glVertexAttrib4f(Message msg) {
517         glVertexAttrib4f(msg.getArg0(), Float.intBitsToFloat(msg.getArg1()),
518                 Float.intBitsToFloat(msg.getArg2()),
519                 Float.intBitsToFloat(msg.getArg3()),
520                 Float.intBitsToFloat(msg.getArg4()));
521     }
522 
glVertexAttrib4f(int indx, float x, float y, float z, float w)523     void glVertexAttrib4f(int indx, float x, float y, float z, float w) {
524         if (indx < 0 || indx >= defaultAttribs.length)
525             return;
526         defaultAttribs[indx][0] = x;
527         defaultAttribs[indx][1] = y;
528         defaultAttribs[indx][2] = z;
529         defaultAttribs[indx][3] = w;
530     }
531 
532     // void glVertexAttrib4fv(GLuint indx, const GLfloat* values)
glVertexAttrib4fv(Message msg)533     public void glVertexAttrib4fv(Message msg) {
534         final ByteBuffer values = msg.getData().asReadOnlyByteBuffer();
535         values.order(GLFramesView.TARGET_BYTE_ORDER);
536         glVertexAttrib4f(msg.getArg0(),
537                 Float.intBitsToFloat(values.getInt()),
538                 Float.intBitsToFloat(values.getInt()),
539                 Float.intBitsToFloat(values.getInt()),
540                 Float.intBitsToFloat(values.getInt()));
541     }
542 }
543