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 * Manipulation of GL extensions.
30 * So far we insert GREMEDY extensions, but in the future we could also clamp
31 * the GL extensions to core GL versions here.
43 #include "gltrace.hpp"
49 typedef std::map<std::string, const char *> ExtensionsMap;
51 // Cache of the translated extensions strings
52 static ExtensionsMap extensionsMap;
55 // Additional extensions to be advertised
57 extraExtension_stringsFull[] = {
58 "GL_GREMEDY_string_marker",
59 "GL_GREMEDY_frame_terminator",
63 extraExtension_stringsES[] = {
64 "GL_EXT_debug_marker",
67 // Description of additional extensions we want to advertise
74 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
76 const struct ExtensionsDesc
77 extraExtensionsFull = {
78 ARRAY_SIZE(extraExtension_stringsFull),
79 extraExtension_stringsFull
82 const struct ExtensionsDesc
84 ARRAY_SIZE(extraExtension_stringsES),
85 extraExtension_stringsES
89 const struct ExtensionsDesc *
90 getExtraExtensions(void)
92 Context *ctx = getContext();
94 switch (ctx->profile) {
96 return &extraExtensionsFull;
99 return &extraExtensionsES;
102 return &extraExtensionsFull;
108 * Translate the GL extensions string, adding new extensions.
111 overrideExtensionsString(const char *extensions)
113 const ExtensionsDesc *desc = getExtraExtensions();
116 ExtensionsMap::const_iterator it = extensionsMap.find(extensions);
117 if (it != extensionsMap.end()) {
121 size_t extensionsLen = strlen(extensions);
123 size_t extraExtensionsLen = 0;
124 for (i = 0; i < desc->numStrings; ++i) {
125 const char * extraExtension = desc->strings[i];
126 size_t extraExtensionLen = strlen(extraExtension);
127 extraExtensionsLen += extraExtensionLen + 1;
130 // We use malloc memory instead of a std::string because we need to ensure
131 // that extensions strings will not move in memory as the extensionsMap is
133 size_t newExtensionsLen = extensionsLen + 1 + extraExtensionsLen + 1;
134 char *newExtensions = (char *)malloc(newExtensionsLen);
135 if (!newExtensions) {
140 memcpy(newExtensions, extensions, extensionsLen);
142 // Add space separator if necessary
143 if (newExtensions[extensionsLen - 1] != ' ') {
144 newExtensions[extensionsLen++] = ' ';
148 for (i = 0; i < desc->numStrings; ++i) {
149 const char * extraExtension = desc->strings[i];
150 size_t extraExtensionLen = strlen(extraExtension);
151 memcpy(newExtensions + extensionsLen, extraExtension, extraExtensionLen);
152 extensionsLen += extraExtensionLen;
153 newExtensions[extensionsLen++] = ' ';
155 newExtensions[extensionsLen++] = '\0';
156 assert(extensionsLen <= newExtensionsLen);
158 extensionsMap[extensions] = newExtensions;
160 return newExtensions;
165 _glGetString_override(GLenum name)
167 const GLubyte *result = _glGetString(name);
172 result = (const GLubyte *)overrideExtensionsString((const char *)result);
184 _glGetIntegerv_override(GLenum pname, GLint *params)
186 _glGetIntegerv(pname, params);
190 case GL_NUM_EXTENSIONS:
192 const ExtensionsDesc *desc = getExtraExtensions();
193 *params += desc->numStrings;
204 _glGetStringi_override(GLenum name, GLuint index)
209 const ExtensionsDesc *desc = getExtraExtensions();
210 GLint numExtensions = 0;
211 _glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
212 if ((GLuint)numExtensions <= index && index < (GLuint)numExtensions + desc->numStrings) {
213 return (const GLubyte *)desc->strings[index - (GLuint)numExtensions];
221 return _glGetStringi(name, index);
225 } /* namespace gltrace */