]> git.tdb.fi Git - gldbg.git/blobdiff - source/glwrap.c
Query implementation limits on process startup
[gldbg.git] / source / glwrap.c
index 10bfc77fcb12cd56f21149444593f8df57de8d52..ee679577011931b7264fda5e011fecda59077d35 100644 (file)
@@ -1,16 +1,22 @@
-/* $Id$
-
-This file is part of gldbg
-Copyright © 2009-2010  Mikko Rasa, Mikkosoft Productions
-Distributed under the GPL
-*/
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
 #include <dlfcn.h>
 #include <fcntl.h>
+#include <signal.h>
+#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,143 @@ 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_gldQueryLimits(GlPacket *pkt UNUSED)
+{
+       int value;
+
+       no_break = 1;
+       value = 0;
+       glGetIntegerv(GL_MAX_TEXTURE_UNITS, &value);
+       value = 0;
+       glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value);
+       value = 0;
+       glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &value);
+       no_break = 0;
+}
+
+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;
+               case FUNC_GLDQUERYLIMITS: receive_gldQueryLimits(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;
+               }
+       }
+}