blob: 70c34333db967cf30ceb2e1103a3ef0f162ed839 [file] [log] [blame]
David Li55c94cc2011-03-04 17:50:48 -08001/*
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
19namespace android
20{
21bool capture; // capture after each glDraw*
David Li55c94cc2011-03-04 17:50:48 -080022}
23
David Li55c94cc2011-03-04 17:50:48 -080024void Debug_glDrawArrays(GLenum mode, GLint first, GLsizei count)
25{
David Li5c425f22011-03-10 16:40:37 -080026 DbgContext * const dbg = getDbgContextThreadSpecific();
David Li55c94cc2011-03-04 17:50:48 -080027 glesv2debugger::Message msg, cmd;
David Li5c425f22011-03-10 16:40:37 -080028 msg.set_context_id(reinterpret_cast<int>(dbg));
David Li55c94cc2011-03-04 17:50:48 -080029 msg.set_type(glesv2debugger::Message_Type_BeforeCall);
David Lie2ad4d02011-04-08 18:41:00 -070030 bool expectResponse = dbg->expectResponse.Bit(glesv2debugger::Message_Function_glDrawArrays);
David Li55c94cc2011-03-04 17:50:48 -080031 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);
David Li5c425f22011-03-10 16:40:37 -080036
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;
David Li55c94cc2011-03-04 17:50:48 -080045 int viewport[4] = {};
David Lie9f619f2011-04-14 11:20:22 -070046 cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
47 cmd.set_expect_response(expectResponse);
David Lie2ad4d02011-04-08 18:41:00 -070048 glesv2debugger::Message_Function oldCmd = cmd.function();
David Li940c3f82011-03-10 19:07:42 -080049 Send(msg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -070050 expectResponse = cmd.expect_response();
David Li55c94cc2011-03-04 17:50:48 -080051 while (true) {
52 msg.Clear();
53 nsecs_t c0 = systemTime(timeMode);
54 switch (cmd.function()) {
55 case glesv2debugger::Message_Function_CONTINUE:
David Li5c425f22011-03-10 16:40:37 -080056 dbg->hooks->gl.glDrawArrays(mode, first, count);
David Li55c94cc2011-03-04 17:50:48 -080057 msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
David Li5c425f22011-03-10 16:40:37 -080058 msg.set_context_id(reinterpret_cast<int>(dbg));
David Li55c94cc2011-03-04 17:50:48 -080059 msg.set_function(glesv2debugger::Message_Function_glDrawArrays);
60 msg.set_type(glesv2debugger::Message_Type_AfterCall);
61 msg.set_expect_response(expectResponse);
David Lie2ad4d02011-04-08 18:41:00 -070062 if (!expectResponse) {
63 cmd.set_function(glesv2debugger::Message_Function_SKIP);
64 cmd.set_expect_response(false);
65 }
66 oldCmd = cmd.function();
David Li940c3f82011-03-10 19:07:42 -080067 Send(msg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -070068 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
David Lie7180e82011-04-08 18:45:45 -070072 if (dbg->captureDraw > 0) {
73 dbg->captureDraw--;
David Li940c3f82011-03-10 19:07:42 -080074 dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
Steve Block5baa3a62011-12-20 16:23:08 +000075// ALOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
David Li6a5ca482011-03-21 10:02:30 -070076// viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
David Lif9bc1242011-03-22 18:42:03 -070077 pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
David Lie7180e82011-04-08 18:45:45 -070078 dbg->readBytesPerPixel);
David Li940c3f82011-03-10 19:07:42 -080079 Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
Mathias Agopian575e01c62011-09-13 18:15:50 -070080 GL_RGBA, GL_UNSIGNED_BYTE, pixels);
David Li940c3f82011-03-10 19:07:42 -080081 }
David Li55c94cc2011-03-04 17:50:48 -080082 break;
83 case glesv2debugger::Message_Function_SKIP:
84 return;
David Li940c3f82011-03-10 19:07:42 -080085 case glesv2debugger::Message_Function_SETPROP:
David Lifbfc7032011-03-21 16:25:58 -070086 SetProp(dbg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -070087 expectResponse = cmd.expect_response();
88 if (!expectResponse) // SETPROP is "out of band"
89 cmd.set_function(oldCmd);
90 else
91 Receive(cmd);
David Li55c94cc2011-03-04 17:50:48 -080092 break;
93 default:
David Li291f5fe2011-03-21 17:42:50 -070094 GenerateCall(dbg, cmd, msg, NULL);
95 msg.set_expect_response(expectResponse);
David Lie2ad4d02011-04-08 18:41:00 -070096 if (!expectResponse) {
David Li291f5fe2011-03-21 17:42:50 -070097 cmd.set_function(cmd.SKIP);
David Lie2ad4d02011-04-08 18:41:00 -070098 cmd.set_expect_response(expectResponse);
99 }
100 oldCmd = cmd.function();
David Li291f5fe2011-03-21 17:42:50 -0700101 Send(msg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -0700102 expectResponse = cmd.expect_response();
David Li55c94cc2011-03-04 17:50:48 -0800103 break;
104 }
105 }
106}
107
David Li5c425f22011-03-10 16:40:37 -0800108template<typename T>
109static 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
David Li55c94cc2011-03-04 17:50:48 -0800120void Debug_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
121{
David Li5c425f22011-03-10 16:40:37 -0800122 DbgContext * const dbg = getDbgContextThreadSpecific();
David Li55c94cc2011-03-04 17:50:48 -0800123 glesv2debugger::Message msg, cmd;
David Li5c425f22011-03-10 16:40:37 -0800124 msg.set_context_id(reinterpret_cast<int>(dbg));
David Li55c94cc2011-03-04 17:50:48 -0800125 msg.set_type(glesv2debugger::Message_Type_BeforeCall);
David Lie2ad4d02011-04-08 18:41:00 -0700126 bool expectResponse = dbg->expectResponse.Bit(glesv2debugger::Message_Function_glDrawElements);
David Li55c94cc2011-03-04 17:50:48 -0800127 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));
David Li5c425f22011-03-10 16:40:37 -0800133
134 msg.set_arg7(dbg->maxAttrib); // indicate capturing vertex data
135 std::string * const data = msg.mutable_data();
136 if (GL_UNSIGNED_BYTE == type) {
Mathias Agopian575e01c62011-09-13 18:15:50 -0700137 if (dbg->indexBuffer) {
David Lif9bc1242011-03-22 18:42:03 -0700138 FetchIndexed(count, (unsigned char *)dbg->indexBuffer->data +
139 (unsigned long)indices, data, dbg);
Mathias Agopian575e01c62011-09-13 18:15:50 -0700140 } else {
David Li5c425f22011-03-10 16:40:37 -0800141 FetchIndexed(count, (unsigned char *)indices, data, dbg);
Mathias Agopian575e01c62011-09-13 18:15:50 -0700142 }
David Li5c425f22011-03-10 16:40:37 -0800143 } else if (GL_UNSIGNED_SHORT == type) {
Mathias Agopian575e01c62011-09-13 18:15:50 -0700144 if (dbg->indexBuffer) {
David Lif9bc1242011-03-22 18:42:03 -0700145 FetchIndexed(count, (unsigned short *)((char *)dbg->indexBuffer->data +
146 (unsigned long)indices), data, dbg);
Mathias Agopian575e01c62011-09-13 18:15:50 -0700147 } else {
David Li5c425f22011-03-10 16:40:37 -0800148 FetchIndexed(count, (unsigned short *)indices, data, dbg);
Mathias Agopian575e01c62011-09-13 18:15:50 -0700149 }
150 } else {
David Li5c425f22011-03-10 16:40:37 -0800151 assert(0);
Mathias Agopian575e01c62011-09-13 18:15:50 -0700152 }
David Li5c425f22011-03-10 16:40:37 -0800153
154 void * pixels = NULL;
David Li55c94cc2011-03-04 17:50:48 -0800155 int viewport[4] = {};
David Lie9f619f2011-04-14 11:20:22 -0700156 cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
157 cmd.set_expect_response(expectResponse);
David Lie2ad4d02011-04-08 18:41:00 -0700158 glesv2debugger::Message_Function oldCmd = cmd.function();
David Li940c3f82011-03-10 19:07:42 -0800159 Send(msg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -0700160 expectResponse = cmd.expect_response();
David Li55c94cc2011-03-04 17:50:48 -0800161 while (true) {
162 msg.Clear();
163 nsecs_t c0 = systemTime(timeMode);
164 switch (cmd.function()) {
165 case glesv2debugger::Message_Function_CONTINUE:
David Li5c425f22011-03-10 16:40:37 -0800166 dbg->hooks->gl.glDrawElements(mode, count, type, indices);
David Li55c94cc2011-03-04 17:50:48 -0800167 msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
David Li5c425f22011-03-10 16:40:37 -0800168 msg.set_context_id(reinterpret_cast<int>(dbg));
David Li55c94cc2011-03-04 17:50:48 -0800169 msg.set_function(glesv2debugger::Message_Function_glDrawElements);
170 msg.set_type(glesv2debugger::Message_Type_AfterCall);
171 msg.set_expect_response(expectResponse);
David Lie2ad4d02011-04-08 18:41:00 -0700172 if (!expectResponse) {
173 cmd.set_function(glesv2debugger::Message_Function_SKIP);
174 cmd.set_expect_response(false);
175 }
176 oldCmd = cmd.function();
David Li940c3f82011-03-10 19:07:42 -0800177 Send(msg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -0700178 expectResponse = cmd.expect_response();
179 // TODO: pack glReadPixels data with vertex data instead of
Mathias Agopian575e01c62011-09-13 18:15:50 -0700180 // relying on separate call for transport, this would allow
David Lie2ad4d02011-04-08 18:41:00 -0700181 // auto generated message loop using EXTEND_Debug macro
David Lie7180e82011-04-08 18:45:45 -0700182 if (dbg->captureDraw > 0) {
183 dbg->captureDraw--;
David Li940c3f82011-03-10 19:07:42 -0800184 dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
David Lif9bc1242011-03-22 18:42:03 -0700185 pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
David Lie7180e82011-04-08 18:45:45 -0700186 dbg->readBytesPerPixel);
David Li940c3f82011-03-10 19:07:42 -0800187 Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
Mathias Agopian575e01c62011-09-13 18:15:50 -0700188 GL_RGBA, GL_UNSIGNED_BYTE, pixels);
David Li940c3f82011-03-10 19:07:42 -0800189 }
David Li55c94cc2011-03-04 17:50:48 -0800190 break;
191 case glesv2debugger::Message_Function_SKIP:
192 return;
David Li940c3f82011-03-10 19:07:42 -0800193 case glesv2debugger::Message_Function_SETPROP:
David Lifbfc7032011-03-21 16:25:58 -0700194 SetProp(dbg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -0700195 expectResponse = cmd.expect_response();
196 if (!expectResponse) // SETPROP is "out of band"
197 cmd.set_function(oldCmd);
198 else
199 Receive(cmd);
David Li55c94cc2011-03-04 17:50:48 -0800200 break;
201 default:
David Li291f5fe2011-03-21 17:42:50 -0700202 GenerateCall(dbg, cmd, msg, NULL);
203 msg.set_expect_response(expectResponse);
David Lie2ad4d02011-04-08 18:41:00 -0700204 if (!expectResponse) {
David Li291f5fe2011-03-21 17:42:50 -0700205 cmd.set_function(cmd.SKIP);
David Lie2ad4d02011-04-08 18:41:00 -0700206 cmd.set_expect_response(expectResponse);
207 }
208 oldCmd = cmd.function();
David Li291f5fe2011-03-21 17:42:50 -0700209 Send(msg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -0700210 expectResponse = cmd.expect_response();
David Li55c94cc2011-03-04 17:50:48 -0800211 break;
212 }
213 }
214}