• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Debug_glDrawArrays(GLenum mode,GLint first,GLsizei count)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>
FetchIndexed(const unsigned count,const T * indices,std::string * const data,const DbgContext * const ctx)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 
Debug_glDrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)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