1 /**************************************************************************
3 * Copyright 2011 Jose Fonseca
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 **************************************************************************/
28 #include "retrace.hpp"
29 #include "glretrace.hpp"
32 using namespace glretrace;
35 typedef std::map<unsigned long, glws::Drawable *> DrawableMap;
36 typedef std::map<void *, glws::Context *> ContextMap;
37 static DrawableMap drawable_map;
38 static ContextMap context_map;
41 static glws::Drawable *
42 getDrawable(unsigned long drawable_id) {
43 if (drawable_id == 0) {
47 DrawableMap::const_iterator it;
48 it = drawable_map.find(drawable_id);
49 if (it == drawable_map.end()) {
50 return (drawable_map[drawable_id] = ws->createDrawable(visual));
56 static void retrace_glXChooseVisual(Trace::Call &call) {
59 static void retrace_glXCreateContext(Trace::Call &call) {
60 void * orig_context = call.ret->toPointer();
61 glws::Context *share_context = NULL;
63 if (call.arg(2).toPointer()) {
64 share_context = context_map[call.arg(2).toPointer()];
67 glws::Context *context = ws->createContext(glretrace::visual, share_context);
68 context_map[orig_context] = context;
71 static void retrace_glXDestroyContext(Trace::Call &call) {
74 static void retrace_glXMakeCurrent(Trace::Call &call) {
75 glws::Drawable *new_drawable = getDrawable(call.arg(1).toUInt());
76 glws::Context *new_context = context_map[call.arg(2).toPointer()];
78 if (new_drawable == drawable && new_context == context) {
82 if (drawable && context) {
85 frame_complete(call.no);
89 bool result = ws->makeCurrent(new_drawable, new_context);
91 if (new_drawable && new_context && result) {
92 drawable = new_drawable;
93 context = new_context;
100 static void retrace_glXCopyContext(Trace::Call &call) {
103 static void retrace_glXSwapBuffers(Trace::Call &call) {
104 frame_complete(call.no);
106 drawable->swapBuffers();
112 static void retrace_glXCreateGLXPixmap(Trace::Call &call) {
115 static void retrace_glXDestroyGLXPixmap(Trace::Call &call) {
118 static void retrace_glXQueryExtension(Trace::Call &call) {
121 static void retrace_glXQueryVersion(Trace::Call &call) {
124 static void retrace_glXIsDirect(Trace::Call &call) {
127 static void retrace_glXGetConfig(Trace::Call &call) {
130 static void retrace_glXWaitGL(Trace::Call &call) {
133 static void retrace_glXWaitX(Trace::Call &call) {
136 static void retrace_glXUseXFont(Trace::Call &call) {
139 static void retrace_glXQueryExtensionsString(Trace::Call &call) {
142 static void retrace_glXQueryServerString(Trace::Call &call) {
145 static void retrace_glXGetClientString(Trace::Call &call) {
148 static void retrace_glXChooseFBConfig(Trace::Call &call) {
151 static void retrace_glXGetFBConfigAttrib(Trace::Call &call) {
154 static void retrace_glXGetFBConfigs(Trace::Call &call) {
157 static void retrace_glXGetVisualFromFBConfig(Trace::Call &call) {
160 static void retrace_glXCreateWindow(Trace::Call &call) {
163 static void retrace_glXDestroyWindow(Trace::Call &call) {
166 static void retrace_glXCreatePixmap(Trace::Call &call) {
169 static void retrace_glXDestroyPixmap(Trace::Call &call) {
172 static void retrace_glXCreatePbuffer(Trace::Call &call) {
175 static void retrace_glXDestroyPbuffer(Trace::Call &call) {
178 static void retrace_glXQueryDrawable(Trace::Call &call) {
181 static void retrace_glXCreateNewContext(Trace::Call &call) {
182 void * orig_context = call.ret->toPointer();
183 glws::Context *share_context = NULL;
185 if (call.arg(3).toPointer()) {
186 share_context = context_map[call.arg(3).toPointer()];
189 glws::Context *context = ws->createContext(glretrace::visual, share_context);
190 context_map[orig_context] = context;
193 static void retrace_glXMakeContextCurrent(Trace::Call &call) {
194 glws::Drawable *new_drawable = getDrawable(call.arg(1).toUInt());
195 glws::Context *new_context = context_map[call.arg(3).toPointer()];
197 if (new_drawable == drawable && new_context == context) {
201 if (drawable && context) {
203 if (!double_buffer) {
204 frame_complete(call.no);
208 bool result = ws->makeCurrent(new_drawable, new_context);
210 if (new_drawable && new_context && result) {
211 drawable = new_drawable;
212 context = new_context;
219 static void retrace_glXGetCurrentReadDrawable(Trace::Call &call) {
222 static void retrace_glXQueryContext(Trace::Call &call) {
225 static void retrace_glXSelectEvent(Trace::Call &call) {
228 static void retrace_glXGetSelectedEvent(Trace::Call &call) {
231 static void retrace_glXGetProcAddressARB(Trace::Call &call) {
234 static void retrace_glXGetProcAddress(Trace::Call &call) {
237 void glretrace::retrace_call_glx(Trace::Call &call) {
238 const char *name = call.name();
254 if (name[10] == 'B' && name[11] == 'C' && name[12] == 'o' && name[13] == 'n' && name[14] == 'f' && name[15] == 'i' && name[16] == 'g' && name[17] == '\0') {
256 retrace_glXChooseFBConfig(call);
261 if (name[10] == 'i' && name[11] == 's' && name[12] == 'u' && name[13] == 'a' && name[14] == 'l' && name[15] == '\0') {
263 retrace_glXChooseVisual(call);
278 if (name[5] == 'p' && name[6] == 'y' && name[7] == 'C' && name[8] == 'o' && name[9] == 'n' && name[10] == 't' && name[11] == 'e' && name[12] == 'x' && name[13] == 't' && name[14] == '\0') {
280 retrace_glXCopyContext(call);
295 if (name[10] == 'o' && name[11] == 'n' && name[12] == 't' && name[13] == 'e' && name[14] == 'x' && name[15] == 't' && name[16] == '\0') {
297 retrace_glXCreateContext(call);
302 if (name[10] == 'L' && name[11] == 'X' && name[12] == 'P' && name[13] == 'i' && name[14] == 'x' && name[15] == 'm' && name[16] == 'a' && name[17] == 'p' && name[18] == '\0') {
303 // glXCreateGLXPixmap
304 retrace_glXCreateGLXPixmap(call);
309 if (name[10] == 'e' && name[11] == 'w' && name[12] == 'C' && name[13] == 'o' && name[14] == 'n' && name[15] == 't' && name[16] == 'e' && name[17] == 'x' && name[18] == 't' && name[19] == '\0') {
310 // glXCreateNewContext
311 retrace_glXCreateNewContext(call);
318 if (name[11] == 'u' && name[12] == 'f' && name[13] == 'f' && name[14] == 'e' && name[15] == 'r' && name[16] == '\0') {
320 retrace_glXCreatePbuffer(call);
325 if (name[11] == 'x' && name[12] == 'm' && name[13] == 'a' && name[14] == 'p' && name[15] == '\0') {
327 retrace_glXCreatePixmap(call);
334 if (name[10] == 'i' && name[11] == 'n' && name[12] == 'd' && name[13] == 'o' && name[14] == 'w' && name[15] == '\0') {
336 retrace_glXCreateWindow(call);
367 if (name[11] == 'o' && name[12] == 'n' && name[13] == 't' && name[14] == 'e' && name[15] == 'x' && name[16] == 't' && name[17] == '\0') {
369 retrace_glXDestroyContext(call);
374 if (name[11] == 'L' && name[12] == 'X' && name[13] == 'P' && name[14] == 'i' && name[15] == 'x' && name[16] == 'm' && name[17] == 'a' && name[18] == 'p' && name[19] == '\0') {
375 // glXDestroyGLXPixmap
376 retrace_glXDestroyGLXPixmap(call);
383 if (name[12] == 'u' && name[13] == 'f' && name[14] == 'f' && name[15] == 'e' && name[16] == 'r' && name[17] == '\0') {
385 retrace_glXDestroyPbuffer(call);
390 if (name[12] == 'x' && name[13] == 'm' && name[14] == 'a' && name[15] == 'p' && name[16] == '\0') {
392 retrace_glXDestroyPixmap(call);
399 if (name[11] == 'i' && name[12] == 'n' && name[13] == 'd' && name[14] == 'o' && name[15] == 'w' && name[16] == '\0') {
401 retrace_glXDestroyWindow(call);
428 if (name[8] == 'i' && name[9] == 'e' && name[10] == 'n' && name[11] == 't' && name[12] == 'S' && name[13] == 't' && name[14] == 'r' && name[15] == 'i' && name[16] == 'n' && name[17] == 'g' && name[18] == '\0') {
429 // glXGetClientString
430 retrace_glXGetClientString(call);
435 if (name[8] == 'n' && name[9] == 'f' && name[10] == 'i' && name[11] == 'g' && name[12] == '\0') {
437 retrace_glXGetConfig(call);
454 if (name[14] == 'o' && name[15] == 'n' && name[16] == 't' && name[17] == 'e' && name[18] == 'x' && name[19] == 't' && name[20] == '\0') {
455 // glXGetCurrentContext
462 if (name[15] == 's' && name[16] == 'p' && name[17] == 'l' && name[18] == 'a' && name[19] == 'y' && name[20] == '\0') {
463 // glXGetCurrentDisplay
468 if (name[15] == 'a' && name[16] == 'w' && name[17] == 'a' && name[18] == 'b' && name[19] == 'l' && name[20] == 'e' && name[21] == '\0') {
469 // glXGetCurrentDrawable
476 if (name[14] == 'e' && name[15] == 'a' && name[16] == 'd' && name[17] == 'D' && name[18] == 'r' && name[19] == 'a' && name[20] == 'w' && name[21] == 'a' && name[22] == 'b' && name[23] == 'l' && name[24] == 'e' && name[25] == '\0') {
477 // glXGetCurrentReadDrawable
478 retrace_glXGetCurrentReadDrawable(call);
513 if (name[15] == 't' && name[16] == 't' && name[17] == 'r' && name[18] == 'i' && name[19] == 'b' && name[20] == '\0') {
514 // glXGetFBConfigAttrib
515 retrace_glXGetFBConfigAttrib(call);
520 if (name[15] == '\0') {
522 retrace_glXGetFBConfigs(call);
566 retrace_glXGetProcAddress(call);
570 if (name[18] == 'R' && name[19] == 'B' && name[20] == '\0') {
571 // glXGetProcAddressARB
572 retrace_glXGetProcAddressARB(call);
599 if (name[7] == 'e' && name[8] == 'l' && name[9] == 'e' && name[10] == 'c' && name[11] == 't' && name[12] == 'e' && name[13] == 'd' && name[14] == 'E' && name[15] == 'v' && name[16] == 'e' && name[17] == 'n' && name[18] == 't' && name[19] == '\0') {
600 // glXGetSelectedEvent
601 retrace_glXGetSelectedEvent(call);
606 if (name[7] == 'i' && name[8] == 's' && name[9] == 'u' && name[10] == 'a' && name[11] == 'l' && name[12] == 'F' && name[13] == 'r' && name[14] == 'o' && name[15] == 'm' && name[16] == 'F' && name[17] == 'B' && name[18] == 'C' && name[19] == 'o' && name[20] == 'n' && name[21] == 'f' && name[22] == 'i' && name[23] == 'g' && name[24] == '\0') {
607 // glXGetVisualFromFBConfig
608 retrace_glXGetVisualFromFBConfig(call);
619 if (name[4] == 's' && name[5] == 'D' && name[6] == 'i' && name[7] == 'r' && name[8] == 'e' && name[9] == 'c' && name[10] == 't' && name[11] == '\0') {
621 retrace_glXIsDirect(call);
636 if (name[9] == 'n' && name[10] == 't' && name[11] == 'e' && name[12] == 'x' && name[13] == 't' && name[14] == 'C' && name[15] == 'u' && name[16] == 'r' && name[17] == 'r' && name[18] == 'e' && name[19] == 'n' && name[20] == 't' && name[21] == '\0') {
637 // glXMakeContextCurrent
638 retrace_glXMakeContextCurrent(call);
643 if (name[9] == 'r' && name[10] == 'r' && name[11] == 'e' && name[12] == 'n' && name[13] == 't' && name[14] == '\0') {
645 retrace_glXMakeCurrent(call);
670 if (name[9] == 'o' && name[10] == 'n' && name[11] == 't' && name[12] == 'e' && name[13] == 'x' && name[14] == 't' && name[15] == '\0') {
672 retrace_glXQueryContext(call);
677 if (name[9] == 'r' && name[10] == 'a' && name[11] == 'w' && name[12] == 'a' && name[13] == 'b' && name[14] == 'l' && name[15] == 'e' && name[16] == '\0') {
679 retrace_glXQueryDrawable(call);
703 retrace_glXQueryExtension(call);
707 if (name[18] == 'S' && name[19] == 't' && name[20] == 'r' && name[21] == 'i' && name[22] == 'n' && name[23] == 'g' && name[24] == '\0') {
708 // glXQueryExtensionsString
709 retrace_glXQueryExtensionsString(call);
732 if (name[9] == 'e' && name[10] == 'r' && name[11] == 'v' && name[12] == 'e' && name[13] == 'r' && name[14] == 'S' && name[15] == 't' && name[16] == 'r' && name[17] == 'i' && name[18] == 'n' && name[19] == 'g' && name[20] == '\0') {
733 // glXQueryServerString
734 retrace_glXQueryServerString(call);
739 if (name[9] == 'e' && name[10] == 'r' && name[11] == 's' && name[12] == 'i' && name[13] == 'o' && name[14] == 'n' && name[15] == '\0') {
741 retrace_glXQueryVersion(call);
758 if (name[5] == 'l' && name[6] == 'e' && name[7] == 'c' && name[8] == 't' && name[9] == 'E' && name[10] == 'v' && name[11] == 'e' && name[12] == 'n' && name[13] == 't' && name[14] == '\0') {
760 retrace_glXSelectEvent(call);
765 if (name[5] == 'a' && name[6] == 'p' && name[7] == 'B' && name[8] == 'u' && name[9] == 'f' && name[10] == 'f' && name[11] == 'e' && name[12] == 'r' && name[13] == 's' && name[14] == '\0') {
767 retrace_glXSwapBuffers(call);
774 if (name[4] == 's' && name[5] == 'e' && name[6] == 'X' && name[7] == 'F' && name[8] == 'o' && name[9] == 'n' && name[10] == 't' && name[11] == '\0') {
776 retrace_glXUseXFont(call);
789 if (name[8] == 'L' && name[9] == '\0') {
791 retrace_glXWaitGL(call);
796 if (name[8] == '\0') {
798 retrace_glXWaitX(call);
811 retrace::retrace_unknown(call);