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) { \
114 metrics_counter_start (); \
116 GLWRAP_DEFER(function, __VA_ARGS__); \
117 if (! inside_new_list) { \
118 metrics_counter_stop (); \
122 /* Thanks to apitrace source code for the list of OpenGL draw calls. */
124 glDrawArrays (GLenum mode, GLint first, GLsizei count)
126 TIMED_DEFER (glDrawArrays, mode, first, count);
130 glDrawArraysEXT (GLenum mode, GLint first, GLsizei count)
132 TIMED_DEFER (glDrawArraysEXT, mode, first, count);
136 glDrawArraysIndirect (GLenum mode, const GLvoid *indirect)
138 TIMED_DEFER (glDrawArraysIndirect, mode, indirect);
142 glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count,
145 TIMED_DEFER (glDrawArraysInstanced, mode, first, count, primcount);
149 glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count,
152 TIMED_DEFER (glDrawArraysInstancedARB, mode, first, count, primcount);
156 glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count,
159 TIMED_DEFER (glDrawArraysInstancedEXT, mode, start, count, primcount);
163 glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count,
164 GLsizei primcount, GLuint baseinstance)
166 TIMED_DEFER (glDrawArraysInstancedBaseInstance, mode,
167 first, count, primcount, baseinstance);
171 glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width)
173 TIMED_DEFER (glDrawMeshArraysSUN, mode, first, count, width);
177 glMultiDrawArrays (GLenum mode, const GLint *first,
178 const GLsizei *count, GLsizei primcount)
180 TIMED_DEFER (glMultiDrawArrays, mode, first, count, primcount);
184 glMultiDrawArraysEXT (GLenum mode, const GLint *first,
185 const GLsizei *count, GLsizei primcount)
187 TIMED_DEFER (glMultiDrawArraysEXT, mode, first, count, primcount);
191 glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first,
192 const GLsizei *count, GLsizei primcount,
195 TIMED_DEFER (glMultiModeDrawArraysIBM, mode,
196 first, count, primcount, modestride);
200 glMultiDrawArraysIndirect (GLenum mode, const void *indirect,
201 GLsizei drawcount, GLsizei stride)
203 TIMED_DEFER (glMultiDrawArraysIndirect, mode, indirect, drawcount, stride);
207 glMultiDrawArraysIndirectAMD (GLenum mode, const GLvoid *indirect,
208 GLsizei primcount, GLsizei stride)
210 TIMED_DEFER (glMultiDrawArraysIndirectAMD, mode,
211 indirect, primcount, stride);
215 glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
217 TIMED_DEFER (glDrawElements, mode, count, type, indices);
221 glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type,
222 const GLvoid *indices, GLint basevertex)
224 TIMED_DEFER (glDrawElementsBaseVertex, mode, count,
225 type, indices, basevertex);
229 glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect)
231 TIMED_DEFER (glDrawElementsIndirect, mode, type, indirect);
235 glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type,
236 const GLvoid *indices, GLsizei primcount)
238 TIMED_DEFER (glDrawElementsInstanced, mode, count,
239 type, indices, primcount);
243 glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type,
244 const GLvoid *indices, GLsizei primcount)
246 TIMED_DEFER (glDrawElementsInstancedARB, mode, count,
247 type, indices, primcount);
251 glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type,
252 const GLvoid *indices, GLsizei primcount)
254 TIMED_DEFER (glDrawElementsInstancedEXT, mode, count,
255 type, indices, primcount);
259 glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type,
260 const GLvoid *indices, GLsizei primcount,
263 TIMED_DEFER (glDrawElementsInstancedBaseVertex, mode, count,
264 type, indices, primcount, basevertex);
268 glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type,
269 const void *indices, GLsizei primcount,
272 TIMED_DEFER (glDrawElementsInstancedBaseInstance, mode, count, type,
273 indices, primcount, baseinstance);
277 glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count,
278 GLenum type, const void *indices, GLsizei primcount,
279 GLint basevertex, GLuint baseinstance)
281 TIMED_DEFER (glDrawElementsInstancedBaseVertexBaseInstance, mode,
282 count, type, indices, primcount, basevertex, baseinstance);
286 glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count,
287 GLenum type, const GLvoid *indices)
289 TIMED_DEFER (glDrawRangeElements, mode, start, end,
290 count, type, indices);
294 glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count,
295 GLenum type, const GLvoid *indices)
297 TIMED_DEFER (glDrawRangeElementsEXT, mode, start, end,
298 count, type, indices);
302 glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end,
303 GLsizei count, GLenum type,
304 const GLvoid *indices, GLint basevertex)
306 TIMED_DEFER (glDrawRangeElementsBaseVertex, mode, start, end,
307 count, type, indices, basevertex);
311 glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type,
312 const GLvoid* *indices, GLsizei primcount)
314 TIMED_DEFER (glMultiDrawElements, mode, count, type,
319 glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count,
320 GLenum type, const GLvoid* *indices,
321 GLsizei primcount, const GLint *basevertex)
323 TIMED_DEFER (glMultiDrawElementsBaseVertex, mode, count,
324 type, indices, primcount, basevertex);
328 glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type,
329 const GLvoid* *indices, GLsizei primcount)
331 TIMED_DEFER (glMultiDrawElementsEXT, mode, count,
332 type, indices, primcount);
336 glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count,
337 GLenum type, const GLvoid* const *indices,
338 GLsizei primcount, GLint modestride)
340 TIMED_DEFER (glMultiModeDrawElementsIBM, mode, count,
341 type, indices, primcount, modestride);
345 glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect,
346 GLsizei drawcount, GLsizei stride)
348 TIMED_DEFER (glMultiDrawElementsIndirect, mode, type,
349 indirect, drawcount, stride);
353 glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type,
354 const GLvoid *indirect,
355 GLsizei primcount, GLsizei stride)
357 TIMED_DEFER (glMultiDrawElementsIndirectAMD, mode, type,
358 indirect, primcount, stride);
362 glCallList (GLuint list)
364 TIMED_DEFER (glCallList, list);
368 glCallLists (GLsizei n, GLenum type, const GLvoid *lists)
370 TIMED_DEFER (glCallLists, n, type, lists);
374 glClear (GLbitfield mask)
376 TIMED_DEFER (glClear, mask);
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
384 glBegin (GLenum mode)
386 if (! inside_new_list)
387 metrics_counter_start ();
389 GLWRAP_DEFER (glBegin, mode);
395 GLWRAP_DEFER (glEnd);
397 if (! inside_new_list)
398 metrics_counter_stop ();
401 /* And we need to track display lists to avoid inserting queries
402 * inside the list while it's being constructed. */
404 glNewList (GLuint list, GLenum mode)
407 GLWRAP_DEFER (glNewList, list, mode);
413 GLWRAP_DEFER (glEndList);
418 glDrawPixels (GLsizei width, GLsizei height, GLenum format,
419 GLenum type, const GLvoid *pixels)
421 TIMED_DEFER (glDrawPixels, width, height, format, type, pixels);
425 glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
426 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
427 GLbitfield mask, GLenum filter)
429 TIMED_DEFER (glBlitFramebuffer,
430 srcX0, srcY0, srcX1, srcY1,
431 dstX0, dstY0, dstX1, dstY1,
436 glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
437 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
438 GLbitfield mask, GLenum filter)
440 TIMED_DEFER (glBlitFramebufferEXT,
441 srcX0, srcY0, srcX1, srcY1,
442 dstX0, dstY0, dstX1, dstY1,
447 glUseProgram (GLuint program)
449 metrics_set_current_program (program);
451 GLWRAP_DEFER(glUseProgram, program);
455 glUseProgramObjectARB (GLhandleARB programObj)
457 metrics_set_current_program (programObj);
459 GLWRAP_DEFER(glUseProgramObjectARB, programObj);