blob: 029ee3bf50a7fdc9e165c187a72817cfdf90516d [file] [log] [blame]
/*
** Copyright 2011, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#include "header.h"
namespace android
{
bool capture; // capture after each glDraw*
}
void Debug_glDrawArrays(GLenum mode, GLint first, GLsizei count)
{
DbgContext * const dbg = getDbgContextThreadSpecific();
glesv2debugger::Message msg, cmd;
msg.set_context_id(reinterpret_cast<int>(dbg));
msg.set_type(glesv2debugger::Message_Type_BeforeCall);
bool expectResponse = dbg->expectResponse.Bit(glesv2debugger::Message_Function_glDrawArrays);
msg.set_expect_response(expectResponse);
msg.set_function(glesv2debugger::Message_Function_glDrawArrays);
msg.set_arg0(mode);
msg.set_arg1(first);
msg.set_arg2(count);
msg.set_arg7(dbg->maxAttrib); // indicate capturing vertex data
if (dbg->hasNonVBOAttribs) {
std::string * const data = msg.mutable_data();
for (unsigned i = 0; i < count; i++)
dbg->Fetch(i + first, data);
}
void * pixels = NULL;
int viewport[4] = {};
cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
cmd.set_expect_response(expectResponse);
glesv2debugger::Message_Function oldCmd = cmd.function();
Send(msg, cmd);
expectResponse = cmd.expect_response();
while (true) {
msg.Clear();
nsecs_t c0 = systemTime(timeMode);
switch (cmd.function()) {
case glesv2debugger::Message_Function_CONTINUE:
dbg->hooks->gl.glDrawArrays(mode, first, count);
msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
msg.set_context_id(reinterpret_cast<int>(dbg));
msg.set_function(glesv2debugger::Message_Function_glDrawArrays);
msg.set_type(glesv2debugger::Message_Type_AfterCall);
msg.set_expect_response(expectResponse);
if (!expectResponse) {
cmd.set_function(glesv2debugger::Message_Function_SKIP);
cmd.set_expect_response(false);
}
oldCmd = cmd.function();
Send(msg, cmd);
expectResponse = cmd.expect_response();
// TODO: pack glReadPixels data with vertex data instead of
// relying on sperate call for transport, this would allow
// auto generated message loop using EXTEND_Debug macro
if (dbg->captureDraw > 0) {
dbg->captureDraw--;
dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
// LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
// viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
dbg->readBytesPerPixel);
Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
dbg->readFormat, dbg->readType, pixels);
}
break;
case glesv2debugger::Message_Function_SKIP:
return;
case glesv2debugger::Message_Function_SETPROP:
SetProp(dbg, cmd);
expectResponse = cmd.expect_response();
if (!expectResponse) // SETPROP is "out of band"
cmd.set_function(oldCmd);
else
Receive(cmd);
break;
default:
GenerateCall(dbg, cmd, msg, NULL);
msg.set_expect_response(expectResponse);
if (!expectResponse) {
cmd.set_function(cmd.SKIP);
cmd.set_expect_response(expectResponse);
}
oldCmd = cmd.function();
Send(msg, cmd);
expectResponse = cmd.expect_response();
break;
}
}
}
template<typename T>
static inline void FetchIndexed(const unsigned count, const T * indices,
std::string * const data, const DbgContext * const ctx)
{
for (unsigned i = 0; i < count; i++) {
if (!ctx->indexBuffer)
data->append((const char *)(indices + i), sizeof(*indices));
if (ctx->hasNonVBOAttribs)
ctx->Fetch(indices[i], data);
}
}
void Debug_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
{
DbgContext * const dbg = getDbgContextThreadSpecific();
glesv2debugger::Message msg, cmd;
msg.set_context_id(reinterpret_cast<int>(dbg));
msg.set_type(glesv2debugger::Message_Type_BeforeCall);
bool expectResponse = dbg->expectResponse.Bit(glesv2debugger::Message_Function_glDrawElements);
msg.set_expect_response(expectResponse);
msg.set_function(glesv2debugger::Message_Function_glDrawElements);
msg.set_arg0(mode);
msg.set_arg1(count);
msg.set_arg2(type);
msg.set_arg3(reinterpret_cast<int>(indices));
msg.set_arg7(dbg->maxAttrib); // indicate capturing vertex data
std::string * const data = msg.mutable_data();
if (GL_UNSIGNED_BYTE == type) {
if (dbg->indexBuffer)
FetchIndexed(count, (unsigned char *)dbg->indexBuffer->data +
(unsigned long)indices, data, dbg);
else
FetchIndexed(count, (unsigned char *)indices, data, dbg);
} else if (GL_UNSIGNED_SHORT == type) {
if (dbg->indexBuffer)
FetchIndexed(count, (unsigned short *)((char *)dbg->indexBuffer->data +
(unsigned long)indices), data, dbg);
else
FetchIndexed(count, (unsigned short *)indices, data, dbg);
} else
assert(0);
void * pixels = NULL;
int viewport[4] = {};
cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
cmd.set_expect_response(expectResponse);
glesv2debugger::Message_Function oldCmd = cmd.function();
Send(msg, cmd);
expectResponse = cmd.expect_response();
while (true) {
msg.Clear();
nsecs_t c0 = systemTime(timeMode);
switch (cmd.function()) {
case glesv2debugger::Message_Function_CONTINUE:
dbg->hooks->gl.glDrawElements(mode, count, type, indices);
msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
msg.set_context_id(reinterpret_cast<int>(dbg));
msg.set_function(glesv2debugger::Message_Function_glDrawElements);
msg.set_type(glesv2debugger::Message_Type_AfterCall);
msg.set_expect_response(expectResponse);
if (!expectResponse) {
cmd.set_function(glesv2debugger::Message_Function_SKIP);
cmd.set_expect_response(false);
}
oldCmd = cmd.function();
Send(msg, cmd);
expectResponse = cmd.expect_response();
// TODO: pack glReadPixels data with vertex data instead of
// relying on sperate call for transport, this would allow
// auto generated message loop using EXTEND_Debug macro
if (dbg->captureDraw > 0) {
dbg->captureDraw--;
dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
dbg->readBytesPerPixel);
Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
dbg->readFormat, dbg->readType, pixels);
}
break;
case glesv2debugger::Message_Function_SKIP:
return;
case glesv2debugger::Message_Function_SETPROP:
SetProp(dbg, cmd);
expectResponse = cmd.expect_response();
if (!expectResponse) // SETPROP is "out of band"
cmd.set_function(oldCmd);
else
Receive(cmd);
break;
default:
GenerateCall(dbg, cmd, msg, NULL);
msg.set_expect_response(expectResponse);
if (!expectResponse) {
cmd.set_function(cmd.SKIP);
cmd.set_expect_response(expectResponse);
}
oldCmd = cmd.function();
Send(msg, cmd);
expectResponse = cmd.expect_response();
break;
}
}
}