summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc12
-rw-r--r--chrome/renderer/webgraphicscontext3d_command_buffer_impl.h3
-rw-r--r--gpu/GLES2/gl2ext.h28
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py20
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h11
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper_autogen.h12
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc31
-rw-r--r--gpu/command_buffer/client/gles2_implementation.h4
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h4
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_autogen.h68
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_test_autogen.h26
-rw-r--r--gpu/command_buffer/common/gles2_cmd_ids_autogen.h2
-rw-r--r--gpu/command_buffer/service/feature_info.cc21
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc134
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc11
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h42
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc12
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h46
-rw-r--r--gpu/command_buffer/service/mocks.h5
-rw-r--r--gpu/command_buffer/service/shader_translator.cc33
-rw-r--r--gpu/command_buffer/service/shader_translator.h10
-rw-r--r--gpu/command_buffer/service/shader_translator_unittest.cc4
22 files changed, 427 insertions, 112 deletions
diff --git a/chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc b/chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc
index b269151..6479a7a 100644
--- a/chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc
+++ b/chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc
@@ -90,7 +90,7 @@ bool WebGraphicsContext3DCommandBufferImpl::initialize(
GPUInfo gpu_info = host->gpu_info();
UMA_HISTOGRAM_ENUMERATION(
"GPU.WebGraphicsContext3D_Init_CanLoseContext",
- attributes.canRecoverFromContextLoss * 2 + gpu_info.can_lose_context(),
+ attributes.canRecoverFromContextLoss * 2 + gpu_info.can_lose_context(),
4);
if (attributes.canRecoverFromContextLoss == false) {
if (gpu_info.can_lose_context())
@@ -371,6 +371,16 @@ void WebGraphicsContext3DCommandBufferImpl::copyTextureToParentTextureCHROMIUM(
copyTextureToCompositor(texture, parentTexture);
}
+WebKit::WebString WebGraphicsContext3DCommandBufferImpl::
+ getRequestableExtensionsCHROMIUM() {
+ return WebKit::WebString::fromUTF8(glGetRequestableExtensionsCHROMIUM());
+}
+
+void WebGraphicsContext3DCommandBufferImpl::requestExtensionCHROMIUM(
+ const char* extension) {
+ glRequestExtensionCHROMIUM(extension);
+}
+
// Helper macros to reduce the amount of code.
#define DELEGATE_TO_GL(name, glname) \
diff --git a/chrome/renderer/webgraphicscontext3d_command_buffer_impl.h b/chrome/renderer/webgraphicscontext3d_command_buffer_impl.h
index bf9ecfe..b4f99d2 100644
--- a/chrome/renderer/webgraphicscontext3d_command_buffer_impl.h
+++ b/chrome/renderer/webgraphicscontext3d_command_buffer_impl.h
@@ -361,6 +361,9 @@ class WebGraphicsContext3DCommandBufferImpl
virtual void copyTextureToParentTextureCHROMIUM(
unsigned texture, unsigned parentTexture);
+ virtual WebKit::WebString getRequestableExtensionsCHROMIUM();
+ virtual void requestExtensionCHROMIUM(const char*);
+
virtual unsigned createCompositorTexture(unsigned width, unsigned height);
virtual void deleteCompositorTexture(unsigned parent_texture);
virtual void copyTextureToCompositor(unsigned texture,
diff --git a/gpu/GLES2/gl2ext.h b/gpu/GLES2/gl2ext.h
index 287b122..4a1f828 100644
--- a/gpu/GLES2/gl2ext.h
+++ b/gpu/GLES2/gl2ext.h
@@ -922,6 +922,34 @@ typedef void (GL_APIENTRYP PFNGLRESIZECHROMIUM) (GLuint width, GLuint height);
#endif
#endif
+/* GL_CHROMIUM_request_extension */
+/*
+ * This extension allows other extensions to be turned on at run time.
+ *
+ * glGetRequestableExtensionsCHROMIUM returns a space-separated and
+ * null-terminated string containing all of the extension names that
+ * can be successfully requested on the current hardware. This may
+ * include the names of extensions that have already been enabled.
+ *
+ * glRequestExtensionCHROMIUM requests that the given extension be
+ * enabled. Call glGetString(GL_EXTENSIONS) to find out whether the
+ * extension request succeeded.
+ */
+#ifndef GL_CHROMIUM_request_extension
+#define GL_CHROMIUM_request_extension 1
+#ifdef GL_GLEXT_PROTOTYPES
+#define glGetRequestableExtensionsCHROMIUM GLES2_GET_FUN(GetRequestableExtensionsCHROMIUM)
+#define glRequestExtensionCHROMIUM GLES2_GET_FUN(RequestExtensionCHROMIUM)
+#if !defined(GLES2_USE_CPP_BINDINGS)
+GL_APICALL const GLchar* GL_APIENTRY glGetRequestableExtensionsCHROMIUM (void);
+GL_APICALL void GL_APIENTRY glRequestExtensionCHROMIUM (const GLchar *extension);
+#endif
+#else
+typedef const GLchar* (GL_APIENTRYP PFNGLGETREQUESTABLEEXTENSIONSCHROMIUM) (void);
+typedef void (GL_APIENTRYP PFNGLREQUESTEXTENSIONCHROMIUM) (const GLchar *extension);
+#endif
+#endif
+
#ifdef __cplusplus
}
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 0e9d7e5..01a321f 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -209,6 +209,8 @@ GL_APICALL void* GL_APIENTRY glMapTexSubImage2DCHROMIUM (GLenum target, G
GL_APICALL void GL_APIENTRY glUnmapTexSubImage2DCHROMIUM (const void* mem);
GL_APICALL void GL_APIENTRY glCopyTextureToParentTextureCHROMIUM (GLidBindTexture client_child_id, GLidBindTexture client_parent_id);
GL_APICALL void GL_APIENTRY glResizeCHROMIUM (GLuint width, GLuint height);
+GL_APICALL const GLchar* GL_APIENTRY glGetRequestableExtensionsCHROMIUM (void);
+GL_APICALL void GL_APIENTRY glRequestExtensionCHROMIUM (const char* extension);
"""
# This is the list of all commmands that will be generated and their Id.
@@ -410,6 +412,8 @@ _CMD_ID_TABLE = {
'BlitFramebufferEXT': 446,
'CopyTextureToParentTextureCHROMIUM': 447,
'ResizeCHROMIUM': 448,
+ 'GetRequestableExtensionsCHROMIUM': 449,
+ 'RequestExtensionCHROMIUM': 450,
}
# This is a list of enum names and their valid values. It is used to map
@@ -1579,6 +1583,22 @@ _FUNCTION_INFO = {
'extension': True,
'chromium': True,
},
+ 'GetRequestableExtensionsCHROMIUM': {
+ 'type': 'Custom',
+ 'impl_func': False,
+ 'immediate': False,
+ 'cmd_args': 'uint32 bucket_id',
+ 'extension': True,
+ 'chromium': True,
+ },
+ 'RequestExtensionCHROMIUM': {
+ 'type': 'Custom',
+ 'impl_func': False,
+ 'immediate': False,
+ 'cmd_args': 'uint32 bucket_id',
+ 'extension': True,
+ 'chromium': True,
+ },
}
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index ab54997..01cb485 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -844,6 +844,17 @@ void GLES2ResizeCHROMIUM(GLuint width, GLuint height) {
GPU_CLIENT_LOG("ResizeCHROMIUM" << "(" << width << ", " << height << ")");
gles2::GetGLContext()->ResizeCHROMIUM(width, height);
}
+const GLchar* GLES2GetRequestableExtensionsCHROMIUM() {
+ GPU_CLIENT_LOG("GetRequestableExtensionsCHROMIUM" << "(" << ")");
+ const GLchar* result =
+ gles2::GetGLContext()->GetRequestableExtensionsCHROMIUM();
+ GPU_CLIENT_LOG("return:" << result)
+ return result;
+}
+void GLES2RequestExtensionCHROMIUM(const char* extension) {
+ GPU_CLIENT_LOG("RequestExtensionCHROMIUM" << "(" << extension << ")");
+ gles2::GetGLContext()->RequestExtensionCHROMIUM(extension);
+}
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_C_LIB_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index 1f2b87b..e69b7ee 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -1203,5 +1203,17 @@
c.Init(width, height);
}
+ void GetRequestableExtensionsCHROMIUM(uint32 bucket_id) {
+ gles2::GetRequestableExtensionsCHROMIUM& c =
+ GetCmdSpace<gles2::GetRequestableExtensionsCHROMIUM>();
+ c.Init(bucket_id);
+ }
+
+ void RequestExtensionCHROMIUM(uint32 bucket_id) {
+ gles2::RequestExtensionCHROMIUM& c =
+ GetCmdSpace<gles2::RequestExtensionCHROMIUM>();
+ c.Init(bucket_id);
+ }
+
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 0debcd0..64bcbe2 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -1581,5 +1581,36 @@ void GLES2Implementation::UnmapTexSubImage2DCHROMIUM(const void* mem) {
mapped_textures_.erase(it);
}
+const GLchar* GLES2Implementation::GetRequestableExtensionsCHROMIUM() {
+ const char* result = NULL;
+ // Clear the bucket so if the command fails nothing will be in it.
+ helper_->SetBucketSize(kResultBucketId, 0);
+ helper_->GetRequestableExtensionsCHROMIUM(kResultBucketId);
+ std::string str;
+ if (GetBucketAsString(kResultBucketId, &str)) {
+ // The set of requestable extensions shrinks as we enable
+ // them. Because we don't know when the client will stop referring
+ // to a previous one it queries (see GetString) we need to cache
+ // the unique results.
+ std::set<std::string>::const_iterator sit =
+ requestable_extensions_set_.find(str);
+ if (sit != requestable_extensions_set_.end()) {
+ result = sit->c_str();
+ } else {
+ std::pair<std::set<std::string>::const_iterator, bool> insert_result =
+ requestable_extensions_set_.insert(str);
+ GPU_DCHECK(insert_result.second);
+ result = insert_result.first->c_str();
+ }
+ }
+ return reinterpret_cast<const GLchar*>(result);
+}
+
+void GLES2Implementation::RequestExtensionCHROMIUM(const char* extension) {
+ SetBucketAsCString(kResultBucketId, extension);
+ helper_->RequestExtensionCHROMIUM(kResultBucketId);
+ helper_->SetBucketSize(kResultBucketId, 0);
+}
+
} // namespace gles2
} // namespace gpu
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index 0b0e242..d56e32e 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -379,6 +379,10 @@ class GLES2Implementation {
typedef std::map<uint32, std::set<std::string> > GLStringMap;
GLStringMap gl_strings_;
+ // Similar cache for glGetRequestableExtensionsCHROMIUM. We don't
+ // have an enum for this so handle it separately.
+ std::set<std::string> requestable_extensions_set_;
+
typedef std::map<const void*, MappedBuffer> MappedBufferMap;
MappedBufferMap mapped_buffers_;
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 6bf924e..bb22143 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -888,5 +888,9 @@ void ResizeCHROMIUM(GLuint width, GLuint height) {
helper_->ResizeCHROMIUM(width, height);
}
+const GLchar* GetRequestableExtensionsCHROMIUM();
+
+void RequestExtensionCHROMIUM(const char* extension);
+
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index 9e10aa7..22fb23a 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -8833,6 +8833,74 @@ COMPILE_ASSERT(offsetof(ResizeCHROMIUM, width) == 4,
COMPILE_ASSERT(offsetof(ResizeCHROMIUM, height) == 8,
OffsetOf_ResizeCHROMIUM_height_not_8);
+struct GetRequestableExtensionsCHROMIUM {
+ typedef GetRequestableExtensionsCHROMIUM ValueType;
+ static const CommandId kCmdId = kGetRequestableExtensionsCHROMIUM;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+
+ static uint32 ComputeSize() {
+ return static_cast<uint32>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() {
+ header.SetCmd<ValueType>();
+ }
+
+ void Init(uint32 _bucket_id) {
+ SetHeader();
+ bucket_id = _bucket_id;
+ }
+
+ void* Set(void* cmd, uint32 _bucket_id) {
+ static_cast<ValueType*>(cmd)->Init(_bucket_id);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32 bucket_id;
+};
+
+COMPILE_ASSERT(sizeof(GetRequestableExtensionsCHROMIUM) == 8,
+ Sizeof_GetRequestableExtensionsCHROMIUM_is_not_8);
+COMPILE_ASSERT(offsetof(GetRequestableExtensionsCHROMIUM, header) == 0,
+ OffsetOf_GetRequestableExtensionsCHROMIUM_header_not_0);
+COMPILE_ASSERT(offsetof(GetRequestableExtensionsCHROMIUM, bucket_id) == 4,
+ OffsetOf_GetRequestableExtensionsCHROMIUM_bucket_id_not_4);
+
+struct RequestExtensionCHROMIUM {
+ typedef RequestExtensionCHROMIUM ValueType;
+ static const CommandId kCmdId = kRequestExtensionCHROMIUM;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+
+ static uint32 ComputeSize() {
+ return static_cast<uint32>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() {
+ header.SetCmd<ValueType>();
+ }
+
+ void Init(uint32 _bucket_id) {
+ SetHeader();
+ bucket_id = _bucket_id;
+ }
+
+ void* Set(void* cmd, uint32 _bucket_id) {
+ static_cast<ValueType*>(cmd)->Init(_bucket_id);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32 bucket_id;
+};
+
+COMPILE_ASSERT(sizeof(RequestExtensionCHROMIUM) == 8,
+ Sizeof_RequestExtensionCHROMIUM_is_not_8);
+COMPILE_ASSERT(offsetof(RequestExtensionCHROMIUM, header) == 0,
+ OffsetOf_RequestExtensionCHROMIUM_header_not_0);
+COMPILE_ASSERT(offsetof(RequestExtensionCHROMIUM, bucket_id) == 4,
+ OffsetOf_RequestExtensionCHROMIUM_bucket_id_not_4);
+
#endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index 75fa9ba..e62ca7c 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -3480,5 +3480,31 @@ TEST(GLES2FormatTest, ResizeCHROMIUM) {
EXPECT_EQ(static_cast<GLuint>(12), cmd.height);
}
+TEST(GLES2FormatTest, GetRequestableExtensionsCHROMIUM) {
+ GetRequestableExtensionsCHROMIUM cmd = { { 0 } };
+ void* next_cmd = cmd.Set(
+ &cmd,
+ static_cast<uint32>(11));
+ EXPECT_EQ(static_cast<uint32>(GetRequestableExtensionsCHROMIUM::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<char*>(next_cmd),
+ reinterpret_cast<char*>(&cmd) + sizeof(cmd));
+ EXPECT_EQ(static_cast<uint32>(11), cmd.bucket_id);
+}
+
+TEST(GLES2FormatTest, RequestExtensionCHROMIUM) {
+ RequestExtensionCHROMIUM cmd = { { 0 } };
+ void* next_cmd = cmd.Set(
+ &cmd,
+ static_cast<uint32>(11));
+ EXPECT_EQ(static_cast<uint32>(RequestExtensionCHROMIUM::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<char*>(next_cmd),
+ reinterpret_cast<char*>(&cmd) + sizeof(cmd));
+ EXPECT_EQ(static_cast<uint32>(11), cmd.bucket_id);
+}
+
#endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_TEST_AUTOGEN_H_
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index 3702b6c..fafbada 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -201,6 +201,8 @@
OP(BlitFramebufferEXT) /* 446 */ \
OP(CopyTextureToParentTextureCHROMIUM) /* 447 */ \
OP(ResizeCHROMIUM) /* 448 */ \
+ OP(GetRequestableExtensionsCHROMIUM) /* 449 */ \
+ OP(RequestExtensionCHROMIUM) /* 450 */ \
enum CommandId {
kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this.
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index cf755d8..5d9403e 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -215,21 +215,32 @@ void FeatureInfo::AddFeatures(const char* desired_features) {
bool enable_texture_float_linear = false;
bool enable_texture_half_float = false;
bool enable_texture_half_float_linear = false;
- if (ext.HaveAndDesire("GL_ARB_texture_float")) {
+
+ bool have_arb_texture_float = ext.Have("GL_ARB_texture_float");
+
+ if (have_arb_texture_float && ext.Desire("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 (ext.HaveAndDesire("GL_OES_texture_float")) {
+ if (ext.HaveAndDesire("GL_OES_texture_float") ||
+ (have_arb_texture_float &&
+ ext.Desire("GL_OES_texture_float"))) {
enable_texture_float = true;
- if (ext.HaveAndDesire("GL_OES_texture_float_linear")) {
+ if (ext.HaveAndDesire("GL_OES_texture_float_linear") ||
+ (have_arb_texture_float &&
+ ext.Desire("GL_OES_texture_float_linear"))) {
enable_texture_float_linear = true;
}
}
- if (ext.HaveAndDesire("GL_OES_texture_half_float")) {
+ if (ext.HaveAndDesire("GL_OES_texture_half_float") ||
+ (have_arb_texture_float &&
+ ext.Desire("GL_OES_texture_half_float"))) {
enable_texture_half_float = true;
- if (ext.HaveAndDesire("GL_OES_texture_half_float_linear")) {
+ if (ext.HaveAndDesire("GL_OES_texture_half_float_linear") ||
+ (have_arb_texture_float &&
+ ext.Desire("GL_OES_texture_half_float_linear"))) {
enable_texture_half_float_linear = true;
}
}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 6c468ca..5d373fc 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -708,6 +708,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
TextureManager::TextureInfo::Ref bound_texture_cube_map;
};
+ // Initialize or re-initialize the shader translator.
+ bool InitializeShaderTranslator();
+
// Helpers for the glGen and glDelete functions.
bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
@@ -1767,12 +1770,15 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
attrib_0_value_.v[2] = 0.0f;
attrib_0_value_.v[3] = 1.0f;
- // The shader translator is not needed for EGL because it already uses the
- // GLSL ES syntax. It is translated for the unit tests because
- // GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes the empty
- // string to CompileShader and this is not a valid shader. TODO(apatrick):
- // fix this test.
- if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ||
+ // The shader translator is used for WebGL even when running on EGL
+ // because additional restrictions are needed (like only enabling
+ // GL_OES_standard_derivatives on demand). It is used for the unit
+ // tests because
+ // GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes the
+ // empty string to CompileShader and this is not a valid shader.
+ // TODO(apatrick): fix this test.
+ if ((gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
+ !feature_info_->feature_flags().chromium_webglsl) ||
gfx::GetGLImplementation() == gfx::kGLImplementationMockGL) {
use_shader_translator_ = false;
}
@@ -1981,42 +1987,59 @@ bool GLES2DecoderImpl::Initialize(gfx::GLContext* context,
glEnable(GL_POINT_SPRITE);
}
- if (use_shader_translator_) {
- ShBuiltInResources resources;
- ShInitBuiltInResources(&resources);
- resources.MaxVertexAttribs = group_->max_vertex_attribs();
- resources.MaxVertexUniformVectors =
- group_->max_vertex_uniform_vectors();
- resources.MaxVaryingVectors = group_->max_varying_vectors();
- resources.MaxVertexTextureImageUnits =
- group_->max_vertex_texture_image_units();
- resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
- resources.MaxTextureImageUnits = group_->max_texture_image_units();
- resources.MaxFragmentUniformVectors =
- group_->max_fragment_uniform_vectors();
- resources.MaxDrawBuffers = 1;
- resources.OES_standard_derivatives =
- feature_info_->feature_flags().oes_standard_derivatives ? 1 : 0;
- vertex_translator_.reset(new ShaderTranslator);
- ShShaderSpec shader_spec = feature_info_->feature_flags().chromium_webglsl ?
- SH_WEBGL_SPEC : SH_GLES2_SPEC;
- if (!vertex_translator_->Init(SH_VERTEX_SHADER, shader_spec, &resources)) {
- LOG(ERROR) << "Could not initialize vertex shader translator.";
- Destroy();
- return false;
- }
- fragment_translator_.reset(new ShaderTranslator);
- if (!fragment_translator_->Init(
- SH_FRAGMENT_SHADER, shader_spec, &resources)) {
- LOG(ERROR) << "Could not initialize fragment shader translator.";
- Destroy();
- return false;
- }
+ if (!InitializeShaderTranslator()) {
+ return false;
}
return true;
}
+bool GLES2DecoderImpl::InitializeShaderTranslator() {
+ // Re-check the state of use_shader_translator_ each time this is called.
+ if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
+ feature_info_->feature_flags().chromium_webglsl &&
+ !use_shader_translator_) {
+ use_shader_translator_ = true;
+ }
+ if (!use_shader_translator_) {
+ return true;
+ }
+ ShBuiltInResources resources;
+ ShInitBuiltInResources(&resources);
+ resources.MaxVertexAttribs = group_->max_vertex_attribs();
+ resources.MaxVertexUniformVectors =
+ group_->max_vertex_uniform_vectors();
+ resources.MaxVaryingVectors = group_->max_varying_vectors();
+ resources.MaxVertexTextureImageUnits =
+ group_->max_vertex_texture_image_units();
+ resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
+ resources.MaxTextureImageUnits = group_->max_texture_image_units();
+ resources.MaxFragmentUniformVectors =
+ group_->max_fragment_uniform_vectors();
+ resources.MaxDrawBuffers = 1;
+ resources.OES_standard_derivatives =
+ feature_info_->feature_flags().oes_standard_derivatives ? 1 : 0;
+ vertex_translator_.reset(new ShaderTranslator);
+ ShShaderSpec shader_spec = feature_info_->feature_flags().chromium_webglsl ?
+ SH_WEBGL_SPEC : SH_GLES2_SPEC;
+ bool is_glsl_es =
+ gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
+ if (!vertex_translator_->Init(
+ SH_VERTEX_SHADER, shader_spec, &resources, is_glsl_es)) {
+ LOG(ERROR) << "Could not initialize vertex shader translator.";
+ Destroy();
+ return false;
+ }
+ fragment_translator_.reset(new ShaderTranslator);
+ if (!fragment_translator_->Init(
+ SH_FRAGMENT_SHADER, shader_spec, &resources, is_glsl_es)) {
+ LOG(ERROR) << "Could not initialize fragment shader translator.";
+ Destroy();
+ return false;
+ }
+ return true;
+}
+
bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
for (GLsizei ii = 0; ii < n; ++ii) {
if (GetBufferInfo(client_ids[ii])) {
@@ -5935,6 +5958,43 @@ error::Error GLES2DecoderImpl::HandleCommandBufferEnableCHROMIUM(
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
+ uint32 immediate_data_size,
+ const gles2::GetRequestableExtensionsCHROMIUM& c) {
+ Bucket* bucket = CreateBucket(c.bucket_id);
+ scoped_ptr<FeatureInfo> info(new FeatureInfo());
+ info->Initialize(NULL);
+ bucket->SetFromString(info->extensions().c_str());
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
+ uint32 immediate_data_size, const gles2::RequestExtensionCHROMIUM& c) {
+ Bucket* bucket = GetBucket(c.bucket_id);
+ std::string feature_str;
+ if (!bucket->GetAsString(&feature_str)) {
+ return error::kInvalidArguments;
+ }
+
+ bool std_derivatives_enabled =
+ feature_info_->feature_flags().oes_standard_derivatives;
+ bool webglsl_enabled =
+ feature_info_->feature_flags().chromium_webglsl;
+
+ feature_info_->AddFeatures(feature_str.c_str());
+
+ // If we just enabled a feature which affects the shader translator,
+ // we may need to re-initialize it.
+ if (std_derivatives_enabled !=
+ feature_info_->feature_flags().oes_standard_derivatives ||
+ webglsl_enabled !=
+ feature_info_->feature_flags().chromium_webglsl) {
+ InitializeShaderTranslator();
+ }
+
+ return error::kNoError;
+}
+
// Include the auto-generated part of this file. We split this because it means
// we can easily edit the non-auto generated parts right here in this file
// instead of having to edit some template or the code generator.
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
index 9237a20..75597fa 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
@@ -119,6 +119,17 @@ void GLES2DecoderTestBase::SpecializedSetup<GetProgramInfoLog, 0>(
info->set_log_info("hello");
};
+template <>
+void GLES2DecoderTestBase::SpecializedSetup<GetVertexAttribfv, 0>(bool valid) {
+ DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
+ DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0);
+ if (valid) {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ }
+};
#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h"
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
index eaa7af3..786ad92 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
@@ -1755,5 +1755,47 @@ TEST_F(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_1) {
// TODO(gman): GetUniformLocationBucket
+
+TEST_F(GLES2DecoderTest1, GetVertexAttribfvValidArgs) {
+ SpecializedSetup<GetVertexAttribfv, 0>(true);
+ typedef GetVertexAttribfv::Result Result;
+ Result* result = static_cast<Result*>(shared_memory_address_);
+ result->size = 0;
+ GetVertexAttribfv cmd;
+ cmd.Init(
+ 1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_,
+ shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
+ GL_VERTEX_ATTRIB_ARRAY_NORMALIZED),
+ result->GetNumResults());
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_F(GLES2DecoderTest1, GetVertexAttribfvInvalidArgs2_0) {
+ EXPECT_CALL(*gl_, GetVertexAttribfv(_, _, _)).Times(0);
+ SpecializedSetup<GetVertexAttribfv, 0>(false);
+ GetVertexAttribfv::Result* result =
+ static_cast<GetVertexAttribfv::Result*>(shared_memory_address_);
+ result->size = 0;
+ GetVertexAttribfv cmd;
+ cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, kInvalidSharedMemoryId, 0);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ EXPECT_EQ(0u, result->size);
+}
+
+TEST_F(GLES2DecoderTest1, GetVertexAttribfvInvalidArgs2_1) {
+ EXPECT_CALL(*gl_, GetVertexAttribfv(_, _, _)).Times(0);
+ SpecializedSetup<GetVertexAttribfv, 0>(false);
+ GetVertexAttribfv::Result* result =
+ static_cast<GetVertexAttribfv::Result*>(shared_memory_address_);
+ result->size = 0;
+ GetVertexAttribfv cmd;
+ cmd.Init(
+ 1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_,
+ kInvalidSharedMemoryOffset);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ EXPECT_EQ(0u, result->size);
+}
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_1_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
index 925e28f..a86149f 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
@@ -224,18 +224,6 @@ void GLES2DecoderTestBase::SpecializedSetup<TexParameterivImmediate, 0>(
};
template <>
-void GLES2DecoderTestBase::SpecializedSetup<GetVertexAttribfv, 0>(bool valid) {
- DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
- DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0);
- if (valid) {
- EXPECT_CALL(*gl_, GetError())
- .WillOnce(Return(GL_NO_ERROR))
- .WillOnce(Return(GL_NO_ERROR))
- .RetiresOnSaturation();
- }
-};
-
-template <>
void GLES2DecoderTestBase::SpecializedSetup<GetVertexAttribiv, 0>(bool valid) {
DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
index 7b0d1c9..7549fa9e 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
@@ -9,48 +9,6 @@
#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
-TEST_F(GLES2DecoderTest2, GetVertexAttribfvValidArgs) {
- SpecializedSetup<GetVertexAttribfv, 0>(true);
- typedef GetVertexAttribfv::Result Result;
- Result* result = static_cast<Result*>(shared_memory_address_);
- result->size = 0;
- GetVertexAttribfv cmd;
- cmd.Init(
- 1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_,
- shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
- GL_VERTEX_ATTRIB_ARRAY_NORMALIZED),
- result->GetNumResults());
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest2, GetVertexAttribfvInvalidArgs2_0) {
- EXPECT_CALL(*gl_, GetVertexAttribfv(_, _, _)).Times(0);
- SpecializedSetup<GetVertexAttribfv, 0>(false);
- GetVertexAttribfv::Result* result =
- static_cast<GetVertexAttribfv::Result*>(shared_memory_address_);
- result->size = 0;
- GetVertexAttribfv cmd;
- cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, kInvalidSharedMemoryId, 0);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
- EXPECT_EQ(0u, result->size);
-}
-
-TEST_F(GLES2DecoderTest2, GetVertexAttribfvInvalidArgs2_1) {
- EXPECT_CALL(*gl_, GetVertexAttribfv(_, _, _)).Times(0);
- SpecializedSetup<GetVertexAttribfv, 0>(false);
- GetVertexAttribfv::Result* result =
- static_cast<GetVertexAttribfv::Result*>(shared_memory_address_);
- result->size = 0;
- GetVertexAttribfv cmd;
- cmd.Init(
- 1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_,
- kInvalidSharedMemoryOffset);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
- EXPECT_EQ(0u, result->size);
-}
-
TEST_F(GLES2DecoderTest2, GetVertexAttribivValidArgs) {
SpecializedSetup<GetVertexAttribiv, 0>(true);
typedef GetVertexAttribiv::Result Result;
@@ -1611,5 +1569,9 @@ TEST_F(GLES2DecoderTest2, ViewportInvalidArgs3_0) {
// TODO(gman): CopyTextureToParentTextureCHROMIUM
// TODO(gman): ResizeCHROMIUM
+// TODO(gman): GetRequestableExtensionsCHROMIUM
+
+// TODO(gman): RequestExtensionCHROMIUM
+
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/mocks.h b/gpu/command_buffer/service/mocks.h
index 8c84547..8a11aee 100644
--- a/gpu/command_buffer/service/mocks.h
+++ b/gpu/command_buffer/service/mocks.h
@@ -83,10 +83,11 @@ class MockShaderTranslator : public ShaderTranslatorInterface {
public:
virtual ~MockShaderTranslator() { }
- MOCK_METHOD3(Init, bool(
+ MOCK_METHOD4(Init, bool(
ShShaderType shader_type,
ShShaderSpec shader_spec,
- const ShBuiltInResources* resources));
+ const ShBuiltInResources* resources,
+ bool implementation_is_glsl_es));
MOCK_METHOD1(Translate, bool(const char* shader));
MOCK_CONST_METHOD0(translated_shader, const char*());
MOCK_CONST_METHOD0(info_log, const char*());
diff --git a/gpu/command_buffer/service/shader_translator.cc b/gpu/command_buffer/service/shader_translator.cc
index 551ae14..eb5b265 100644
--- a/gpu/command_buffer/service/shader_translator.cc
+++ b/gpu/command_buffer/service/shader_translator.cc
@@ -4,6 +4,8 @@
#include "gpu/command_buffer/service/shader_translator.h"
+#include <string.h>
+
#include "base/at_exit.h"
#include "base/logging.h"
@@ -62,7 +64,9 @@ void GetVariableInfo(ShHandle compiler, ShShaderInfo var_type,
namespace gpu {
namespace gles2 {
-ShaderTranslator::ShaderTranslator() : compiler_(NULL) {
+ShaderTranslator::ShaderTranslator()
+ : compiler_(NULL),
+ implementation_is_glsl_es_(false) {
}
ShaderTranslator::~ShaderTranslator() {
@@ -72,7 +76,8 @@ ShaderTranslator::~ShaderTranslator() {
bool ShaderTranslator::Init(ShShaderType shader_type,
ShShaderSpec shader_spec,
- const ShBuiltInResources* resources) {
+ const ShBuiltInResources* resources,
+ bool implementation_is_glsl_es) {
// Make sure Init is called only once.
DCHECK(compiler_ == NULL);
DCHECK(shader_type == SH_FRAGMENT_SHADER || shader_type == SH_VERTEX_SHADER);
@@ -83,6 +88,7 @@ bool ShaderTranslator::Init(ShShaderType shader_type,
return false;
compiler_ = ShConstructCompiler(shader_type, shader_spec, resources);
+ implementation_is_glsl_es_ = implementation_is_glsl_es;
return compiler_ != NULL;
}
@@ -96,12 +102,23 @@ bool ShaderTranslator::Translate(const char* shader) {
int compile_options = SH_OBJECT_CODE | SH_ATTRIBUTES_UNIFORMS;
if (ShCompile(compiler_, &shader, 1, compile_options)) {
success = true;
- // Get translated shader.
- int obj_code_len = 0;
- ShGetInfo(compiler_, SH_OBJECT_CODE_LENGTH, &obj_code_len);
- if (obj_code_len > 1) {
- translated_shader_.reset(new char[obj_code_len]);
- ShGetObjectCode(compiler_, translated_shader_.get());
+ if (!implementation_is_glsl_es_) {
+ // Get translated shader.
+ int obj_code_len = 0;
+ ShGetInfo(compiler_, SH_OBJECT_CODE_LENGTH, &obj_code_len);
+ if (obj_code_len > 1) {
+ translated_shader_.reset(new char[obj_code_len]);
+ ShGetObjectCode(compiler_, translated_shader_.get());
+ }
+ } else {
+ // Pass down the original shader's source rather than the
+ // compiler's output. TODO(kbr): once the shader compiler has a
+ // GLSL ES backend, use its output.
+ int shader_code_len = 1 + strlen(shader);
+ if (shader_code_len > 1) {
+ translated_shader_.reset(new char[shader_code_len]);
+ strncpy(translated_shader_.get(), shader, shader_code_len);
+ }
}
// Get info for attribs and uniforms.
GetVariableInfo(compiler_, SH_ACTIVE_ATTRIBUTES, &attrib_map_);
diff --git a/gpu/command_buffer/service/shader_translator.h b/gpu/command_buffer/service/shader_translator.h
index 852ee5f..084d1b8 100644
--- a/gpu/command_buffer/service/shader_translator.h
+++ b/gpu/command_buffer/service/shader_translator.h
@@ -15,7 +15,8 @@
namespace gpu {
namespace gles2 {
-// Translates GLSL ES 2.0 shader to desktop GLSL shader.
+// Translates a GLSL ES 2.0 shader to desktop GLSL shader, or just
+// validates GLSL ES 2.0 shaders on a true GLSL ES implementation.
class ShaderTranslatorInterface {
public:
virtual ~ShaderTranslatorInterface() { }
@@ -25,7 +26,8 @@ class ShaderTranslatorInterface {
virtual bool Init(
ShShaderType shader_type,
ShShaderSpec shader_spec,
- const ShBuiltInResources* resources) = 0;
+ const ShBuiltInResources* resources,
+ bool implementation_is_glsl_es) = 0;
// Translates the given shader source.
// Returns true if translation is successful, false otherwise.
@@ -66,7 +68,8 @@ class ShaderTranslator : public ShaderTranslatorInterface {
virtual bool Init(
ShShaderType shader_type,
ShShaderSpec shader_spec,
- const ShBuiltInResources* resources);
+ const ShBuiltInResources* resources,
+ bool implementation_is_glsl_es);
// Overridden from ShaderTranslatorInterface.
virtual bool Translate(const char* shader);
@@ -88,6 +91,7 @@ class ShaderTranslator : public ShaderTranslatorInterface {
scoped_array<char> info_log_;
VariableMap attrib_map_;
VariableMap uniform_map_;
+ bool implementation_is_glsl_es_;
DISALLOW_COPY_AND_ASSIGN(ShaderTranslator);
};
diff --git a/gpu/command_buffer/service/shader_translator_unittest.cc b/gpu/command_buffer/service/shader_translator_unittest.cc
index dbd9c60..5238859 100644
--- a/gpu/command_buffer/service/shader_translator_unittest.cc
+++ b/gpu/command_buffer/service/shader_translator_unittest.cc
@@ -22,9 +22,9 @@ class ShaderTranslatorTest : public testing::Test {
ShInitBuiltInResources(&resources);
ASSERT_TRUE(vertex_translator_.Init(
- SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources));
+ SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources, false));
ASSERT_TRUE(fragment_translator_.Init(
- SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources));
+ SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources, false));
// Post-init the results must be empty.
// Vertex translator results.
EXPECT_TRUE(vertex_translator_.translated_shader() == NULL);