X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglwrap.c;h=cd1c328139e784f2a4bea80d90297e86401d4402;hb=a832996c884a0e0acc9a38ba4dd258edb75ec7af;hp=10bfc77fcb12cd56f21149444593f8df57de8d52;hpb=fab9ed5163a8f4ef5314bc67e48d1690d1126649;p=gldbg.git diff --git a/source/glwrap.c b/source/glwrap.c index 10bfc77..cd1c328 100644 --- a/source/glwrap.c +++ b/source/glwrap.c @@ -1,16 +1,22 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - #include #include #include #include #include #include +#include +#include "arraysize.h" +#include "breakpoint.h" +#include "functions.h" +#include "opengl.h" +#include "packet.h" + +#define UNUSED __attribute__((unused)) + +static unsigned char breakpoints[N_FUNCS] = { }; +static char break_any = 0; +static char hold = 0; +static char no_break = 0; static const char *get_lib_names(void) { @@ -102,3 +108,128 @@ int get_out_fd(void) return fd; } + +int get_in_fd(void) +{ + static int fd = -1; + + if(fd<0) + { + const char *var = getenv("GLWRAP_CTRL_FD"); + if(var) + fd = strtol(var, NULL, 0); + else + fd = 0; + } + + return fd; +} + +static void receive_gldBreak(GlPacket *pkt) +{ + unsigned short func; + unsigned char flags_set; + unsigned char flags_clr; + + packet_read_short(pkt, (short *)&func); + packet_read_char(pkt, (char *)&flags_set); + packet_read_char(pkt, (char *)&flags_clr); + + if(func) + { + breakpoints[func] &= ~flags_clr; + breakpoints[func] |= flags_set; + } + else + break_any = flags_set; +} + +static void receive_gldHold(GlPacket *pkt UNUSED) +{ + hold = 1; +} + +static void receive_gldQueryViewport(GlPacket *pkt UNUSED) +{ + int viewport[4]; + + no_break = 1; + glGetIntegerv(GL_VIEWPORT, viewport); + no_break = 0; +} + +static void receive_gldReadPixels(GlPacket *pkt) +{ + GLint x, y; + GLsizei width, height; + GLenum format, type; + char *data; + + packet_read_int(pkt, &x); + packet_read_int(pkt, &y); + packet_read_int(pkt, &width); + packet_read_int(pkt, &height); + packet_read_int(pkt, (int *)&format); + packet_read_int(pkt, (int *)&type); + + data = (char *)malloc(width*height*typesize(type)*formatsize(format)); + no_break = 1; + glReadPixels(x, y, width, height, format, type, data); + no_break = 0; + free(data); +} + +static void receive(void) +{ + GlPacket *pkt; + + while((pkt = packet_receive(get_in_fd()))) + { + unsigned short func; + + packet_read_short(pkt, (short *)&func); + switch(func) + { + case FUNC_GLDBREAK: receive_gldBreak(pkt); break; + case FUNC_GLDHOLD: receive_gldHold(pkt); break; + case FUNC_GLDQUERYVIEWPORT: receive_gldQueryViewport(pkt); break; + case FUNC_GLDREADPIXELS: receive_gldReadPixels(pkt); break; + default:; + } + } +} + +void tracepoint(unsigned short func, int flag) +{ + int breakpoint; + + if(no_break) + return; + + receive(); + + breakpoint = (breakpoints[func]|break_any)&flag; + if(breakpoint || hold) + { + GlPacket *pkt; + + if(breakpoint) + { + pkt = packet_begin(FUNC_GLDBREAK); + packet_write_short(pkt, func); + packet_write_char(pkt, flag); + packet_send(pkt, get_out_fd()); + } + + break_any = 0; + + while(1) + { + hold = 0; + raise(SIGTRAP); + receive(); + if(!hold) + break; + } + } +}