Home | History | Annotate | Download | only in gldebugger
      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 
     31     public GLBuffer(final int name) {
     32         this.name = name;
     33     }
     34 
     35     /** deep copy */
     36     @Override
     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 */
     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 
     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
    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 */
    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)
    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)
    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)
    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)
    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)
    273     public void glDisableVertexAttribArray(Message msg) {
    274         if (msg.getArg0() >= 0 && msg.getArg0() < attribPointers.length)
    275             attribPointers[msg.getArg0()].enabled = false;
    276     }
    277 
    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 
    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 
    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      */
    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      */
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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 
    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 
    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)
    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