]> git.cworth.org Git - fips/blob - glwrap.c
glxwrap: Initialize fips_dispatch when glxMakeContextCurrent is called
[fips] / glwrap.c
1 /* Copyright © 2013, Intel Corporation
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to deal
5  * in the Software without restriction, including without limitation the rights
6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  * copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19  * THE SOFTWARE.
20  */
21
22 #include "dlwrap.h"
23
24 /* The prototypes for some OpenGL functions changed at one point from:
25  *
26  *      const void* *indices
27  * to:
28  *      const void* const coist *indices
29  *
30  * This makes it difficult for us to provide an implementation of
31  * these functions that is consistent with the locally-available gl.h
32  * since we don't know if the extra const will be present or not.
33  *
34  * To workaround this problem, we simply #define away const altogether
35  * before including gl.h.
36  *
37  * Kudos to Keith Packard for suggesting this kludge.
38  */
39 #define const
40
41 #define GL_GLEXT_PROTOTYPES
42 #include <GL/gl.h>
43
44 #include "fips.h"
45
46 #include "glwrap.h"
47
48 #include "metrics.h"
49
50 static int inside_new_list = 0;
51
52 static void *gl_handle;
53
54 void
55 glwrap_set_gl_handle (void *handle)
56 {
57         if (gl_handle == NULL)
58                 gl_handle = handle;
59 }
60
61 void *
62 glwrap_lookup (char *name)
63 {
64         void *ret;
65
66         /* We don't call dlopen here to find the library in which to
67          * perform a dlsym lookup. That's because the application may
68          * be loading libGL.so or libGLESv2.so for its OpenGL symbols.
69          *
70          * So we instead watch for one of those filenames to go by in
71          * our dlopen wrapper, which will then call
72          * glwrap_set_gl_handle to give us the handle to use here.
73          *
74
75          * If the application hasn't called dlopen on a "libGL"
76          * library, then presumably the application is linked directly
77          * to an OpenGL implementation. In this case, we can use
78          * RTLD_NEXT to find the symbol.
79          */
80         if (gl_handle == NULL)
81                 gl_handle = RTLD_NEXT;
82
83         ret = dlwrap_real_dlsym (gl_handle, name);
84
85         if (ret == NULL) {
86                 fprintf (stderr, "Error: glwrap_lookup failed to dlsym %s\n",
87                          name);
88                 exit (1);
89         }
90
91         return ret;
92 }
93
94 /* Execute an OpenGL call and time it with a GPU metrics counter. */
95 #define TIMED_DEFER(function,...) do {                                  \
96         if (! inside_new_list) {                                        \
97                 unsigned counter;                                       \
98                 counter = metrics_counter_new ();                       \
99                 metrics_counter_start (counter);                        \
100         }                                                               \
101         GLWRAP_DEFER(function, __VA_ARGS__);                            \
102         if (! inside_new_list) {                                        \
103                 metrics_counter_stop ();                                \
104         }                                                               \
105 } while (0);
106
107 /* Thanks to apitrace source code for the list of OpenGL draw calls. */
108 void
109 glDrawArrays (GLenum mode, GLint first, GLsizei count)
110 {
111         TIMED_DEFER (glDrawArrays, mode, first, count);
112 }
113
114 void
115 glDrawArraysEXT (GLenum mode, GLint first, GLsizei count)
116 {
117         TIMED_DEFER (glDrawArraysEXT, mode, first, count);
118 }
119
120 void
121 glDrawArraysIndirect (GLenum mode, const GLvoid *indirect)
122 {
123         TIMED_DEFER (glDrawArraysIndirect, mode, indirect);
124 }
125
126 void
127 glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count,
128                        GLsizei primcount)
129 {
130         TIMED_DEFER (glDrawArraysInstanced, mode, first, count, primcount);
131 }
132
133 void
134 glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count,
135                           GLsizei primcount)
136 {
137         TIMED_DEFER (glDrawArraysInstancedARB, mode, first, count, primcount);
138 }
139
140 void
141 glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count,
142                           GLsizei primcount)
143 {
144         TIMED_DEFER (glDrawArraysInstancedEXT, mode, start, count, primcount);
145 }
146
147 void
148 glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count,
149                                    GLsizei primcount, GLuint baseinstance)
150 {
151         TIMED_DEFER (glDrawArraysInstancedBaseInstance, mode,
152                      first, count, primcount, baseinstance);
153 }
154
155 void
156 glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width)
157 {
158         TIMED_DEFER (glDrawMeshArraysSUN, mode, first, count, width);
159 }
160
161 void
162 glMultiDrawArrays (GLenum mode, const GLint *first,
163                    const GLsizei *count, GLsizei primcount)
164 {
165         TIMED_DEFER (glMultiDrawArrays, mode, first, count, primcount);
166 }
167
168 void
169 glMultiDrawArraysEXT (GLenum mode, const GLint *first,
170                       const GLsizei *count, GLsizei primcount)
171 {
172         TIMED_DEFER (glMultiDrawArraysEXT, mode, first, count, primcount);
173 }
174
175 void
176 glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first,
177                           const GLsizei *count, GLsizei primcount,
178                           GLint modestride)
179 {
180         TIMED_DEFER (glMultiModeDrawArraysIBM, mode,
181                      first, count, primcount, modestride);
182 }
183
184 void
185 glMultiDrawArraysIndirect (GLenum mode, const void *indirect,
186                            GLsizei drawcount, GLsizei stride)
187 {
188         TIMED_DEFER (glMultiDrawArraysIndirect, mode, indirect, drawcount, stride);
189 }
190
191 void
192 glMultiDrawArraysIndirectAMD (GLenum mode, const GLvoid *indirect,
193                               GLsizei primcount, GLsizei stride)
194 {
195         TIMED_DEFER (glMultiDrawArraysIndirectAMD, mode,
196                      indirect, primcount, stride);
197 }
198
199 void
200 glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
201 {
202         TIMED_DEFER (glDrawElements, mode, count, type, indices);
203 }
204
205 void
206 glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type,
207                           const GLvoid *indices, GLint basevertex)
208 {
209         TIMED_DEFER (glDrawElementsBaseVertex, mode, count,
210                      type, indices, basevertex);
211 }
212
213 void
214 glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect)
215 {
216         TIMED_DEFER (glDrawElementsIndirect, mode, type, indirect);
217 }
218
219 void
220 glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type,
221                          const GLvoid *indices, GLsizei primcount)
222 {
223         TIMED_DEFER (glDrawElementsInstanced, mode, count,
224                      type, indices, primcount);
225 }
226
227 void
228 glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type,
229                             const GLvoid *indices, GLsizei primcount)
230 {
231         TIMED_DEFER (glDrawElementsInstancedARB, mode, count,
232                      type, indices, primcount);
233 }
234
235 void
236 glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type,
237                             const GLvoid *indices, GLsizei primcount)
238 {
239         TIMED_DEFER (glDrawElementsInstancedEXT, mode, count,
240                      type, indices, primcount);
241 }
242
243 void
244 glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type,
245                                    const GLvoid *indices, GLsizei primcount,
246                                    GLint basevertex)
247 {
248         TIMED_DEFER (glDrawElementsInstancedBaseVertex, mode, count,
249                      type, indices, primcount, basevertex);
250 }
251
252 void
253 glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type,
254                                      const void *indices, GLsizei primcount,
255                                      GLuint baseinstance)
256 {
257         TIMED_DEFER (glDrawElementsInstancedBaseInstance, mode, count, type,
258                      indices, primcount, baseinstance);
259 }
260
261 void
262 glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count,
263                       GLenum type, const void *indices, GLsizei primcount,
264                       GLint basevertex, GLuint baseinstance)
265 {
266         TIMED_DEFER (glDrawElementsInstancedBaseVertexBaseInstance, mode,
267                      count, type, indices, primcount, basevertex, baseinstance);
268 }
269
270 void
271 glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count,
272                      GLenum type, const GLvoid *indices)
273 {
274         TIMED_DEFER (glDrawRangeElements, mode, start, end,
275                      count, type, indices);
276 }
277
278 void
279 glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count,
280                         GLenum type, const GLvoid *indices)
281 {
282         TIMED_DEFER (glDrawRangeElementsEXT, mode, start, end,
283                      count, type, indices);
284 }
285
286 void
287 glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end,
288                                GLsizei count, GLenum type,
289                                const GLvoid *indices, GLint basevertex)
290 {
291         TIMED_DEFER (glDrawRangeElementsBaseVertex, mode, start, end,
292                      count, type, indices, basevertex);
293 }
294
295 void
296 glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type,
297                      const GLvoid* *indices, GLsizei primcount)
298 {
299         TIMED_DEFER (glMultiDrawElements, mode, count, type,
300                      indices, primcount);
301 }
302
303 void
304 glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count,
305                                GLenum type, const GLvoid* *indices,
306                                GLsizei primcount, const GLint *basevertex)
307 {
308         TIMED_DEFER (glMultiDrawElementsBaseVertex, mode, count,
309                      type, indices, primcount, basevertex);
310 }
311
312 void
313 glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type,
314                         const GLvoid* *indices, GLsizei primcount)
315 {
316         TIMED_DEFER (glMultiDrawElementsEXT, mode, count,
317                      type, indices, primcount);
318 }
319
320 void
321 glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count,
322                             GLenum type, const GLvoid* const *indices,
323                             GLsizei primcount, GLint modestride)
324 {
325         TIMED_DEFER (glMultiModeDrawElementsIBM, mode, count,
326                      type, indices, primcount, modestride);
327 }
328
329 void
330 glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect,
331                              GLsizei drawcount, GLsizei stride)
332 {
333         TIMED_DEFER (glMultiDrawElementsIndirect, mode, type,
334                      indirect, drawcount, stride);
335 }
336
337 void
338 glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type,
339                                 const GLvoid *indirect,
340                                 GLsizei primcount, GLsizei stride)
341 {
342         TIMED_DEFER (glMultiDrawElementsIndirectAMD, mode, type,
343                      indirect, primcount, stride);
344 }
345
346 void
347 glCallList (GLuint list)
348 {
349         TIMED_DEFER (glCallList, list);
350 }
351
352 void
353 glCallLists (GLsizei n, GLenum type, const GLvoid *lists)
354 {
355         TIMED_DEFER (glCallLists, n, type, lists);
356 }
357
358 void
359 glClear (GLbitfield mask)
360 {
361         TIMED_DEFER (glClear, mask);
362 }
363
364 /* We can't just use TIMED_DEFER for glBegin/glEnd since the metrics
365  * counter must be started before glBegin and stopped after glEnd,
366  * (that is, everything from glBegin to glEnd is counted as a single
367  * operation). */
368 void
369 glBegin (GLenum mode)
370 {
371         if (! inside_new_list)
372         {
373                 unsigned counter;
374                 counter = metrics_counter_new ();
375                 metrics_counter_start (counter);
376         }
377
378         GLWRAP_DEFER (glBegin, mode);
379 }
380
381 void
382 glEnd (void)
383 {
384         GLWRAP_DEFER (glEnd);
385
386         if (! inside_new_list) {
387                 metrics_counter_stop ();
388         }
389 }
390
391 /* And we need to track display lists to avoid inserting queries
392  * inside the list while it's being constructed. */
393 void
394 glNewList (GLuint list, GLenum mode)
395 {
396         inside_new_list = 1;
397         GLWRAP_DEFER (glNewList, list, mode);
398 }
399
400 void
401 glEndList (void)
402 {
403         GLWRAP_DEFER (glEndList);
404         inside_new_list = 0;
405 }
406
407 void
408 glDrawPixels (GLsizei width, GLsizei height, GLenum format,
409               GLenum type, const GLvoid *pixels)
410 {
411         TIMED_DEFER (glDrawPixels, width, height, format, type, pixels);
412 }
413
414 void
415 glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
416                    GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
417                    GLbitfield mask, GLenum filter)
418 {
419         TIMED_DEFER (glBlitFramebuffer,
420                      srcX0, srcY0, srcX1, srcY1,
421                      dstX0, dstY0, dstX1, dstY1,
422                      mask, filter);
423 }
424
425 void
426 glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
427                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
428                       GLbitfield mask, GLenum filter)
429 {
430         TIMED_DEFER (glBlitFramebufferEXT,
431                      srcX0, srcY0, srcX1, srcY1,
432                      dstX0, dstY0, dstX1, dstY1,
433                      mask, filter);
434 }
435
436 void
437 glUseProgram (GLuint program)
438 {
439         metrics_set_current_program (program);
440
441         GLWRAP_DEFER(glUseProgram, program);
442 }
443
444 void
445 glUseProgramObjectARB (GLhandleARB programObj)
446 {
447         metrics_set_current_program (programObj);
448
449         GLWRAP_DEFER(glUseProgramObjectARB, programObj);
450 }