blob: 3abea67a77e4a50997b4e3957f6e7dd730419a96 [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;
45 GLint readFormat = 0, readType = 0;
David Li55c94cc2011-03-04 17:50:48 -080046 int viewport[4] = {};
David Lie2ad4d02011-04-08 18:41:00 -070047 if (!expectResponse) {
David Li55c94cc2011-03-04 17:50:48 -080048 cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
David Lie2ad4d02011-04-08 18:41:00 -070049 cmd.set_expect_response(false);
50 }
51 glesv2debugger::Message_Function oldCmd = cmd.function();
David Li940c3f82011-03-10 19:07:42 -080052 Send(msg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -070053 expectResponse = cmd.expect_response();
David Li55c94cc2011-03-04 17:50:48 -080054 while (true) {
55 msg.Clear();
56 nsecs_t c0 = systemTime(timeMode);
57 switch (cmd.function()) {
58 case glesv2debugger::Message_Function_CONTINUE:
David Li5c425f22011-03-10 16:40:37 -080059 dbg->hooks->gl.glDrawArrays(mode, first, count);
David Li55c94cc2011-03-04 17:50:48 -080060 msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
David Li5c425f22011-03-10 16:40:37 -080061 msg.set_context_id(reinterpret_cast<int>(dbg));
David Li55c94cc2011-03-04 17:50:48 -080062 msg.set_function(glesv2debugger::Message_Function_glDrawArrays);
63 msg.set_type(glesv2debugger::Message_Type_AfterCall);
64 msg.set_expect_response(expectResponse);
David Li940c3f82011-03-10 19:07:42 -080065 if (!expectResponse)
David Li55c94cc2011-03-04 17:50:48 -080066 cmd.set_function(glesv2debugger::Message_Function_SKIP);
David Lie2ad4d02011-04-08 18:41:00 -070067 if (!expectResponse) {
68 cmd.set_function(glesv2debugger::Message_Function_SKIP);
69 cmd.set_expect_response(false);
70 }
71 oldCmd = cmd.function();
David Li940c3f82011-03-10 19:07:42 -080072 Send(msg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -070073 expectResponse = cmd.expect_response();
74 // TODO: pack glReadPixels data with vertex data instead of
75 // relying on sperate call for transport, this would allow
76 // auto generated message loop using EXTEND_Debug macro
David Li940c3f82011-03-10 19:07:42 -080077 if (capture) {
78 dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
79 dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
80 dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
David Li6a5ca482011-03-21 10:02:30 -070081// LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
82// viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
David Lif9bc1242011-03-22 18:42:03 -070083 pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
84 GetBytesPerPixel(readFormat, readType));
David Li940c3f82011-03-10 19:07:42 -080085 Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
86 readFormat, readType, pixels);
David Li940c3f82011-03-10 19:07:42 -080087 }
David Li55c94cc2011-03-04 17:50:48 -080088 break;
89 case glesv2debugger::Message_Function_SKIP:
90 return;
David Li940c3f82011-03-10 19:07:42 -080091 case glesv2debugger::Message_Function_SETPROP:
David Lifbfc7032011-03-21 16:25:58 -070092 SetProp(dbg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -070093 expectResponse = cmd.expect_response();
94 if (!expectResponse) // SETPROP is "out of band"
95 cmd.set_function(oldCmd);
96 else
97 Receive(cmd);
David Li55c94cc2011-03-04 17:50:48 -080098 break;
99 default:
David Li291f5fe2011-03-21 17:42:50 -0700100 GenerateCall(dbg, cmd, msg, NULL);
101 msg.set_expect_response(expectResponse);
David Lie2ad4d02011-04-08 18:41:00 -0700102 if (!expectResponse) {
David Li291f5fe2011-03-21 17:42:50 -0700103 cmd.set_function(cmd.SKIP);
David Lie2ad4d02011-04-08 18:41:00 -0700104 cmd.set_expect_response(expectResponse);
105 }
106 oldCmd = cmd.function();
David Li291f5fe2011-03-21 17:42:50 -0700107 Send(msg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -0700108 expectResponse = cmd.expect_response();
David Li55c94cc2011-03-04 17:50:48 -0800109 break;
110 }
111 }
112}
113
David Li5c425f22011-03-10 16:40:37 -0800114template<typename T>
115static inline void FetchIndexed(const unsigned count, const T * indices,
116 std::string * const data, const DbgContext * const ctx)
117{
118 for (unsigned i = 0; i < count; i++) {
119 if (!ctx->indexBuffer)
120 data->append((const char *)(indices + i), sizeof(*indices));
121 if (ctx->hasNonVBOAttribs)
122 ctx->Fetch(indices[i], data);
123 }
124}
125
David Li55c94cc2011-03-04 17:50:48 -0800126void Debug_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
127{
David Li5c425f22011-03-10 16:40:37 -0800128 DbgContext * const dbg = getDbgContextThreadSpecific();
David Li55c94cc2011-03-04 17:50:48 -0800129 glesv2debugger::Message msg, cmd;
David Li5c425f22011-03-10 16:40:37 -0800130 msg.set_context_id(reinterpret_cast<int>(dbg));
David Li55c94cc2011-03-04 17:50:48 -0800131 msg.set_type(glesv2debugger::Message_Type_BeforeCall);
David Lie2ad4d02011-04-08 18:41:00 -0700132 bool expectResponse = dbg->expectResponse.Bit(glesv2debugger::Message_Function_glDrawElements);
David Li55c94cc2011-03-04 17:50:48 -0800133 msg.set_expect_response(expectResponse);
134 msg.set_function(glesv2debugger::Message_Function_glDrawElements);
135 msg.set_arg0(mode);
136 msg.set_arg1(count);
137 msg.set_arg2(type);
138 msg.set_arg3(reinterpret_cast<int>(indices));
David Li5c425f22011-03-10 16:40:37 -0800139
140 msg.set_arg7(dbg->maxAttrib); // indicate capturing vertex data
141 std::string * const data = msg.mutable_data();
142 if (GL_UNSIGNED_BYTE == type) {
143 if (dbg->indexBuffer)
David Lif9bc1242011-03-22 18:42:03 -0700144 FetchIndexed(count, (unsigned char *)dbg->indexBuffer->data +
145 (unsigned long)indices, data, dbg);
David Li5c425f22011-03-10 16:40:37 -0800146 else
147 FetchIndexed(count, (unsigned char *)indices, data, dbg);
148 } else if (GL_UNSIGNED_SHORT == type) {
149 if (dbg->indexBuffer)
David Lif9bc1242011-03-22 18:42:03 -0700150 FetchIndexed(count, (unsigned short *)((char *)dbg->indexBuffer->data +
151 (unsigned long)indices), data, dbg);
David Li5c425f22011-03-10 16:40:37 -0800152 else
153 FetchIndexed(count, (unsigned short *)indices, data, dbg);
154 } else
155 assert(0);
156
157 void * pixels = NULL;
158 GLint readFormat = 0, readType = 0;
David Li55c94cc2011-03-04 17:50:48 -0800159 int viewport[4] = {};
David Lie2ad4d02011-04-08 18:41:00 -0700160 if (!expectResponse) {
David Li55c94cc2011-03-04 17:50:48 -0800161 cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
David Lie2ad4d02011-04-08 18:41:00 -0700162 cmd.set_expect_response(false);
163 }
164 glesv2debugger::Message_Function oldCmd = cmd.function();
David Li940c3f82011-03-10 19:07:42 -0800165 Send(msg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -0700166 expectResponse = cmd.expect_response();
David Li55c94cc2011-03-04 17:50:48 -0800167 while (true) {
168 msg.Clear();
169 nsecs_t c0 = systemTime(timeMode);
170 switch (cmd.function()) {
171 case glesv2debugger::Message_Function_CONTINUE:
David Li5c425f22011-03-10 16:40:37 -0800172 dbg->hooks->gl.glDrawElements(mode, count, type, indices);
David Li55c94cc2011-03-04 17:50:48 -0800173 msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
David Li5c425f22011-03-10 16:40:37 -0800174 msg.set_context_id(reinterpret_cast<int>(dbg));
David Li55c94cc2011-03-04 17:50:48 -0800175 msg.set_function(glesv2debugger::Message_Function_glDrawElements);
176 msg.set_type(glesv2debugger::Message_Type_AfterCall);
177 msg.set_expect_response(expectResponse);
David Li940c3f82011-03-10 19:07:42 -0800178 if (!expectResponse)
David Li55c94cc2011-03-04 17:50:48 -0800179 cmd.set_function(glesv2debugger::Message_Function_SKIP);
David Lie2ad4d02011-04-08 18:41:00 -0700180 if (!expectResponse) {
181 cmd.set_function(glesv2debugger::Message_Function_SKIP);
182 cmd.set_expect_response(false);
183 }
184 oldCmd = cmd.function();
David Li940c3f82011-03-10 19:07:42 -0800185 Send(msg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -0700186 expectResponse = cmd.expect_response();
187 // TODO: pack glReadPixels data with vertex data instead of
188 // relying on sperate call for transport, this would allow
189 // auto generated message loop using EXTEND_Debug macro
David Li940c3f82011-03-10 19:07:42 -0800190 if (capture) {
191 dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
192 dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
193 dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
David Li6a5ca482011-03-21 10:02:30 -0700194// LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
195// viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
David Lif9bc1242011-03-22 18:42:03 -0700196 pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
197 GetBytesPerPixel(readFormat, readType));
David Li940c3f82011-03-10 19:07:42 -0800198 Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
199 readFormat, readType, pixels);
David Li940c3f82011-03-10 19:07:42 -0800200 }
David Li55c94cc2011-03-04 17:50:48 -0800201 break;
202 case glesv2debugger::Message_Function_SKIP:
203 return;
David Li940c3f82011-03-10 19:07:42 -0800204 case glesv2debugger::Message_Function_SETPROP:
David Lifbfc7032011-03-21 16:25:58 -0700205 SetProp(dbg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -0700206 expectResponse = cmd.expect_response();
207 if (!expectResponse) // SETPROP is "out of band"
208 cmd.set_function(oldCmd);
209 else
210 Receive(cmd);
David Li55c94cc2011-03-04 17:50:48 -0800211 break;
212 default:
David Li291f5fe2011-03-21 17:42:50 -0700213 GenerateCall(dbg, cmd, msg, NULL);
214 msg.set_expect_response(expectResponse);
David Lie2ad4d02011-04-08 18:41:00 -0700215 if (!expectResponse) {
David Li291f5fe2011-03-21 17:42:50 -0700216 cmd.set_function(cmd.SKIP);
David Lie2ad4d02011-04-08 18:41:00 -0700217 cmd.set_expect_response(expectResponse);
218 }
219 oldCmd = cmd.function();
David Li291f5fe2011-03-21 17:42:50 -0700220 Send(msg, cmd);
David Lie2ad4d02011-04-08 18:41:00 -0700221 expectResponse = cmd.expect_response();
David Li55c94cc2011-03-04 17:50:48 -0800222 break;
223 }
224 }
225}