1 /* Copyright © 2013, Intel Corporation
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:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
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
24 /* The prototypes for some OpenGL functions changed at one point from:
26 * const void* *indices
28 * const void* const coist *indices
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.
34 * To workaround this problem, we simply #define away const altogether
35 * before including gl.h.
37 * Kudos to Keith Packard for suggesting this kludge.
41 #define GL_GLEXT_PROTOTYPES
50 static int inside_new_list = 0;
52 static void *gl_handle;
55 glwrap_set_gl_handle (void *handle)
57 if (gl_handle == NULL)
62 glwrap_lookup (char *name)
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.
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.
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.
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.
83 if (gl_handle == NULL) {
86 path = getenv ("FIPS_LIBGL");
88 gl_handle = dlopen (path, RTLD_LAZY);
90 if (gl_handle == NULL) {
91 fprintf (stderr, "Failed to dlopen FIPS_LIBGL: "
96 gl_handle = RTLD_NEXT;
100 ret = dlwrap_real_dlsym (gl_handle, name);
103 fprintf (stderr, "Error: glwrap_lookup failed to dlsym %s\n",
111 /* Execute an OpenGL call and time it with a GPU metrics counter. */
112 #define TIMED_DEFER(function,...) do { \
113 if (! inside_new_list) { \
115 counter = metrics_counter_new (); \
116 metrics_counter_start (counter); \
118 GLWRAP_DEFER(function, __VA_ARGS__); \
119 if (! inside_new_list) { \
120 metrics_counter_stop (); \
124 /* Thanks to apitrace source code for the list of OpenGL draw calls. */
126 glDrawArrays (GLenum mode, GLint first, GLsizei count)
128 TIMED_DEFER (glDrawArrays, mode, first, count);
132 glDrawArraysEXT (GLenum mode, GLint first, GLsizei count)
134 TIMED_DEFER (glDrawArraysEXT, mode, first, count);
138 glDrawArraysIndirect (GLenum mode, const GLvoid *indirect)
140 TIMED_DEFER (glDrawArraysIndirect, mode, indirect);
144 glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count,
147 TIMED_DEFER (glDrawArraysInstanced, mode, first, count, primcount);
151 glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count,
154 TIMED_DEFER (glDrawArraysInstancedARB, mode, first, count, primcount);
158 glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count,
161 TIMED_DEFER (glDrawArraysInstancedEXT, mode, start, count, primcount);
165 glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count,
166 GLsizei primcount, GLuint baseinstance)
168 TIMED_DEFER (glDrawArraysInstancedBaseInstance, mode,
169 first, count, primcount, baseinstance);
173 glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width)
175 TIMED_DEFER (glDrawMeshArraysSUN, mode, first, count, width);
179 glMultiDrawArrays (GLenum mode, const GLint *first,
180 const GLsizei *count, GLsizei primcount)
182 TIMED_DEFER (glMultiDrawArrays, mode, first, count, primcount);
186 glMultiDrawArraysEXT (GLenum mode, const GLint *first,
187 const GLsizei *count, GLsizei primcount)
189 TIMED_DEFER (glMultiDrawArraysEXT, mode, first, count, primcount);
193 glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first,
194 const GLsizei *count, GLsizei primcount,
197 TIMED_DEFER (glMultiModeDrawArraysIBM, mode,
198 first, count, primcount, modestride);
202 glMultiDrawArraysIndirect (GLenum mode, const void *indirect,
203 GLsizei drawcount, GLsizei stride)
205 TIMED_DEFER (glMultiDrawArraysIndirect, mode, indirect, drawcount, stride);
209 glMultiDrawArraysIndirectAMD (GLenum mode, const GLvoid *indirect,
210 GLsizei primcount, GLsizei stride)
212 TIMED_DEFER (glMultiDrawArraysIndirectAMD, mode,
213 indirect, primcount, stride);
217 glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
219 TIMED_DEFER (glDrawElements, mode, count, type, indices);
223 glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type,
224 const GLvoid *indices, GLint basevertex)
226 TIMED_DEFER (glDrawElementsBaseVertex, mode, count,
227 type, indices, basevertex);
231 glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect)
233 TIMED_DEFER (glDrawElementsIndirect, mode, type, indirect);
237 glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type,
238 const GLvoid *indices, GLsizei primcount)
240 TIMED_DEFER (glDrawElementsInstanced, mode, count,
241 type, indices, primcount);
245 glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type,
246 const GLvoid *indices, GLsizei primcount)
248 TIMED_DEFER (glDrawElementsInstancedARB, mode, count,
249 type, indices, primcount);
253 glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type,
254 const GLvoid *indices, GLsizei primcount)
256 TIMED_DEFER (glDrawElementsInstancedEXT, mode, count,
257 type, indices, primcount);
261 glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type,
262 const GLvoid *indices, GLsizei primcount,
265 TIMED_DEFER (glDrawElementsInstancedBaseVertex, mode, count,
266 type, indices, primcount, basevertex);
270 glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type,
271 const void *indices, GLsizei primcount,
274 TIMED_DEFER (glDrawElementsInstancedBaseInstance, mode, count, type,
275 indices, primcount, baseinstance);
279 glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count,
280 GLenum type, const void *indices, GLsizei primcount,
281 GLint basevertex, GLuint baseinstance)
283 TIMED_DEFER (glDrawElementsInstancedBaseVertexBaseInstance, mode,
284 count, type, indices, primcount, basevertex, baseinstance);
288 glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count,
289 GLenum type, const GLvoid *indices)
291 TIMED_DEFER (glDrawRangeElements, mode, start, end,
292 count, type, indices);
296 glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count,
297 GLenum type, const GLvoid *indices)
299 TIMED_DEFER (glDrawRangeElementsEXT, mode, start, end,
300 count, type, indices);
304 glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end,
305 GLsizei count, GLenum type,
306 const GLvoid *indices, GLint basevertex)
308 TIMED_DEFER (glDrawRangeElementsBaseVertex, mode, start, end,
309 count, type, indices, basevertex);
313 glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type,
314 const GLvoid* *indices, GLsizei primcount)
316 TIMED_DEFER (glMultiDrawElements, mode, count, type,
321 glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count,
322 GLenum type, const GLvoid* *indices,
323 GLsizei primcount, const GLint *basevertex)
325 TIMED_DEFER (glMultiDrawElementsBaseVertex, mode, count,
326 type, indices, primcount, basevertex);
330 glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type,
331 const GLvoid* *indices, GLsizei primcount)
333 TIMED_DEFER (glMultiDrawElementsEXT, mode, count,
334 type, indices, primcount);
338 glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count,
339 GLenum type, const GLvoid* const *indices,
340 GLsizei primcount, GLint modestride)
342 TIMED_DEFER (glMultiModeDrawElementsIBM, mode, count,
343 type, indices, primcount, modestride);
347 glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect,
348 GLsizei drawcount, GLsizei stride)
350 TIMED_DEFER (glMultiDrawElementsIndirect, mode, type,
351 indirect, drawcount, stride);
355 glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type,
356 const GLvoid *indirect,
357 GLsizei primcount, GLsizei stride)
359 TIMED_DEFER (glMultiDrawElementsIndirectAMD, mode, type,
360 indirect, primcount, stride);
364 glCallList (GLuint list)
366 TIMED_DEFER (glCallList, list);
370 glCallLists (GLsizei n, GLenum type, const GLvoid *lists)
372 TIMED_DEFER (glCallLists, n, type, lists);
376 glClear (GLbitfield mask)
378 TIMED_DEFER (glClear, mask);
381 /* We can't just use TIMED_DEFER for glBegin/glEnd since the metrics
382 * counter must be started before glBegin and stopped after glEnd,
383 * (that is, everything from glBegin to glEnd is counted as a single
386 glBegin (GLenum mode)
388 if (! inside_new_list)
391 counter = metrics_counter_new ();
392 metrics_counter_start (counter);
395 GLWRAP_DEFER (glBegin, mode);
401 GLWRAP_DEFER (glEnd);
403 if (! inside_new_list) {
404 metrics_counter_stop ();
408 /* And we need to track display lists to avoid inserting queries
409 * inside the list while it's being constructed. */
411 glNewList (GLuint list, GLenum mode)
414 GLWRAP_DEFER (glNewList, list, mode);
420 GLWRAP_DEFER (glEndList);
425 glDrawPixels (GLsizei width, GLsizei height, GLenum format,
426 GLenum type, const GLvoid *pixels)
428 TIMED_DEFER (glDrawPixels, width, height, format, type, pixels);
432 glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
433 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
434 GLbitfield mask, GLenum filter)
436 TIMED_DEFER (glBlitFramebuffer,
437 srcX0, srcY0, srcX1, srcY1,
438 dstX0, dstY0, dstX1, dstY1,
443 glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
444 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
445 GLbitfield mask, GLenum filter)
447 TIMED_DEFER (glBlitFramebufferEXT,
448 srcX0, srcY0, srcX1, srcY1,
449 dstX0, dstY0, dstX1, dstY1,
454 glUseProgram (GLuint program)
456 metrics_set_current_program (program);
458 GLWRAP_DEFER(glUseProgram, program);
462 glUseProgramObjectARB (GLhandleARB programObj)
464 metrics_set_current_program (programObj);
466 GLWRAP_DEFER(glUseProgramObjectARB, programObj);