]> git.cworth.org Git - fips/blob - glwrap.c
Simplify metrics interface by dropping metrics_counter_new
[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          * If the application hasn't called dlopen on a "libGL"
75          * library, then presumably the application is linked directly
76          * to an OpenGL implementation. In this case, we can use
77          * RTLD_NEXT to find the symbol.
78          *
79          * But just in case, we also let the user override that by
80          * specifying the FIPS_LIBGL environment variable to the path
81          * of the real libGL.so library that fips should dlopen here.
82          */
83         if (gl_handle == NULL) {
84                 const char *path;
85
86                 path = getenv ("FIPS_LIBGL");
87                 if (path) {
88                         gl_handle = dlopen (path, RTLD_LAZY);
89
90                         if (gl_handle == NULL) {
91                                 fprintf (stderr, "Failed to dlopen FIPS_LIBGL: "
92                                          "%s\n", path);
93                                 exit (1);
94                         }
95                 } else {
96                         gl_handle = RTLD_NEXT;
97                 }
98         }
99
100         ret = dlwrap_real_dlsym (gl_handle, name);
101
102         if (ret == NULL) {
103                 fprintf (stderr, "Error: glwrap_lookup failed to dlsym %s\n",
104                          name);
105                 exit (1);
106         }
107
108         return ret;
109 }
110
111 /* Execute an OpenGL call and time it with a GPU metrics counter. */
112 #define TIMED_DEFER(function,...) do {                                  \
113         if (! inside_new_list) {                                        \
114                 metrics_counter_start ();                               \
115         }                                                               \
116         GLWRAP_DEFER(function, __VA_ARGS__);                            \
117         if (! inside_new_list) {                                        \
118                 metrics_counter_stop ();                                \
119         }                                                               \
120 } while (0);
121
122 /* Thanks to apitrace source code for the list of OpenGL draw calls. */
123 void
124 glDrawArrays (GLenum mode, GLint first, GLsizei count)
125 {
126         TIMED_DEFER (glDrawArrays, mode, first, count);
127 }
128
129 void
130 glDrawArraysEXT (GLenum mode, GLint first, GLsizei count)
131 {
132         TIMED_DEFER (glDrawArraysEXT, mode, first, count);
133 }
134
135 void
136 glDrawArraysIndirect (GLenum mode, const GLvoid *indirect)
137 {
138         TIMED_DEFER (glDrawArraysIndirect, mode, indirect);
139 }
140
141 void
142 glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count,
143                        GLsizei primcount)
144 {
145         TIMED_DEFER (glDrawArraysInstanced, mode, first, count, primcount);
146 }
147
148 void
149 glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count,
150                           GLsizei primcount)
151 {
152         TIMED_DEFER (glDrawArraysInstancedARB, mode, first, count, primcount);
153 }
154
155 void
156 glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count,
157                           GLsizei primcount)
158 {
159         TIMED_DEFER (glDrawArraysInstancedEXT, mode, start, count, primcount);
160 }
161
162 void
163 glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count,
164                                    GLsizei primcount, GLuint baseinstance)
165 {
166         TIMED_DEFER (glDrawArraysInstancedBaseInstance, mode,
167                      first, count, primcount, baseinstance);
168 }
169
170 void
171 glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width)
172 {
173         TIMED_DEFER (glDrawMeshArraysSUN, mode, first, count, width);
174 }
175
176 void
177 glMultiDrawArrays (GLenum mode, const GLint *first,
178                    const GLsizei *count, GLsizei primcount)
179 {
180         TIMED_DEFER (glMultiDrawArrays, mode, first, count, primcount);
181 }
182
183 void
184 glMultiDrawArraysEXT (GLenum mode, const GLint *first,
185                       const GLsizei *count, GLsizei primcount)
186 {
187         TIMED_DEFER (glMultiDrawArraysEXT, mode, first, count, primcount);
188 }
189
190 void
191 glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first,
192                           const GLsizei *count, GLsizei primcount,
193                           GLint modestride)
194 {
195         TIMED_DEFER (glMultiModeDrawArraysIBM, mode,
196                      first, count, primcount, modestride);
197 }
198
199 void
200 glMultiDrawArraysIndirect (GLenum mode, const void *indirect,
201                            GLsizei drawcount, GLsizei stride)
202 {
203         TIMED_DEFER (glMultiDrawArraysIndirect, mode, indirect, drawcount, stride);
204 }
205
206 void
207 glMultiDrawArraysIndirectAMD (GLenum mode, const GLvoid *indirect,
208                               GLsizei primcount, GLsizei stride)
209 {
210         TIMED_DEFER (glMultiDrawArraysIndirectAMD, mode,
211                      indirect, primcount, stride);
212 }
213
214 void
215 glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
216 {
217         TIMED_DEFER (glDrawElements, mode, count, type, indices);
218 }
219
220 void
221 glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type,
222                           const GLvoid *indices, GLint basevertex)
223 {
224         TIMED_DEFER (glDrawElementsBaseVertex, mode, count,
225                      type, indices, basevertex);
226 }
227
228 void
229 glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect)
230 {
231         TIMED_DEFER (glDrawElementsIndirect, mode, type, indirect);
232 }
233
234 void
235 glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type,
236                          const GLvoid *indices, GLsizei primcount)
237 {
238         TIMED_DEFER (glDrawElementsInstanced, mode, count,
239                      type, indices, primcount);
240 }
241
242 void
243 glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type,
244                             const GLvoid *indices, GLsizei primcount)
245 {
246         TIMED_DEFER (glDrawElementsInstancedARB, mode, count,
247                      type, indices, primcount);
248 }
249
250 void
251 glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type,
252                             const GLvoid *indices, GLsizei primcount)
253 {
254         TIMED_DEFER (glDrawElementsInstancedEXT, mode, count,
255                      type, indices, primcount);
256 }
257
258 void
259 glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type,
260                                    const GLvoid *indices, GLsizei primcount,
261                                    GLint basevertex)
262 {
263         TIMED_DEFER (glDrawElementsInstancedBaseVertex, mode, count,
264                      type, indices, primcount, basevertex);
265 }
266
267 void
268 glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type,
269                                      const void *indices, GLsizei primcount,
270                                      GLuint baseinstance)
271 {
272         TIMED_DEFER (glDrawElementsInstancedBaseInstance, mode, count, type,
273                      indices, primcount, baseinstance);
274 }
275
276 void
277 glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count,
278                       GLenum type, const void *indices, GLsizei primcount,
279                       GLint basevertex, GLuint baseinstance)
280 {
281         TIMED_DEFER (glDrawElementsInstancedBaseVertexBaseInstance, mode,
282                      count, type, indices, primcount, basevertex, baseinstance);
283 }
284
285 void
286 glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count,
287                      GLenum type, const GLvoid *indices)
288 {
289         TIMED_DEFER (glDrawRangeElements, mode, start, end,
290                      count, type, indices);
291 }
292
293 void
294 glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count,
295                         GLenum type, const GLvoid *indices)
296 {
297         TIMED_DEFER (glDrawRangeElementsEXT, mode, start, end,
298                      count, type, indices);
299 }
300
301 void
302 glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end,
303                                GLsizei count, GLenum type,
304                                const GLvoid *indices, GLint basevertex)
305 {
306         TIMED_DEFER (glDrawRangeElementsBaseVertex, mode, start, end,
307                      count, type, indices, basevertex);
308 }
309
310 void
311 glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type,
312                      const GLvoid* *indices, GLsizei primcount)
313 {
314         TIMED_DEFER (glMultiDrawElements, mode, count, type,
315                      indices, primcount);
316 }
317
318 void
319 glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count,
320                                GLenum type, const GLvoid* *indices,
321                                GLsizei primcount, const GLint *basevertex)
322 {
323         TIMED_DEFER (glMultiDrawElementsBaseVertex, mode, count,
324                      type, indices, primcount, basevertex);
325 }
326
327 void
328 glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type,
329                         const GLvoid* *indices, GLsizei primcount)
330 {
331         TIMED_DEFER (glMultiDrawElementsEXT, mode, count,
332                      type, indices, primcount);
333 }
334
335 void
336 glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count,
337                             GLenum type, const GLvoid* const *indices,
338                             GLsizei primcount, GLint modestride)
339 {
340         TIMED_DEFER (glMultiModeDrawElementsIBM, mode, count,
341                      type, indices, primcount, modestride);
342 }
343
344 void
345 glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect,
346                              GLsizei drawcount, GLsizei stride)
347 {
348         TIMED_DEFER (glMultiDrawElementsIndirect, mode, type,
349                      indirect, drawcount, stride);
350 }
351
352 void
353 glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type,
354                                 const GLvoid *indirect,
355                                 GLsizei primcount, GLsizei stride)
356 {
357         TIMED_DEFER (glMultiDrawElementsIndirectAMD, mode, type,
358                      indirect, primcount, stride);
359 }
360
361 void
362 glCallList (GLuint list)
363 {
364         TIMED_DEFER (glCallList, list);
365 }
366
367 void
368 glCallLists (GLsizei n, GLenum type, const GLvoid *lists)
369 {
370         TIMED_DEFER (glCallLists, n, type, lists);
371 }
372
373 void
374 glClear (GLbitfield mask)
375 {
376         TIMED_DEFER (glClear, mask);
377 }
378
379 /* We can't just use TIMED_DEFER for glBegin/glEnd since the metrics
380  * counter must be started before glBegin and stopped after glEnd,
381  * (that is, everything from glBegin to glEnd is counted as a single
382  * operation). */
383 void
384 glBegin (GLenum mode)
385 {
386         if (! inside_new_list)
387                 metrics_counter_start ();
388
389         GLWRAP_DEFER (glBegin, mode);
390 }
391
392 void
393 glEnd (void)
394 {
395         GLWRAP_DEFER (glEnd);
396
397         if (! inside_new_list)
398                 metrics_counter_stop ();
399 }
400
401 /* And we need to track display lists to avoid inserting queries
402  * inside the list while it's being constructed. */
403 void
404 glNewList (GLuint list, GLenum mode)
405 {
406         inside_new_list = 1;
407         GLWRAP_DEFER (glNewList, list, mode);
408 }
409
410 void
411 glEndList (void)
412 {
413         GLWRAP_DEFER (glEndList);
414         inside_new_list = 0;
415 }
416
417 void
418 glDrawPixels (GLsizei width, GLsizei height, GLenum format,
419               GLenum type, const GLvoid *pixels)
420 {
421         TIMED_DEFER (glDrawPixels, width, height, format, type, pixels);
422 }
423
424 void
425 glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
426                    GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
427                    GLbitfield mask, GLenum filter)
428 {
429         TIMED_DEFER (glBlitFramebuffer,
430                      srcX0, srcY0, srcX1, srcY1,
431                      dstX0, dstY0, dstX1, dstY1,
432                      mask, filter);
433 }
434
435 void
436 glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
437                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
438                       GLbitfield mask, GLenum filter)
439 {
440         TIMED_DEFER (glBlitFramebufferEXT,
441                      srcX0, srcY0, srcX1, srcY1,
442                      dstX0, dstY0, dstX1, dstY1,
443                      mask, filter);
444 }
445
446 void
447 glUseProgram (GLuint program)
448 {
449         metrics_set_current_program (program);
450
451         GLWRAP_DEFER(glUseProgram, program);
452 }
453
454 void
455 glUseProgramObjectARB (GLhandleARB programObj)
456 {
457         metrics_set_current_program (programObj);
458
459         GLWRAP_DEFER(glUseProgramObjectARB, programObj);
460 }