summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/service/feature_info.cc
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-30 21:29:11 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-30 21:29:11 +0000
commit915a59a10d1a1bb008821fd4e4f2019a4c676142 (patch)
treebec2e4c963ea3f6da1e839799a144de14086945e /gpu/command_buffer/service/feature_info.cc
parentd15e56c68d773261b98d20b61aeeb03cfa0fb24e (diff)
downloadchromium_src-915a59a10d1a1bb008821fd4e4f2019a4c676142.zip
chromium_src-915a59a10d1a1bb008821fd4e4f2019a4c676142.tar.gz
chromium_src-915a59a10d1a1bb008821fd4e4f2019a4c676142.tar.bz2
A step in making it possible for WebGL to request no features
and the add them in as extensions are enabled. The idea is when WebGL inits it's context it will pass "" to FeatureInfo::Initialize. After that it can pass various GL extension strings to FeatureInfo::AddFeatures to turn on more features. It can then call glGetString(GL_EXTENSIONS) to see if the feature was turned on. Questions: I started this CL trying to make it possible so each context could have it's own FeatureInfo. I decided against that. So that brings up the question, should I get rid of FeatureInfo and just put this stuff back on ContextGroup or leave it as is? If I leave it as is, should I move all the max_XXX stuff on ContextGroup to FeatureInfo? TEST=unit tests BUG=none Review URL: http://codereview.chromium.org/3413038 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61114 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer/service/feature_info.cc')
-rw-r--r--gpu/command_buffer/service/feature_info.cc266
1 files changed, 266 insertions, 0 deletions
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
new file mode 100644
index 0000000..883dcd0
--- /dev/null
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -0,0 +1,266 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <set>
+#include <string>
+#include "app/gfx/gl/gl_implementation.h"
+#include "gpu/command_buffer/service/feature_info.h"
+#include "gpu/command_buffer/service/gl_utils.h"
+#include "gpu/GLES2/gles2_command_buffer.h"
+
+namespace gpu {
+namespace gles2 {
+
+FeatureInfo::FeatureInfo() {
+}
+
+// Helps query for extensions.
+class ExtensionHelper {
+ public:
+ ExtensionHelper(const char* extensions, const char* allowed_features) {
+ std::set<std::string> sets[2];
+
+ for (int ii = 0; ii < 2; ++ii) {
+ const char* s = (ii == 0 ? extensions : allowed_features);
+ std::string str(s ? s : "");
+ std::string::size_type lastPos = 0;
+ while (true) {
+ std::string::size_type pos = str.find_first_of(" ", lastPos);
+ if (pos != std::string::npos) {
+ sets[ii].insert(str.substr(lastPos, pos - lastPos));
+ lastPos = pos + 1;
+ } else {
+ sets[ii].insert(str.substr(lastPos));
+ break;
+ }
+ }
+ }
+
+ if (allowed_features) {
+ std::set_intersection(
+ sets[0].begin(), sets[0].end(), sets[1].begin(), sets[1].end(),
+ std::inserter(extensions_, extensions_.begin()));
+ } else {
+ extensions_ = sets[0];
+ }
+ }
+
+ // Returns true if extension exists.
+ bool HasExtension(const char* extension) {
+ return extensions_.find(extension) != extensions_.end();
+ }
+
+ private:
+ std::set<std::string> extensions_;
+};
+
+bool FeatureInfo::Initialize(const char* allowed_features) {
+ AddFeatures(allowed_features);
+ return true;
+}
+
+void FeatureInfo::AddFeatures(const char* desired_features) {
+ // Figure out what extensions to turn on.
+ std::string gl_extensions(
+ reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
+
+ ExtensionHelper helper(
+ (gl_extensions +
+ (gl_extensions.empty() ? "" : " ") + "GL_CHROMIUM_map_sub").c_str(),
+ desired_features);
+
+ bool npot_ok = false;
+
+ if (helper.HasExtension("GL_CHROMIUM_map_sub")) {
+ AddExtensionString("GL_CHROMIUM_map_sub");
+ }
+
+ // Check if we should allow GL_EXT_texture_compression_dxt1 and
+ // GL_EXT_texture_compression_s3tc.
+ bool enable_dxt1 = false;
+ bool enable_s3tc = false;
+
+ if (helper.HasExtension("GL_EXT_texture_compression_dxt1")) {
+ enable_dxt1 = true;
+ }
+ if (helper.HasExtension("GL_EXT_texture_compression_s3tc")) {
+ enable_dxt1 = true;
+ enable_s3tc = true;
+ }
+
+ if (enable_dxt1) {
+ AddExtensionString("GL_EXT_texture_compression_dxt1");
+ validators_.compressed_texture_format.AddValue(
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
+ validators_.compressed_texture_format.AddValue(
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
+ }
+
+ if (enable_s3tc) {
+ AddExtensionString("GL_EXT_texture_compression_s3tc");
+ validators_.compressed_texture_format.AddValue(
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
+ validators_.compressed_texture_format.AddValue(
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
+ }
+
+ // Check if we should enable GL_EXT_texture_filter_anisotropic.
+ if (helper.HasExtension("GL_EXT_texture_filter_anisotropic")) {
+ AddExtensionString("GL_EXT_texture_filter_anisotropic");
+ validators_.texture_parameter.AddValue(
+ GL_TEXTURE_MAX_ANISOTROPY_EXT);
+ validators_.g_l_state.AddValue(
+ GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT);
+ }
+
+ // Check if we should support GL_OES_packed_depth_stencil and/or
+ // GL_GOOGLE_depth_texture.
+ // NOTE: GL_OES_depth_texture requires support for depth
+ // cubemaps. GL_ARB_depth_texture requires other features that
+ // GL_OES_packed_depth_stencil does not provide. Therefore we made up
+ // GL_GOOGLE_depth_texture.
+ bool enable_depth_texture = false;
+ if (helper.HasExtension("GL_ARB_depth_texture") ||
+ helper.HasExtension("GL_OES_depth_texture")) {
+ enable_depth_texture = true;
+ AddExtensionString("GL_GOOGLE_depth_texture");
+ validators_.texture_internal_format.AddValue(GL_DEPTH_COMPONENT);
+ validators_.texture_format.AddValue(GL_DEPTH_COMPONENT);
+ validators_.pixel_type.AddValue(GL_UNSIGNED_SHORT);
+ validators_.pixel_type.AddValue(GL_UNSIGNED_INT);
+ }
+ // TODO(gman): Add depth types fo ElementsPerGroup and BytesPerElement
+
+ if (helper.HasExtension("GL_EXT_packed_depth_stencil") ||
+ helper.HasExtension("GL_OES_packed_depth_stencil")) {
+ AddExtensionString("GL_OES_packed_depth_stencil");
+ if (enable_depth_texture) {
+ validators_.texture_internal_format.AddValue(GL_DEPTH_STENCIL);
+ validators_.texture_format.AddValue(GL_DEPTH_STENCIL);
+ validators_.pixel_type.AddValue(GL_UNSIGNED_INT_24_8);
+ }
+ validators_.render_buffer_format.AddValue(GL_DEPTH24_STENCIL8);
+ }
+
+ bool enable_texture_format_bgra8888 = false;
+ bool enable_read_format_bgra = false;
+ // Check if we should allow GL_EXT_texture_format_BGRA8888
+ if (helper.HasExtension("GL_EXT_texture_format_BGRA8888") ||
+ helper.HasExtension("GL_APPLE_texture_format_BGRA8888")) {
+ enable_texture_format_bgra8888 = true;
+ }
+
+ if (helper.HasExtension("GL_EXT_bgra")) {
+ enable_texture_format_bgra8888 = true;
+ enable_read_format_bgra = true;
+ }
+
+ if (helper.HasExtension("GL_EXT_read_format_bgra")) {
+ enable_read_format_bgra = true;
+ }
+
+ if (enable_texture_format_bgra8888) {
+ AddExtensionString("GL_EXT_texture_format_BGRA8888");
+ validators_.texture_internal_format.AddValue(GL_BGRA_EXT);
+ validators_.texture_format.AddValue(GL_BGRA_EXT);
+ }
+
+ if (enable_read_format_bgra) {
+ AddExtensionString("GL_EXT_read_format_bgra");
+ validators_.read_pixel_format.AddValue(GL_BGRA_EXT);
+ }
+
+ // Check if we should allow GL_OES_texture_npot
+ if (helper.HasExtension("GL_ARB_texture_non_power_of_two") ||
+ helper.HasExtension("GL_OES_texture_npot")) {
+ AddExtensionString("GL_OES_texture_npot");
+ npot_ok = true;
+ }
+
+ // Check if we should allow GL_OES_texture_float, GL_OES_texture_half_float,
+ // GL_OES_texture_float_linear, GL_OES_texture_half_float_linear
+ bool enable_texture_float = false;
+ bool enable_texture_float_linear = false;
+ bool enable_texture_half_float = false;
+ bool enable_texture_half_float_linear = false;
+ if (helper.HasExtension("GL_ARB_texture_float")) {
+ enable_texture_float = true;
+ enable_texture_float_linear = true;
+ enable_texture_half_float = true;
+ enable_texture_half_float_linear = true;
+ } else {
+ if (helper.HasExtension("GL_OES_texture_float")) {
+ enable_texture_float = true;
+ if (helper.HasExtension("GL_OES_texture_float_linear")) {
+ enable_texture_float_linear = true;
+ }
+ }
+ if (helper.HasExtension("GL_OES_texture_half_float")) {
+ enable_texture_half_float = true;
+ if (helper.HasExtension("GL_OES_texture_half_float_linear")) {
+ enable_texture_half_float_linear = true;
+ }
+ }
+ }
+
+ if (enable_texture_float) {
+ validators_.pixel_type.AddValue(GL_FLOAT);
+ AddExtensionString("GL_OES_texture_float");
+ if (enable_texture_float_linear) {
+ AddExtensionString("GL_OES_texture_float_linear");
+ }
+ }
+
+ if (enable_texture_half_float) {
+ validators_.pixel_type.AddValue(GL_HALF_FLOAT_OES);
+ AddExtensionString("GL_OES_texture_half_float");
+ if (enable_texture_half_float_linear) {
+ AddExtensionString("GL_OES_texture_half_float_linear");
+ }
+ }
+
+ // Check for multisample support
+ if (helper.HasExtension("GL_EXT_framebuffer_multisample")) {
+ feature_flags_.ext_framebuffer_multisample = true;
+ validators_.frame_buffer_target.AddValue(GL_READ_FRAMEBUFFER_EXT);
+ validators_.frame_buffer_target.AddValue(GL_DRAW_FRAMEBUFFER_EXT);
+ validators_.g_l_state.AddValue(GL_READ_FRAMEBUFFER_BINDING_EXT);
+ validators_.render_buffer_parameter.AddValue(GL_MAX_SAMPLES_EXT);
+ AddExtensionString("GL_EXT_framebuffer_multisample");
+ AddExtensionString("GL_EXT_framebuffer_blit");
+ }
+
+ if (helper.HasExtension("GL_OES_depth24") ||
+ gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) {
+ AddExtensionString("GL_OES_depth24");
+ validators_.render_buffer_format.AddValue(GL_DEPTH_COMPONENT24);
+ }
+
+ if (helper.HasExtension("GL_OES_standard_derivatives") ||
+ gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) {
+ AddExtensionString("GL_OES_standard_derivatives");
+ feature_flags_.oes_standard_derivatives = true;
+ }
+
+ // TODO(gman): Add support for these extensions.
+ // GL_OES_depth32
+ // GL_OES_element_index_uint
+
+ feature_flags_.enable_texture_float_linear = enable_texture_float_linear;
+ feature_flags_.enable_texture_half_float_linear =
+ enable_texture_half_float_linear;
+ feature_flags_.npot_ok = npot_ok;
+}
+
+void FeatureInfo::AddExtensionString(const std::string& str) {
+ if (extensions_.find(str) == std::string::npos) {
+ extensions_ += (extensions_.empty() ? "" : " ") + str;
+ }
+}
+
+} // namespace gles2
+} // namespace gpu
+
+
+