]> git.tdb.fi Git - gldbg.git/blob - source/glwrap.c
Packetize the command stream for more robustness
[gldbg.git] / source / glwrap.c
1 /* $Id$
2
3 This file is part of gldbg
4 Copyright © 2009  Mikko Rasa, Mikkosoft Productions
5 Distributed under the GPL
6 */
7
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <dlfcn.h>
12 #include <sys/uio.h>
13 #include <GL/gl.h>
14 #include "functions.h"
15
16 static inline void *glsym(const char *sym)
17 {
18         static void *libgl = NULL;
19         if(!libgl)
20         {
21                 libgl = dlopen("libGL.so", RTLD_NOW);
22                 if(!libgl)
23                 {
24                         fprintf(stderr, "Could not open libGL: %s\n", dlerror());
25                         abort();
26                 }
27         }
28
29         return dlsym(libgl, sym);
30 }
31
32 static char *buffer = 0;
33 static char *write_pos;
34 static struct iovec *iovecs = 0;
35 static struct iovec *cur_vec;
36 static unsigned length;
37
38 static inline void next_vec()
39 {
40         if(write_pos!=cur_vec->iov_base)
41         {
42                 cur_vec->iov_len = write_pos-(char *)cur_vec->iov_base;
43                 length += cur_vec->iov_len;
44                 ++cur_vec;
45                 cur_vec->iov_base = write_pos;
46         }
47 }
48
49 static inline void write_bytes(const char *ptr, unsigned size)
50 {
51         unsigned i;
52         for(i=0; i<size; ++i)
53                 *write_pos++ = *ptr++;
54 }
55
56 static inline void write_char(char v)
57 {
58         *write_pos++ = v;
59 }
60
61 static inline void write_short(short v)
62 {
63         write_bytes((char *)&v, sizeof(short));
64 }
65
66 static inline void write_int(int v)
67 {
68         write_bytes((char *)&v, sizeof(int));
69 }
70
71 static inline void write_long(long v)
72 {
73         write_bytes((char *)&v, sizeof(long));
74 }
75
76 static inline void write_ulong(unsigned long v)
77 {
78         write_bytes((char *)&v, sizeof(unsigned long));
79 }
80
81 static inline void write_longlong(long long v)
82 {
83         write_bytes((char *)&v, sizeof(long long));
84 }
85
86 static inline void write_float(float v)
87 {
88         write_bytes((char *)&v, sizeof(float));
89 }
90
91 static inline void write_double(double v)
92 {
93         write_bytes((char *)&v, sizeof(double));
94 }
95
96 static inline void write_pointer(const void *p)
97 {
98         write_bytes((char *)&p, sizeof(void *));
99 }
100
101 static inline void write_data(const void *data, unsigned size)
102 {
103         if(data)
104         {
105                 write_int(size);
106                 next_vec();
107                 cur_vec->iov_base = (void *)data;
108                 cur_vec->iov_len = size;
109                 length += size;
110                 ++cur_vec;
111                 cur_vec->iov_base = write_pos;
112         }
113         else
114                 write_int(0);
115 }
116
117 static inline void write_string(const unsigned char *s)
118 {
119         write_data(s, strlen(s));
120 }
121
122 static inline void begin_packet(int func)
123 {
124         if(!buffer)
125                 buffer = (char *)malloc(1024);
126         if(!iovecs)
127                 iovecs = (struct iovec *)malloc(16*sizeof(struct iovec));
128         write_pos = buffer;
129         cur_vec = iovecs;
130         cur_vec->iov_base = write_pos;
131         length = 0;
132         write_int(0);
133         write_short(func);
134 }
135
136 static inline void send_packet()
137 {
138         static int fd = -1;
139         if(fd<0)
140         {
141                 const char *var = getenv("GLWRAP_FD");
142                 if(var)
143                         fd = strtol(var, NULL, 0);
144                 else
145                         fd = 2;
146         }
147         next_vec();
148         write_pos = buffer;
149         write_int(length);
150         writev(fd, iovecs, cur_vec-iovecs);
151 }
152
153 static inline int typesize(GLenum type)
154 {
155         switch(type)
156         {
157         case GL_BYTE: return sizeof(GLbyte);
158         case GL_SHORT: return sizeof(GLshort);
159         case GL_INT: return sizeof(GLint);
160         case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
161         case GL_UNSIGNED_SHORT: return sizeof(GLushort);
162         case GL_UNSIGNED_INT: return sizeof(GLuint);
163         case GL_FLOAT: return sizeof(GLfloat);
164         case GL_DOUBLE: return sizeof(GLdouble);
165         // Short and byte packed types are broken
166         default: return 1;
167         }
168 }
169
170 static inline int formatsize(GLenum format)
171 {
172         switch(format)
173         {
174         case GL_COLOR_INDEX: return 1;
175         case GL_STENCIL_INDEX: return 1;
176         case GL_DEPTH_COMPONENT: return 1;
177         case GL_RED: return 1;
178         case GL_GREEN: return 1;
179         case GL_BLUE: return 1;
180         case GL_ALPHA: return 1;
181         case GL_RGB: return 3;
182         case GL_RGBA: return 4;
183         case GL_BGR: return 3;
184         case GL_BGRA: return 4;
185         case GL_LUMINANCE: return 1;
186         case GL_LUMINANCE_ALPHA: return 2;
187         default: return 1;
188         }
189 }
190
191 static inline int paramsize(GLenum pname)
192 {
193         switch(pname)
194         {
195         // Lighting and material
196         case GL_AMBIENT: return 4;
197         case GL_DIFFUSE: return 4;
198         case GL_AMBIENT_AND_DIFFUSE: return 4;
199         case GL_SPECULAR: return 4;
200         case GL_EMISSION: return 4;
201         case GL_SHININESS: return 1;
202         case GL_COLOR_INDEXES: return 3;
203         case GL_POSITION: return 4;
204         case GL_SPOT_DIRECTION: return 3;
205         case GL_SPOT_EXPONENT: return 1;
206         case GL_SPOT_CUTOFF: return 1;
207         case GL_CONSTANT_ATTENUATION: return 1;
208         case GL_LINEAR_ATTENUATION: return 1;
209         case GL_QUADRATIC_ATTENUATION: return 1;
210         case GL_LIGHT_MODEL_AMBIENT: return 4;
211         case GL_LIGHT_MODEL_LOCAL_VIEWER: return 1;
212         case GL_LIGHT_MODEL_TWO_SIDE: return 1;
213         case GL_LIGHT_MODEL_COLOR_CONTROL: return 1;
214
215         // Texture
216         case GL_TEXTURE_WRAP_S: return 1;
217         case GL_TEXTURE_WRAP_T: return 1;
218         case GL_TEXTURE_WRAP_R: return 1;
219         case GL_TEXTURE_MIN_FILTER: return 1;
220         case GL_TEXTURE_MAG_FILTER: return 1;
221         case GL_TEXTURE_BORDER_COLOR: return 4;
222         case GL_TEXTURE_MIN_LOD: return 1;
223         case GL_TEXTURE_MAX_LOD: return 1;
224         case GL_TEXTURE_BASE_LEVEL: return 1;
225         case GL_TEXTURE_MAX_LEVEL: return 1;
226         case GL_TEXTURE_LOD_BIAS: return 1;
227         case GL_DEPTH_TEXTURE_MODE: return 1;
228         case GL_TEXTURE_COMPARE_MODE: return 1;
229         case GL_TEXTURE_COMPARE_FUNC: return 1;
230         case GL_GENERATE_MIPMAP: return 1;
231         default: return 1;
232         }
233 }
234
235 static inline int mapsize(GLenum target)
236 {
237         return 1;
238 }
239
240 #include "glwrap.funcs"