Home | History | Annotate | Download | only in src
      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 #include "header.h"
     18 
     19 namespace android
     20 {
     21 bool capture; // capture after each glDraw*
     22 }
     23 
     24 void Debug_glDrawArrays(GLenum mode, GLint first, GLsizei count)
     25 {
     26     DbgContext * const dbg = getDbgContextThreadSpecific();
     27     glesv2debugger::Message msg, cmd;
     28     msg.set_context_id(reinterpret_cast<int>(dbg));
     29     msg.set_type(glesv2debugger::Message_Type_BeforeCall);
     30     bool expectResponse = dbg->expectResponse.Bit(glesv2debugger::Message_Function_glDrawArrays);
     31     msg.set_expect_response(expectResponse);
     32     msg.set_function(glesv2debugger::Message_Function_glDrawArrays);
     33     msg.set_arg0(mode);
     34     msg.set_arg1(first);
     35     msg.set_arg2(count);
     36 
     37     msg.set_arg7(dbg->maxAttrib); // indicate capturing vertex data
     38     if (dbg->hasNonVBOAttribs) {
     39         std::string * const data = msg.mutable_data();
     40         for (unsigned i = 0; i < count; i++)
     41             dbg->Fetch(i + first, data);
     42     }
     43 
     44     void * pixels = NULL;
     45     int viewport[4] = {};
     46     cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
     47     cmd.set_expect_response(expectResponse);
     48     glesv2debugger::Message_Function oldCmd = cmd.function();
     49     Send(msg, cmd);
     50     expectResponse = cmd.expect_response();
     51     while (true) {
     52         msg.Clear();
     53         nsecs_t c0 = systemTime(timeMode);
     54         switch (cmd.function()) {
     55         case glesv2debugger::Message_Function_CONTINUE:
     56             dbg->hooks->gl.glDrawArrays(mode, first, count);
     57             msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
     58             msg.set_context_id(reinterpret_cast<int>(dbg));
     59             msg.set_function(glesv2debugger::Message_Function_glDrawArrays);
     60             msg.set_type(glesv2debugger::Message_Type_AfterCall);
     61             msg.set_expect_response(expectResponse);
     62             if (!expectResponse) {
     63                 cmd.set_function(glesv2debugger::Message_Function_SKIP);
     64                 cmd.set_expect_response(false);
     65             }
     66             oldCmd = cmd.function();
     67             Send(msg, cmd);
     68             expectResponse = cmd.expect_response();
     69             // TODO: pack glReadPixels data with vertex data instead of
     70             //  relying on sperate call for transport, this would allow
     71             //  auto generated message loop using EXTEND_Debug macro
     72             if (dbg->captureDraw > 0) {
     73                 dbg->captureDraw--;
     74                 dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
     75 //                LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
     76 //                     viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
     77                 pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
     78                                                   dbg->readBytesPerPixel);
     79                 Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
     80                         GL_RGBA, GL_UNSIGNED_BYTE, pixels);
     81             }
     82             break;
     83         case glesv2debugger::Message_Function_SKIP:
     84             return;
     85         case glesv2debugger::Message_Function_SETPROP:
     86             SetProp(dbg, cmd);
     87             expectResponse = cmd.expect_response();
     88             if (!expectResponse) // SETPROP is "out of band"
     89                 cmd.set_function(oldCmd);
     90             else
     91                 Receive(cmd);
     92             break;
     93         default:
     94             GenerateCall(dbg, cmd, msg, NULL);
     95             msg.set_expect_response(expectResponse);
     96             if (!expectResponse) {
     97                 cmd.set_function(cmd.SKIP);
     98                 cmd.set_expect_response(expectResponse);
     99             }
    100             oldCmd = cmd.function();
    101             Send(msg, cmd);
    102             expectResponse = cmd.expect_response();
    103             break;
    104         }
    105     }
    106 }
    107 
    108 template<typename T>
    109 static inline void FetchIndexed(const unsigned count, const T * indices,
    110                                 std::string * const data, const DbgContext * const ctx)
    111 {
    112     for (unsigned i = 0; i < count; i++) {
    113         if (!ctx->indexBuffer)
    114             data->append((const char *)(indices + i), sizeof(*indices));
    115         if (ctx->hasNonVBOAttribs)
    116             ctx->Fetch(indices[i], data);
    117     }
    118 }
    119 
    120 void Debug_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
    121 {
    122     DbgContext * const dbg = getDbgContextThreadSpecific();
    123     glesv2debugger::Message msg, cmd;
    124     msg.set_context_id(reinterpret_cast<int>(dbg));
    125     msg.set_type(glesv2debugger::Message_Type_BeforeCall);
    126     bool expectResponse = dbg->expectResponse.Bit(glesv2debugger::Message_Function_glDrawElements);
    127     msg.set_expect_response(expectResponse);
    128     msg.set_function(glesv2debugger::Message_Function_glDrawElements);
    129     msg.set_arg0(mode);
    130     msg.set_arg1(count);
    131     msg.set_arg2(type);
    132     msg.set_arg3(reinterpret_cast<int>(indices));
    133 
    134     msg.set_arg7(dbg->maxAttrib); // indicate capturing vertex data
    135     std::string * const data = msg.mutable_data();
    136     if (GL_UNSIGNED_BYTE == type) {
    137         if (dbg->indexBuffer) {
    138             FetchIndexed(count, (unsigned char *)dbg->indexBuffer->data +
    139                          (unsigned long)indices, data, dbg);
    140         } else {
    141             FetchIndexed(count, (unsigned char *)indices, data, dbg);
    142         }
    143     } else if (GL_UNSIGNED_SHORT == type) {
    144         if (dbg->indexBuffer) {
    145             FetchIndexed(count, (unsigned short *)((char *)dbg->indexBuffer->data +
    146                                                    (unsigned long)indices), data, dbg);
    147         } else {
    148             FetchIndexed(count, (unsigned short *)indices, data, dbg);
    149         }
    150     } else {
    151         assert(0);
    152     }
    153 
    154     void * pixels = NULL;
    155     int viewport[4] = {};
    156     cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
    157     cmd.set_expect_response(expectResponse);
    158     glesv2debugger::Message_Function oldCmd = cmd.function();
    159     Send(msg, cmd);
    160     expectResponse = cmd.expect_response();
    161     while (true) {
    162         msg.Clear();
    163         nsecs_t c0 = systemTime(timeMode);
    164         switch (cmd.function()) {
    165         case glesv2debugger::Message_Function_CONTINUE:
    166             dbg->hooks->gl.glDrawElements(mode, count, type, indices);
    167             msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
    168             msg.set_context_id(reinterpret_cast<int>(dbg));
    169             msg.set_function(glesv2debugger::Message_Function_glDrawElements);
    170             msg.set_type(glesv2debugger::Message_Type_AfterCall);
    171             msg.set_expect_response(expectResponse);
    172             if (!expectResponse) {
    173                 cmd.set_function(glesv2debugger::Message_Function_SKIP);
    174                 cmd.set_expect_response(false);
    175             }
    176             oldCmd = cmd.function();
    177             Send(msg, cmd);
    178             expectResponse = cmd.expect_response();
    179             // TODO: pack glReadPixels data with vertex data instead of
    180             //  relying on separate call for transport, this would allow
    181             //  auto generated message loop using EXTEND_Debug macro
    182             if (dbg->captureDraw > 0) {
    183                 dbg->captureDraw--;
    184                 dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
    185                 pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
    186                                                   dbg->readBytesPerPixel);
    187                 Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
    188                         GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    189             }
    190             break;
    191         case glesv2debugger::Message_Function_SKIP:
    192             return;
    193         case glesv2debugger::Message_Function_SETPROP:
    194             SetProp(dbg, cmd);
    195             expectResponse = cmd.expect_response();
    196             if (!expectResponse) // SETPROP is "out of band"
    197                 cmd.set_function(oldCmd);
    198             else
    199                 Receive(cmd);
    200             break;
    201         default:
    202             GenerateCall(dbg, cmd, msg, NULL);
    203             msg.set_expect_response(expectResponse);
    204             if (!expectResponse) {
    205                 cmd.set_function(cmd.SKIP);
    206                 cmd.set_expect_response(expectResponse);
    207             }
    208             oldCmd = cmd.function();
    209             Send(msg, cmd);
    210             expectResponse = cmd.expect_response();
    211             break;
    212         }
    213     }
    214 }
    215