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 long, glws::Drawable *> DrawableMap;
36 typedef std::map<unsigned long long, glws::Context *> ContextMap;
37 static DrawableMap drawable_map;
38 static DrawableMap pbuffer_map;
39 static ContextMap context_map;
42 static glws::Drawable *
43 getDrawable(unsigned long long hdc) {
48 DrawableMap::const_iterator it;
49 it = drawable_map.find(hdc);
50 if (it == drawable_map.end()) {
51 return (drawable_map[hdc] = ws->createDrawable(visual));
57 static void retrace_wglCreateContext(Trace::Call &call) {
58 unsigned long long orig_context = call.ret->toUIntPtr();
59 glws::Context *context = ws->createContext(glretrace::visual);
60 context_map[orig_context] = context;
63 static void retrace_wglDeleteContext(Trace::Call &call) {
66 static void retrace_wglMakeCurrent(Trace::Call &call) {
67 if (drawable && context) {
70 frame_complete(call.no);
74 glws::Drawable *new_drawable = getDrawable(call.arg(0).toUIntPtr());
75 glws::Context *new_context = context_map[call.arg(1).toUIntPtr()];
77 bool result = ws->makeCurrent(new_drawable, new_context);
79 if (new_drawable && new_context && result) {
80 drawable = new_drawable;
81 context = new_context;
88 static void retrace_wglCopyContext(Trace::Call &call) {
91 static void retrace_wglChoosePixelFormat(Trace::Call &call) {
94 static void retrace_wglDescribePixelFormat(Trace::Call &call) {
97 static void retrace_wglSetPixelFormat(Trace::Call &call) {
100 static void retrace_wglSwapBuffers(Trace::Call &call) {
101 frame_complete(call.no);
103 drawable->swapBuffers();
109 static void retrace_wglShareLists(Trace::Call &call) {
110 unsigned long long hglrc1 = call.arg(0).toUIntPtr();
111 unsigned long long hglrc2 = call.arg(1).toUIntPtr();
113 glws::Context *share_context = context_map[hglrc1];
114 glws::Context *old_context = context_map[hglrc2];
116 glws::Context *new_context =
117 ws->createContext(old_context->visual, share_context);
120 context_map[hglrc2] = new_context;
124 static void retrace_wglCreateLayerContext(Trace::Call &call) {
125 retrace_wglCreateContext(call);
128 static void retrace_wglDescribeLayerPlane(Trace::Call &call) {
131 static void retrace_wglSetLayerPaletteEntries(Trace::Call &call) {
134 static void retrace_wglRealizeLayerPalette(Trace::Call &call) {
137 static void retrace_wglSwapLayerBuffers(Trace::Call &call) {
138 retrace_wglSwapBuffers(call);
141 static void retrace_wglUseFontBitmapsA(Trace::Call &call) {
144 static void retrace_wglUseFontBitmapsW(Trace::Call &call) {
147 static void retrace_wglSwapMultipleBuffers(Trace::Call &call) {
150 static void retrace_wglUseFontOutlinesA(Trace::Call &call) {
153 static void retrace_wglUseFontOutlinesW(Trace::Call &call) {
156 static void retrace_wglCreateBufferRegionARB(Trace::Call &call) {
159 static void retrace_wglDeleteBufferRegionARB(Trace::Call &call) {
162 static void retrace_wglSaveBufferRegionARB(Trace::Call &call) {
165 static void retrace_wglRestoreBufferRegionARB(Trace::Call &call) {
168 static void retrace_wglChoosePixelFormatARB(Trace::Call &call) {
171 static void retrace_wglMakeContextCurrentARB(Trace::Call &call) {
174 static void retrace_wglCreatePbufferARB(Trace::Call &call) {
175 int iWidth = call.arg(2).toUInt();
176 int iHeight = call.arg(3).toUInt();
178 unsigned long long orig_pbuffer = call.ret->toUIntPtr();
179 glws::Drawable *drawable = ws->createDrawable(glretrace::visual);
181 drawable->resize(iWidth, iHeight);
183 pbuffer_map[orig_pbuffer] = drawable;
186 static void retrace_wglGetPbufferDCARB(Trace::Call &call) {
187 glws::Drawable *pbuffer = pbuffer_map[call.arg(0).toUIntPtr()];
189 unsigned long long orig_hdc = call.ret->toUIntPtr();
191 drawable_map[orig_hdc] = pbuffer;
194 static void retrace_wglReleasePbufferDCARB(Trace::Call &call) {
197 static void retrace_wglDestroyPbufferARB(Trace::Call &call) {
200 static void retrace_wglQueryPbufferARB(Trace::Call &call) {
203 static void retrace_wglBindTexImageARB(Trace::Call &call) {
206 static void retrace_wglReleaseTexImageARB(Trace::Call &call) {
209 static void retrace_wglSetPbufferAttribARB(Trace::Call &call) {
212 static void retrace_wglCreateContextAttribsARB(Trace::Call &call) {
213 unsigned long long orig_context = call.ret->toUIntPtr();
214 glws::Context *share_context = NULL;
216 if (call.arg(1).toPointer()) {
217 share_context = context_map[call.arg(1).toUIntPtr()];
220 glws::Context *context = ws->createContext(glretrace::visual, share_context);
221 context_map[orig_context] = context;
224 static void retrace_wglMakeContextCurrentEXT(Trace::Call &call) {
227 static void retrace_wglChoosePixelFormatEXT(Trace::Call &call) {
230 static void retrace_wglSwapIntervalEXT(Trace::Call &call) {
233 static void retrace_wglAllocateMemoryNV(Trace::Call &call) {
236 static void retrace_wglFreeMemoryNV(Trace::Call &call) {
239 static void retrace_glAddSwapHintRectWIN(Trace::Call &call) {
242 static void retrace_wglGetProcAddress(Trace::Call &call) {
245 void glretrace::retrace_call_wgl(Trace::Call &call) {
246 const char *name = call.name();
250 if (name[1] == 'l' && name[2] == 'A' && name[3] == 'd' && name[4] == 'd' && name[5] == 'S' && name[6] == 'w' && name[7] == 'a' && name[8] == 'p' && name[9] == 'H' && name[10] == 'i' && name[11] == 'n' && name[12] == 't' && name[13] == 'R' && name[14] == 'e' && name[15] == 'c' && name[16] == 't' && name[17] == 'W' && name[18] == 'I' && name[19] == 'N' && name[20] == '\0') {
251 // glAddSwapHintRectWIN
252 retrace_glAddSwapHintRectWIN(call);
263 if (name[4] == 'l' && name[5] == 'l' && name[6] == 'o' && name[7] == 'c' && name[8] == 'a' && name[9] == 't' && name[10] == 'e' && name[11] == 'M' && name[12] == 'e' && name[13] == 'm' && name[14] == 'o' && name[15] == 'r' && name[16] == 'y' && name[17] == 'N' && name[18] == 'V' && name[19] == '\0') {
264 // wglAllocateMemoryNV
265 retrace_wglAllocateMemoryNV(call);
270 if (name[4] == 'i' && name[5] == 'n' && name[6] == 'd' && name[7] == 'T' && name[8] == 'e' && name[9] == 'x' && name[10] == 'I' && name[11] == 'm' && name[12] == 'a' && name[13] == 'g' && name[14] == 'e' && name[15] == 'A' && name[16] == 'R' && name[17] == 'B' && name[18] == '\0') {
271 // wglBindTexImageARB
272 retrace_wglBindTexImageARB(call);
311 // wglChoosePixelFormat
312 retrace_wglChoosePixelFormat(call);
316 if (name[21] == 'R' && name[22] == 'B' && name[23] == '\0') {
317 // wglChoosePixelFormatARB
318 retrace_wglChoosePixelFormatARB(call);
323 if (name[21] == 'X' && name[22] == 'T' && name[23] == '\0') {
324 // wglChoosePixelFormatEXT
325 retrace_wglChoosePixelFormatEXT(call);
362 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') {
364 retrace_wglCopyContext(call);
379 if (name[10] == 'u' && name[11] == 'f' && name[12] == 'f' && name[13] == 'e' && name[14] == 'r' && name[15] == 'R' && name[16] == 'e' && name[17] == 'g' && name[18] == 'i' && name[19] == 'o' && name[20] == 'n' && name[21] == 'A' && name[22] == 'R' && name[23] == 'B' && name[24] == '\0') {
380 // wglCreateBufferRegionARB
381 retrace_wglCreateBufferRegionARB(call);
401 retrace_wglCreateContext(call);
405 if (name[17] == 't' && name[18] == 't' && name[19] == 'r' && name[20] == 'i' && name[21] == 'b' && name[22] == 's' && name[23] == 'A' && name[24] == 'R' && name[25] == 'B' && name[26] == '\0') {
406 // wglCreateContextAttribsARB
407 retrace_wglCreateContextAttribsARB(call);
426 if (name[10] == 'a' && name[11] == 'y' && name[12] == 'e' && name[13] == 'r' && name[14] == 'C' && name[15] == 'o' && name[16] == 'n' && name[17] == 't' && name[18] == 'e' && name[19] == 'x' && name[20] == 't' && name[21] == '\0') {
427 // wglCreateLayerContext
428 retrace_wglCreateLayerContext(call);
433 if (name[10] == 'b' && name[11] == 'u' && name[12] == 'f' && name[13] == 'f' && name[14] == 'e' && name[15] == 'r' && name[16] == 'A' && name[17] == 'R' && name[18] == 'B' && name[19] == '\0') {
434 // wglCreatePbufferARB
435 retrace_wglCreatePbufferARB(call);
464 if (name[10] == 'u' && name[11] == 'f' && name[12] == 'f' && name[13] == 'e' && name[14] == 'r' && name[15] == 'R' && name[16] == 'e' && name[17] == 'g' && name[18] == 'i' && name[19] == 'o' && name[20] == 'n' && name[21] == 'A' && name[22] == 'R' && name[23] == 'B' && name[24] == '\0') {
465 // wglDeleteBufferRegionARB
466 retrace_wglDeleteBufferRegionARB(call);
471 if (name[10] == 'o' && name[11] == 'n' && name[12] == 't' && name[13] == 'e' && name[14] == 'x' && name[15] == 't' && name[16] == '\0') {
473 retrace_wglDeleteContext(call);
498 if (name[12] == 'a' && name[13] == 'y' && name[14] == 'e' && name[15] == 'r' && name[16] == 'P' && name[17] == 'l' && name[18] == 'a' && name[19] == 'n' && name[20] == 'e' && name[21] == '\0') {
499 // wglDescribeLayerPlane
500 retrace_wglDescribeLayerPlane(call);
505 if (name[12] == 'i' && name[13] == 'x' && name[14] == 'e' && name[15] == 'l' && name[16] == 'F' && name[17] == 'o' && name[18] == 'r' && name[19] == 'm' && name[20] == 'a' && name[21] == 't' && name[22] == '\0') {
506 // wglDescribePixelFormat
507 retrace_wglDescribePixelFormat(call);
522 if (name[7] == 'r' && name[8] == 'o' && name[9] == 'y' && name[10] == 'P' && name[11] == 'b' && name[12] == 'u' && name[13] == 'f' && name[14] == 'f' && name[15] == 'e' && name[16] == 'r' && name[17] == 'A' && name[18] == 'R' && name[19] == 'B' && name[20] == '\0') {
523 // wglDestroyPbufferARB
524 retrace_wglDestroyPbufferARB(call);
535 if (name[4] == 'r' && name[5] == 'e' && name[6] == 'e' && name[7] == 'M' && name[8] == 'e' && name[9] == 'm' && name[10] == 'o' && name[11] == 'r' && name[12] == 'y' && name[13] == 'N' && name[14] == 'V' && name[15] == '\0') {
537 retrace_wglFreeMemoryNV(call);
562 if (name[14] == 'o' && name[15] == 'n' && name[16] == 't' && name[17] == 'e' && name[18] == 'x' && name[19] == 't' && name[20] == '\0') {
563 // wglGetCurrentContext
568 if (name[14] == 'C' && name[15] == '\0') {
586 if (name[20] == 'R' && name[21] == 'B' && name[22] == '\0') {
587 // wglGetCurrentReadDCARB
592 if (name[20] == 'X' && name[21] == 'T' && name[22] == '\0') {
593 // wglGetCurrentReadDCEXT
624 if (name[7] == 'e' && name[8] == 'f' && name[9] == 'a' && name[10] == 'u' && name[11] == 'l' && name[12] == 't' && name[13] == 'P' && name[14] == 'r' && name[15] == 'o' && name[16] == 'c' && name[17] == 'A' && name[18] == 'd' && name[19] == 'd' && name[20] == 'r' && name[21] == 'e' && name[22] == 's' && name[23] == 's' && name[24] == '\0') {
625 // wglGetDefaultProcAddress
662 if (name[23] == 'R' && name[24] == 'B' && name[25] == '\0') {
663 // wglGetExtensionsStringARB
668 if (name[23] == 'X' && name[24] == 'T' && name[25] == '\0') {
669 // wglGetExtensionsStringEXT
706 if (name[7] == 'a' && name[8] == 'y' && name[9] == 'e' && name[10] == 'r' && name[11] == 'P' && name[12] == 'a' && name[13] == 'l' && name[14] == 'e' && name[15] == 't' && name[16] == 't' && name[17] == 'e' && name[18] == 'E' && name[19] == 'n' && name[20] == 't' && name[21] == 'r' && name[22] == 'i' && name[23] == 'e' && name[24] == 's' && name[25] == '\0') {
707 // wglGetLayerPaletteEntries
714 if (name[8] == 'u' && name[9] == 'f' && name[10] == 'f' && name[11] == 'e' && name[12] == 'r' && name[13] == 'D' && name[14] == 'C' && name[15] == 'A' && name[16] == 'R' && name[17] == 'B' && name[18] == '\0') {
715 // wglGetPbufferDCARB
716 retrace_wglGetPbufferDCARB(call);
761 if (name[26] == 'R' && name[27] == 'B' && name[28] == '\0') {
762 // wglGetPixelFormatAttribfvARB
767 if (name[26] == 'X' && name[27] == 'T' && name[28] == '\0') {
768 // wglGetPixelFormatAttribfvEXT
781 if (name[26] == 'R' && name[27] == 'B' && name[28] == '\0') {
782 // wglGetPixelFormatAttribivARB
787 if (name[26] == 'X' && name[27] == 'T' && name[28] == '\0') {
788 // wglGetPixelFormatAttribivEXT
829 if (name[8] == 'o' && name[9] == 'c' && name[10] == 'A' && name[11] == 'd' && name[12] == 'd' && name[13] == 'r' && name[14] == 'e' && name[15] == 's' && name[16] == 's' && name[17] == '\0') {
831 retrace_wglGetProcAddress(call);
838 if (name[7] == 'w' && name[8] == 'a' && name[9] == 'p' && name[10] == 'I' && name[11] == 'n' && name[12] == 't' && name[13] == 'e' && name[14] == 'r' && name[15] == 'v' && name[16] == 'a' && name[17] == 'l' && name[18] == 'E' && name[19] == 'X' && name[20] == 'T' && name[21] == '\0') {
839 // wglGetSwapIntervalEXT
886 if (name[22] == 'R' && name[23] == 'B' && name[24] == '\0') {
887 // wglMakeContextCurrentARB
888 retrace_wglMakeContextCurrentARB(call);
893 if (name[22] == 'X' && name[23] == 'T' && name[24] == '\0') {
894 // wglMakeContextCurrentEXT
895 retrace_wglMakeContextCurrentEXT(call);
926 if (name[9] == 'r' && name[10] == 'r' && name[11] == 'e' && name[12] == 'n' && name[13] == 't' && name[14] == '\0') {
928 retrace_wglMakeCurrent(call);
943 if (name[4] == 'u' && name[5] == 'e' && name[6] == 'r' && name[7] == 'y' && name[8] == 'P' && name[9] == 'b' && name[10] == 'u' && name[11] == 'f' && name[12] == 'f' && name[13] == 'e' && name[14] == 'r' && name[15] == 'A' && name[16] == 'R' && name[17] == 'B' && name[18] == '\0') {
944 // wglQueryPbufferARB
945 retrace_wglQueryPbufferARB(call);
954 if (name[6] == 'l' && name[7] == 'i' && name[8] == 'z' && name[9] == 'e' && name[10] == 'L' && name[11] == 'a' && name[12] == 'y' && name[13] == 'e' && name[14] == 'r' && name[15] == 'P' && name[16] == 'a' && name[17] == 'l' && name[18] == 'e' && name[19] == 't' && name[20] == 't' && name[21] == 'e' && name[22] == '\0') {
955 // wglRealizeLayerPalette
956 retrace_wglRealizeLayerPalette(call);
971 if (name[11] == 'b' && name[12] == 'u' && name[13] == 'f' && name[14] == 'f' && name[15] == 'e' && name[16] == 'r' && name[17] == 'D' && name[18] == 'C' && name[19] == 'A' && name[20] == 'R' && name[21] == 'B' && name[22] == '\0') {
972 // wglReleasePbufferDCARB
973 retrace_wglReleasePbufferDCARB(call);
978 if (name[11] == 'e' && name[12] == 'x' && name[13] == 'I' && name[14] == 'm' && name[15] == 'a' && name[16] == 'g' && name[17] == 'e' && name[18] == 'A' && name[19] == 'R' && name[20] == 'B' && name[21] == '\0') {
979 // wglReleaseTexImageARB
980 retrace_wglReleaseTexImageARB(call);
995 if (name[6] == 't' && name[7] == 'o' && name[8] == 'r' && name[9] == 'e' && name[10] == 'B' && name[11] == 'u' && name[12] == 'f' && name[13] == 'f' && name[14] == 'e' && name[15] == 'r' && name[16] == 'R' && name[17] == 'e' && name[18] == 'g' && name[19] == 'i' && name[20] == 'o' && name[21] == 'n' && name[22] == 'A' && name[23] == 'R' && name[24] == 'B' && name[25] == '\0') {
996 // wglRestoreBufferRegionARB
997 retrace_wglRestoreBufferRegionARB(call);
1008 if (name[5] == 'v' && name[6] == 'e' && name[7] == 'B' && name[8] == 'u' && name[9] == 'f' && name[10] == 'f' && name[11] == 'e' && name[12] == 'r' && name[13] == 'R' && name[14] == 'e' && name[15] == 'g' && name[16] == 'i' && name[17] == 'o' && name[18] == 'n' && name[19] == 'A' && name[20] == 'R' && name[21] == 'B' && name[22] == '\0') {
1009 // wglSaveBufferRegionARB
1010 retrace_wglSaveBufferRegionARB(call);
1019 if (name[7] == 'a' && name[8] == 'y' && name[9] == 'e' && name[10] == 'r' && name[11] == 'P' && name[12] == 'a' && name[13] == 'l' && name[14] == 'e' && name[15] == 't' && name[16] == 't' && name[17] == 'e' && name[18] == 'E' && name[19] == 'n' && name[20] == 't' && name[21] == 'r' && name[22] == 'i' && name[23] == 'e' && name[24] == 's' && name[25] == '\0') {
1020 // wglSetLayerPaletteEntries
1021 retrace_wglSetLayerPaletteEntries(call);
1028 if (name[8] == 'u' && name[9] == 'f' && name[10] == 'f' && name[11] == 'e' && name[12] == 'r' && name[13] == 'A' && name[14] == 't' && name[15] == 't' && name[16] == 'r' && name[17] == 'i' && name[18] == 'b' && name[19] == 'A' && name[20] == 'R' && name[21] == 'B' && name[22] == '\0') {
1029 // wglSetPbufferAttribARB
1030 retrace_wglSetPbufferAttribARB(call);
1035 if (name[8] == 'x' && name[9] == 'e' && name[10] == 'l' && name[11] == 'F' && name[12] == 'o' && name[13] == 'r' && name[14] == 'm' && name[15] == 'a' && name[16] == 't' && name[17] == '\0') {
1036 // wglSetPixelFormat
1037 retrace_wglSetPixelFormat(call);
1048 if (name[5] == 'a' && name[6] == 'r' && name[7] == 'e' && name[8] == 'L' && name[9] == 'i' && name[10] == 's' && name[11] == 't' && name[12] == 's' && name[13] == '\0') {
1050 retrace_wglShareLists(call);
1061 if (name[8] == 'u' && name[9] == 'f' && name[10] == 'f' && name[11] == 'e' && name[12] == 'r' && name[13] == 's' && name[14] == '\0') {
1063 retrace_wglSwapBuffers(call);
1068 if (name[8] == 'n' && name[9] == 't' && name[10] == 'e' && name[11] == 'r' && name[12] == 'v' && name[13] == 'a' && name[14] == 'l' && name[15] == 'E' && name[16] == 'X' && name[17] == 'T' && name[18] == '\0') {
1069 // wglSwapIntervalEXT
1070 retrace_wglSwapIntervalEXT(call);
1075 if (name[8] == 'a' && name[9] == 'y' && name[10] == 'e' && name[11] == 'r' && name[12] == 'B' && name[13] == 'u' && name[14] == 'f' && name[15] == 'f' && name[16] == 'e' && name[17] == 'r' && name[18] == 's' && name[19] == '\0') {
1076 // wglSwapLayerBuffers
1077 retrace_wglSwapLayerBuffers(call);
1082 if (name[8] == 'u' && name[9] == 'l' && name[10] == 't' && name[11] == 'i' && name[12] == 'p' && name[13] == 'l' && name[14] == 'e' && name[15] == 'B' && name[16] == 'u' && name[17] == 'f' && name[18] == 'f' && name[19] == 'e' && name[20] == 'r' && name[21] == 's' && name[22] == '\0') {
1083 // wglSwapMultipleBuffers
1084 retrace_wglSwapMultipleBuffers(call);
1125 if (name[18] == '\0') {
1126 // wglUseFontBitmapsA
1127 retrace_wglUseFontBitmapsA(call);
1132 if (name[18] == '\0') {
1133 // wglUseFontBitmapsW
1134 retrace_wglUseFontBitmapsW(call);
1169 if (name[19] == '\0') {
1170 // wglUseFontOutlinesA
1171 retrace_wglUseFontOutlinesA(call);
1176 if (name[19] == '\0') {
1177 // wglUseFontOutlinesW
1178 retrace_wglUseFontOutlinesW(call);
1219 retrace::retrace_unknown(call);