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.
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.
80 if (gl_handle == NULL)
81 gl_handle = RTLD_NEXT;
83 ret = dlwrap_real_dlsym (gl_handle, name);
86 fprintf (stderr, "Error: glwrap_lookup failed to dlsym %s\n",
94 /* Execute an OpenGL call and time it with a GPU metrics counter. */
95 #define TIMED_DEFER(function,...) do { \
96 if (! inside_new_list) { \
98 counter = metrics_counter_new (); \
99 metrics_counter_start (counter); \
101 GLWRAP_DEFER(function, __VA_ARGS__); \
102 if (! inside_new_list) { \
103 metrics_counter_stop (); \
107 /* Thanks to apitrace source code for the list of OpenGL draw calls. */
109 glDrawArrays (GLenum mode, GLint first, GLsizei count)
111 TIMED_DEFER (glDrawArrays, mode, first, count);
115 glDrawArraysEXT (GLenum mode, GLint first, GLsizei count)
117 TIMED_DEFER (glDrawArraysEXT, mode, first, count);
121 glDrawArraysIndirect (GLenum mode, const GLvoid *indirect)
123 TIMED_DEFER (glDrawArraysIndirect, mode, indirect);
127 glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count,
130 TIMED_DEFER (glDrawArraysInstanced, mode, first, count, primcount);
134 glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count,
137 TIMED_DEFER (glDrawArraysInstancedARB, mode, first, count, primcount);
141 glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count,
144 TIMED_DEFER (glDrawArraysInstancedEXT, mode, start, count, primcount);
148 glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count,
149 GLsizei primcount, GLuint baseinstance)
151 TIMED_DEFER (glDrawArraysInstancedBaseInstance, mode,
152 first, count, primcount, baseinstance);
156 glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width)
158 TIMED_DEFER (glDrawMeshArraysSUN, mode, first, count, width);
162 glMultiDrawArrays (GLenum mode, const GLint *first,
163 const GLsizei *count, GLsizei primcount)
165 TIMED_DEFER (glMultiDrawArrays, mode, first, count, primcount);
169 glMultiDrawArraysEXT (GLenum mode, const GLint *first,
170 const GLsizei *count, GLsizei primcount)
172 TIMED_DEFER (glMultiDrawArraysEXT, mode, first, count, primcount);
176 glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first,
177 const GLsizei *count, GLsizei primcount,
180 TIMED_DEFER (glMultiModeDrawArraysIBM, mode,
181 first, count, primcount, modestride);
185 glMultiDrawArraysIndirect (GLenum mode, const void *indirect,
186 GLsizei drawcount, GLsizei stride)
188 TIMED_DEFER (glMultiDrawArraysIndirect, mode, indirect, drawcount, stride);
192 glMultiDrawArraysIndirectAMD (GLenum mode, const GLvoid *indirect,
193 GLsizei primcount, GLsizei stride)
195 TIMED_DEFER (glMultiDrawArraysIndirectAMD, mode,
196 indirect, primcount, stride);
200 glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
202 TIMED_DEFER (glDrawElements, mode, count, type, indices);
206 glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type,
207 const GLvoid *indices, GLint basevertex)
209 TIMED_DEFER (glDrawElementsBaseVertex, mode, count,
210 type, indices, basevertex);
214 glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect)
216 TIMED_DEFER (glDrawElementsIndirect, mode, type, indirect);
220 glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type,
221 const GLvoid *indices, GLsizei primcount)
223 TIMED_DEFER (glDrawElementsInstanced, mode, count,
224 type, indices, primcount);
228 glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type,
229 const GLvoid *indices, GLsizei primcount)
231 TIMED_DEFER (glDrawElementsInstancedARB, mode, count,
232 type, indices, primcount);
236 glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type,
237 const GLvoid *indices, GLsizei primcount)
239 TIMED_DEFER (glDrawElementsInstancedEXT, mode, count,
240 type, indices, primcount);
244 glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type,
245 const GLvoid *indices, GLsizei primcount,
248 TIMED_DEFER (glDrawElementsInstancedBaseVertex, mode, count,
249 type, indices, primcount, basevertex);
253 glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type,
254 const void *indices, GLsizei primcount,
257 TIMED_DEFER (glDrawElementsInstancedBaseInstance, mode, count, type,
258 indices, primcount, baseinstance);
262 glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count,
263 GLenum type, const void *indices, GLsizei primcount,
264 GLint basevertex, GLuint baseinstance)
266 TIMED_DEFER (glDrawElementsInstancedBaseVertexBaseInstance, mode,
267 count, type, indices, primcount, basevertex, baseinstance);
271 glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count,
272 GLenum type, const GLvoid *indices)
274 TIMED_DEFER (glDrawRangeElements, mode, start, end,
275 count, type, indices);
279 glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count,
280 GLenum type, const GLvoid *indices)
282 TIMED_DEFER (glDrawRangeElementsEXT, mode, start, end,
283 count, type, indices);
287 glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end,
288 GLsizei count, GLenum type,
289 const GLvoid *indices, GLint basevertex)
291 TIMED_DEFER (glDrawRangeElementsBaseVertex, mode, start, end,
292 count, type, indices, basevertex);
296 glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type,
297 const GLvoid* *indices, GLsizei primcount)
299 TIMED_DEFER (glMultiDrawElements, mode, count, type,
304 glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count,
305 GLenum type, const GLvoid* *indices,
306 GLsizei primcount, const GLint *basevertex)
308 TIMED_DEFER (glMultiDrawElementsBaseVertex, mode, count,
309 type, indices, primcount, basevertex);
313 glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type,
314 const GLvoid* *indices, GLsizei primcount)
316 TIMED_DEFER (glMultiDrawElementsEXT, mode, count,
317 type, indices, primcount);
321 glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count,
322 GLenum type, const GLvoid* const *indices,
323 GLsizei primcount, GLint modestride)
325 TIMED_DEFER (glMultiModeDrawElementsIBM, mode, count,
326 type, indices, primcount, modestride);
330 glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect,
331 GLsizei drawcount, GLsizei stride)
333 TIMED_DEFER (glMultiDrawElementsIndirect, mode, type,
334 indirect, drawcount, stride);
338 glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type,
339 const GLvoid *indirect,
340 GLsizei primcount, GLsizei stride)
342 TIMED_DEFER (glMultiDrawElementsIndirectAMD, mode, type,
343 indirect, primcount, stride);
347 glCallList (GLuint list)
349 TIMED_DEFER (glCallList, list);
353 glCallLists (GLsizei n, GLenum type, const GLvoid *lists)
355 TIMED_DEFER (glCallLists, n, type, lists);
359 glClear (GLbitfield mask)
361 TIMED_DEFER (glClear, mask);
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
369 glBegin (GLenum mode)
371 if (! inside_new_list)
374 counter = metrics_counter_new ();
375 metrics_counter_start (counter);
378 GLWRAP_DEFER (glBegin, mode);
384 GLWRAP_DEFER (glEnd);
386 if (! inside_new_list) {
387 metrics_counter_stop ();
391 /* And we need to track display lists to avoid inserting queries
392 * inside the list while it's being constructed. */
394 glNewList (GLuint list, GLenum mode)
397 GLWRAP_DEFER (glNewList, list, mode);
403 GLWRAP_DEFER (glEndList);
408 glDrawPixels (GLsizei width, GLsizei height, GLenum format,
409 GLenum type, const GLvoid *pixels)
411 TIMED_DEFER (glDrawPixels, width, height, format, type, pixels);
415 glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
416 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
417 GLbitfield mask, GLenum filter)
419 TIMED_DEFER (glBlitFramebuffer,
420 srcX0, srcY0, srcX1, srcY1,
421 dstX0, dstY0, dstX1, dstY1,
426 glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
427 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
428 GLbitfield mask, GLenum filter)
430 TIMED_DEFER (glBlitFramebufferEXT,
431 srcX0, srcY0, srcX1, srcY1,
432 dstX0, dstY0, dstX1, dstY1,
437 glUseProgram (GLuint program)
439 metrics_set_current_program (program);
441 GLWRAP_DEFER(glUseProgram, program);
445 glUseProgramObjectARB (GLhandleARB programObj)
447 metrics_set_current_program (programObj);
449 GLWRAP_DEFER(glUseProgramObjectARB, programObj);