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