Implement glGetStringi, for querying specific extension strings.
TRAC #22865
Signed-off-by: Geoff Lang
Signed-off-by: Shannon Woods
Author: Jamie Madill
git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2296 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 98a4cdf..2deec40 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -177,7 +177,7 @@
mState.unpackAlignment = 4;
mState.packReverseRowOrder = false;
- mExtensionString = NULL;
+ mCombinedExtensionsString = NULL;
mRendererString = NULL;
mInvalidEnum = false;
@@ -2808,124 +2808,139 @@
// Vendor extensions
void Context::initExtensionString()
{
- std::string extensionString = "";
-
- // OES extensions
- if (supports32bitIndices())
+ // Do not report extension in GLES 3 contexts for now
+ if (mClientVersion == 2)
{
- extensionString += "GL_OES_element_index_uint ";
+ // OES extensions
+ if (supports32bitIndices())
+ {
+ mExtensionStringList.push_back("GL_OES_element_index_uint");
+ }
+
+ mExtensionStringList.push_back("GL_OES_packed_depth_stencil");
+ mExtensionStringList.push_back("GL_OES_get_program_binary");
+ mExtensionStringList.push_back("GL_OES_rgb8_rgba8");
+ if (mRenderer->getDerivativeInstructionSupport())
+ {
+ mExtensionStringList.push_back("GL_OES_standard_derivatives");
+ }
+
+ if (supportsFloat16Textures())
+ {
+ mExtensionStringList.push_back("GL_OES_texture_half_float");
+ }
+ if (supportsFloat16LinearFilter())
+ {
+ mExtensionStringList.push_back("GL_OES_texture_half_float_linear");
+ }
+ if (supportsFloat32Textures())
+ {
+ mExtensionStringList.push_back("GL_OES_texture_float");
+ }
+ if (supportsFloat32LinearFilter())
+ {
+ mExtensionStringList.push_back("GL_OES_texture_float_linear");
+ }
+
+ if (supportsNonPower2Texture())
+ {
+ mExtensionStringList.push_back("GL_OES_texture_npot");
+ }
+
+ // Multi-vendor (EXT) extensions
+ if (supportsOcclusionQueries())
+ {
+ mExtensionStringList.push_back("GL_EXT_occlusion_query_boolean");
+ }
+
+ mExtensionStringList.push_back("GL_EXT_read_format_bgra");
+ mExtensionStringList.push_back("GL_EXT_robustness");
+
+ if (supportsDXT1Textures())
+ {
+ mExtensionStringList.push_back("GL_EXT_texture_compression_dxt1");
+ }
+
+ if (supportsTextureFilterAnisotropy())
+ {
+ mExtensionStringList.push_back("GL_EXT_texture_filter_anisotropic");
+ }
+
+ if (supportsBGRATextures())
+ {
+ mExtensionStringList.push_back("GL_EXT_texture_format_BGRA8888");
+ }
+
+ if (mRenderer->getMaxRenderTargets() > 1)
+ {
+ mExtensionStringList.push_back("GL_EXT_draw_buffers");
+ }
+
+ mExtensionStringList.push_back("GL_EXT_texture_storage");
+
+ // ANGLE-specific extensions
+ if (supportsDepthTextures())
+ {
+ mExtensionStringList.push_back("GL_ANGLE_depth_texture");
+ }
+
+ mExtensionStringList.push_back("GL_ANGLE_framebuffer_blit");
+ if (getMaxSupportedSamples() != 0)
+ {
+ mExtensionStringList.push_back("GL_ANGLE_framebuffer_multisample");
+ }
+
+ if (supportsInstancing())
+ {
+ mExtensionStringList.push_back("GL_ANGLE_instanced_arrays");
+ }
+
+ mExtensionStringList.push_back("GL_ANGLE_pack_reverse_row_order");
+
+ if (supportsDXT3Textures())
+ {
+ mExtensionStringList.push_back("GL_ANGLE_texture_compression_dxt3");
+ }
+ if (supportsDXT5Textures())
+ {
+ mExtensionStringList.push_back("GL_ANGLE_texture_compression_dxt5");
+ }
+
+ mExtensionStringList.push_back("GL_ANGLE_texture_usage");
+ mExtensionStringList.push_back("GL_ANGLE_translated_shader_source");
+
+ // Other vendor-specific extensions
+ if (supportsEventQueries())
+ {
+ mExtensionStringList.push_back("GL_NV_fence");
+ }
}
- extensionString += "GL_OES_packed_depth_stencil ";
- extensionString += "GL_OES_get_program_binary ";
- extensionString += "GL_OES_rgb8_rgba8 ";
- if (mRenderer->getDerivativeInstructionSupport())
+ // Join the extension strings to one long string for use with GetString
+ std::stringstream strstr;
+ for (unsigned int extensionIndex = 0; extensionIndex < mExtensionStringList.size(); extensionIndex++)
{
- extensionString += "GL_OES_standard_derivatives ";
+ strstr << mExtensionStringList[extensionIndex];
+ strstr << " ";
}
- if (supportsFloat16Textures())
- {
- extensionString += "GL_OES_texture_half_float ";
- }
- if (supportsFloat16LinearFilter())
- {
- extensionString += "GL_OES_texture_half_float_linear ";
- }
- if (supportsFloat32Textures())
- {
- extensionString += "GL_OES_texture_float ";
- }
- if (supportsFloat32LinearFilter())
- {
- extensionString += "GL_OES_texture_float_linear ";
- }
-
- if (supportsNonPower2Texture())
- {
- extensionString += "GL_OES_texture_npot ";
- }
-
- // Multi-vendor (EXT) extensions
- if (supportsOcclusionQueries())
- {
- extensionString += "GL_EXT_occlusion_query_boolean ";
- }
-
- extensionString += "GL_EXT_read_format_bgra ";
- extensionString += "GL_EXT_robustness ";
-
- if (supportsDXT1Textures())
- {
- extensionString += "GL_EXT_texture_compression_dxt1 ";
- }
-
- if (supportsTextureFilterAnisotropy())
- {
- extensionString += "GL_EXT_texture_filter_anisotropic ";
- }
-
- if (supportsBGRATextures())
- {
- extensionString += "GL_EXT_texture_format_BGRA8888 ";
- }
-
- if (mRenderer->getMaxRenderTargets() > 1)
- {
- extensionString += "GL_EXT_draw_buffers ";
- }
-
- extensionString += "GL_EXT_texture_storage ";
-
- // ANGLE-specific extensions
- if (supportsDepthTextures())
- {
- extensionString += "GL_ANGLE_depth_texture ";
- }
-
- extensionString += "GL_ANGLE_framebuffer_blit ";
- if (getMaxSupportedSamples() != 0)
- {
- extensionString += "GL_ANGLE_framebuffer_multisample ";
- }
-
- if (supportsInstancing())
- {
- extensionString += "GL_ANGLE_instanced_arrays ";
- }
-
- extensionString += "GL_ANGLE_pack_reverse_row_order ";
-
- if (supportsDXT3Textures())
- {
- extensionString += "GL_ANGLE_texture_compression_dxt3 ";
- }
- if (supportsDXT5Textures())
- {
- extensionString += "GL_ANGLE_texture_compression_dxt5 ";
- }
-
- extensionString += "GL_ANGLE_texture_usage ";
- extensionString += "GL_ANGLE_translated_shader_source ";
-
- // Other vendor-specific extensions
- if (supportsEventQueries())
- {
- extensionString += "GL_NV_fence ";
- }
-
- std::string::size_type end = extensionString.find_last_not_of(' ');
- if (end != std::string::npos)
- {
- extensionString.resize(end+1);
- }
-
- mExtensionString = makeStaticString(extensionString);
+ mCombinedExtensionsString = makeStaticString(strstr.str());
}
-const char *Context::getExtensionString() const
+const char *Context::getCombinedExtensionsString() const
{
- return mExtensionString;
+ return mCombinedExtensionsString;
+}
+
+const char *Context::getExtensionString(const GLuint index) const
+{
+ ASSERT(index < mExtensionStringList.size());
+ return mExtensionStringList[index].c_str();
+}
+
+unsigned int Context::getNumExtensions() const
+{
+ return mExtensionStringList.size();
}
void Context::initRendererString()
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index 9cbe219..4ee4920 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -431,7 +431,9 @@
GLsizei getMaxSupportedSamples() const;
unsigned int getMaxTransformFeedbackBufferBindings() const;
GLintptr getUniformBufferOffsetAlignment() const;
- const char *getExtensionString() const;
+ const char *getCombinedExtensionsString() const;
+ const char *getExtensionString(const GLuint index) const;
+ unsigned int getNumExtensions() const;
const char *getRendererString() const;
bool supportsEventQueries() const;
bool supportsOcclusionQueries() const;
@@ -513,7 +515,8 @@
QueryMap mQueryMap;
HandleAllocator mQueryHandleAllocator;
- const char *mExtensionString;
+ std::vector<std::string> mExtensionStringList;
+ const char *mCombinedExtensionsString;
const char *mRendererString;
BindingPointer<Texture> mIncompleteTextures[TEXTURE_TYPE_COUNT];
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 955d48c..d3b82fa 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -4397,7 +4397,7 @@
case GL_SHADING_LANGUAGE_VERSION:
return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " VERSION_STRING ")";
case GL_EXTENSIONS:
- return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
+ return (GLubyte*)((context != NULL) ? context->getCombinedExtensionsString() : "");
default:
return gl::error(GL_INVALID_ENUM, (GLubyte*)NULL);
}
@@ -9395,9 +9395,19 @@
{
return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLubyte*>(NULL));
}
- }
- UNIMPLEMENTED();
+ if (name != GL_EXTENSIONS)
+ {
+ return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLubyte*>(NULL));
+ }
+
+ if (index >= context->getNumExtensions())
+ {
+ return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLubyte*>(NULL));
+ }
+
+ return reinterpret_cast<const GLubyte*>(context->getExtensionString(index));
+ }
}
catch(std::bad_alloc&)
{