]> git.cworth.org Git - apitrace/blob - wrappers/glcaps.cpp
eglretrace: Fix window size hints problem.
[apitrace] / wrappers / glcaps.cpp
1 /**************************************************************************
2  *
3  * Copyright 2011 Jose Fonseca
4  * All Rights Reserved.
5  *
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:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
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
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26
27 /*
28  * Manipulation of GL extensions.
29  *
30  * So far we insert GREMEDY extensions, but in the future we could also clamp
31  * the GL extensions to core GL versions here.
32  */
33
34
35 #include <assert.h>
36 #include <string.h>
37 #include <stdlib.h>
38
39 #include <string>
40 #include <map>
41
42 #include "glproc.hpp"
43 #include "gltrace.hpp"
44
45
46 namespace gltrace {
47
48
49 typedef std::map<std::string, const char *> ExtensionsMap;
50
51 // Cache of the translated extensions strings
52 static ExtensionsMap extensionsMap;
53
54
55 // Additional extensions to be advertised
56 static const char *
57 extraExtension_stringsFull[] = {
58     "GL_GREMEDY_string_marker",
59     "GL_GREMEDY_frame_terminator",
60     "GL_ARB_debug_output",
61     "GL_AMD_debug_output",
62     "GL_KHR_debug",
63 };
64
65 static const char *
66 extraExtension_stringsES[] = {
67     "GL_EXT_debug_marker",
68 };
69
70 // Description of additional extensions we want to advertise
71 struct ExtensionsDesc
72 {
73     unsigned numStrings;
74     const char **strings;
75 };
76
77 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
78
79 const struct ExtensionsDesc
80 extraExtensionsFull = {
81     ARRAY_SIZE(extraExtension_stringsFull),
82     extraExtension_stringsFull
83 };
84
85 const struct ExtensionsDesc
86 extraExtensionsES = {
87     ARRAY_SIZE(extraExtension_stringsES),
88     extraExtension_stringsES
89 };
90
91
92 const struct ExtensionsDesc *
93 getExtraExtensions(void)
94 {
95     Context *ctx = getContext();
96
97     switch (ctx->profile) {
98     case PROFILE_COMPAT:
99         return &extraExtensionsFull;
100     case PROFILE_ES1:
101     case PROFILE_ES2:
102         return &extraExtensionsES;
103     default:
104         assert(0);
105         return &extraExtensionsFull;
106     }
107 }
108
109
110 /**
111  * Translate the GL extensions string, adding new extensions.
112  */
113 static const char *
114 overrideExtensionsString(const char *extensions)
115 {
116     const ExtensionsDesc *desc = getExtraExtensions();
117     size_t i;
118
119     ExtensionsMap::const_iterator it = extensionsMap.find(extensions);
120     if (it != extensionsMap.end()) {
121         return it->second;
122     }
123
124     size_t extensionsLen = strlen(extensions);
125
126     size_t extraExtensionsLen = 0;
127     for (i = 0; i < desc->numStrings; ++i) {
128         const char * extraExtension = desc->strings[i];
129         size_t extraExtensionLen = strlen(extraExtension);
130         extraExtensionsLen += extraExtensionLen + 1;
131     }
132
133     // We use malloc memory instead of a std::string because we need to ensure
134     // that extensions strings will not move in memory as the extensionsMap is
135     // updated.
136     size_t newExtensionsLen = extensionsLen + 1 + extraExtensionsLen + 1;
137     char *newExtensions = (char *)malloc(newExtensionsLen);
138     if (!newExtensions) {
139         return extensions;
140     }
141
142     if (extensionsLen) {
143         memcpy(newExtensions, extensions, extensionsLen);
144
145         // Add space separator if necessary
146         if (newExtensions[extensionsLen - 1] != ' ') {
147             newExtensions[extensionsLen++] = ' ';
148         }
149     }
150
151     for (i = 0; i < desc->numStrings; ++i) {
152         const char * extraExtension = desc->strings[i];
153         size_t extraExtensionLen = strlen(extraExtension);
154         memcpy(newExtensions + extensionsLen, extraExtension, extraExtensionLen);
155         extensionsLen += extraExtensionLen;
156         newExtensions[extensionsLen++] = ' ';
157     }
158     newExtensions[extensionsLen++] = '\0';
159     assert(extensionsLen <= newExtensionsLen);
160
161     extensionsMap[extensions] = newExtensions;
162
163     return newExtensions;
164 }
165
166
167 const GLubyte *
168 _glGetString_override(GLenum name)
169 {
170     const GLubyte *result = _glGetString(name);
171
172     if (result) {
173         switch (name) {
174         case GL_EXTENSIONS:
175             result = (const GLubyte *)overrideExtensionsString((const char *)result);
176             break;
177         default:
178             break;
179         }
180     }
181
182     return result;
183 }
184
185
186 void
187 _glGetIntegerv_override(GLenum pname, GLint *params)
188 {
189     _glGetIntegerv(pname, params);
190
191     if (params) {
192         switch (pname) {
193         case GL_NUM_EXTENSIONS:
194             {
195                 const ExtensionsDesc *desc = getExtraExtensions();
196                 *params += desc->numStrings;
197             }
198             break;
199         default:
200             break;
201         }
202     }
203 }
204
205
206 const GLubyte *
207 _glGetStringi_override(GLenum name, GLuint index)
208 {
209     switch (name) {
210     case GL_EXTENSIONS:
211         {
212             const ExtensionsDesc *desc = getExtraExtensions();
213             GLint numExtensions = 0;
214             _glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
215             if ((GLuint)numExtensions <= index && index < (GLuint)numExtensions + desc->numStrings) {
216                 return (const GLubyte *)desc->strings[index - (GLuint)numExtensions];
217             }
218         }
219         break;
220     default:
221         break;
222     }
223
224     return _glGetStringi(name, index);
225 }
226
227
228 } /* namespace gltrace */
229