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",
60 "GL_ARB_debug_output",
61 "GL_AMD_debug_output",
66 extraExtension_stringsES[] = {
67 "GL_EXT_debug_marker",
70 // Description of additional extensions we want to advertise
77 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
79 const struct ExtensionsDesc
80 extraExtensionsFull = {
81 ARRAY_SIZE(extraExtension_stringsFull),
82 extraExtension_stringsFull
85 const struct ExtensionsDesc
87 ARRAY_SIZE(extraExtension_stringsES),
88 extraExtension_stringsES
92 const struct ExtensionsDesc *
93 getExtraExtensions(void)
95 Context *ctx = getContext();
97 switch (ctx->profile) {
99 return &extraExtensionsFull;
102 return &extraExtensionsES;
105 return &extraExtensionsFull;
111 * Translate the GL extensions string, adding new extensions.
114 overrideExtensionsString(const char *extensions)
116 const ExtensionsDesc *desc = getExtraExtensions();
119 ExtensionsMap::const_iterator it = extensionsMap.find(extensions);
120 if (it != extensionsMap.end()) {
124 size_t extensionsLen = strlen(extensions);
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;
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
136 size_t newExtensionsLen = extensionsLen + 1 + extraExtensionsLen + 1;
137 char *newExtensions = (char *)malloc(newExtensionsLen);
138 if (!newExtensions) {
143 memcpy(newExtensions, extensions, extensionsLen);
145 // Add space separator if necessary
146 if (newExtensions[extensionsLen - 1] != ' ') {
147 newExtensions[extensionsLen++] = ' ';
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++] = ' ';
158 newExtensions[extensionsLen++] = '\0';
159 assert(extensionsLen <= newExtensionsLen);
161 extensionsMap[extensions] = newExtensions;
163 return newExtensions;
168 _glGetString_override(GLenum name)
170 const GLubyte *result = _glGetString(name);
175 result = (const GLubyte *)overrideExtensionsString((const char *)result);
187 _glGetIntegerv_override(GLenum pname, GLint *params)
189 _glGetIntegerv(pname, params);
193 case GL_NUM_EXTENSIONS:
195 const ExtensionsDesc *desc = getExtraExtensions();
196 *params += desc->numStrings;
207 _glGetStringi_override(GLenum name, GLuint index)
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];
224 return _glGetStringi(name, index);
228 } /* namespace gltrace */