diff options
author | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-08 22:00:10 +0000 |
---|---|---|
committer | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-08 22:00:10 +0000 |
commit | 4e8a5b125ab20cdeeba546c8c656062165087afa (patch) | |
tree | 4e7cbddda9de296df908c13be3df6901a94ed0e4 /gpu | |
parent | b2134acfa36836b9ec250c02fc83f75f3a2073d7 (diff) | |
download | chromium_src-4e8a5b125ab20cdeeba546c8c656062165087afa.zip chromium_src-4e8a5b125ab20cdeeba546c8c656062165087afa.tar.gz chromium_src-4e8a5b125ab20cdeeba546c8c656062165087afa.tar.bz2 |
Resubmit CL http://codereview.chromium.org/1992008/
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/2013010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46793 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
22 files changed, 426 insertions, 193 deletions
diff --git a/gpu/GLES2/gles2_command_buffer.h b/gpu/GLES2/gles2_command_buffer.h new file mode 100644 index 0000000..137cd78 --- /dev/null +++ b/gpu/GLES2/gles2_command_buffer.h @@ -0,0 +1,18 @@ +// 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. + +// This file defines constants and functions for the Pepper gles2 command +// buffers that fall outside the scope of OpenGL ES 2.0 + +#ifndef GPU_GLES2_GLES2_COMMAND_BUFFER_H_ +#define GPU_GLES2_GLES2_COMMAND_BUFFER_H_ + +// constants for CommandBufferEnable command. +#define GLES2_ALLOW_BUFFERS_ON_MULTIPLE_TARGETS 0x0001 + +#endif // GPU_GLES2_GLES2_COMMAND_BUFFER_H_ + + + + diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 9b90b38..b3e5ade 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -181,7 +181,7 @@ GL_APICALL GLuint GL_APIENTRY glGetMaxValueInBuffer (GLidBuffer buffer_id, GL_APICALL void GL_APIENTRY glGenSharedIds (GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids); GL_APICALL void GL_APIENTRY glDeleteSharedIds (GLuint namespace_id, GLsizei n, const GLuint* ids); GL_APICALL void GL_APIENTRY glRegisterSharedIds (GLuint namespace_id, GLsizei n, const GLuint* ids); -""" +GL_APICALL void GL_APIENTRY glCommandBufferEnable (GLenumCommandBufferState cap, GLboolean enable);""" # This is the list of all commmands that will be generated and their Id. # If a command is not listed in this table it is an error. @@ -375,6 +375,7 @@ _CMD_ID_TABLE = { 'GenSharedIds': 439, 'DeleteSharedIds': 440, 'RegisterSharedIds': 441, + 'CommandBufferEnable': 442, } # This is a list of enum names and their valid values. It is used to map @@ -511,6 +512,12 @@ _ENUM_LISTS = { 'GL_FOG_HINT', ], }, + 'CommandBufferState': { + 'type': 'GLenum', + 'valid': [ + 'GLES2_ALLOW_BUFFERS_ON_MULTIPLE_TARGETS', + ], + }, 'TextureTarget': { 'type': 'GLenum', 'valid': [ @@ -1009,6 +1016,10 @@ _FUNCTION_INFO = { 'result': ['GLenum'], }, 'ClearDepthf': {'decoder_func': 'glClearDepth'}, + 'CommandBufferEnable': { + 'decoder_func': 'DoCommandBufferEnable', + 'expectation': False, + }, 'CompileShader': {'decoder_func': 'DoCompileShader', 'unit_test': False}, 'CompressedTexImage2D': {'type': 'Manual','immediate': True}, 'CompressedTexSubImage2D': {'type': 'Data'}, @@ -1128,6 +1139,7 @@ _FUNCTION_INFO = { 'type': 'GETn', 'result': ['SizedResult<GLboolean>'], 'decoder_func': 'DoGetBooleanv', + 'gl_test_func': 'glGetIntegerv', }, 'GetBufferParameteriv': {'type': 'GETn', 'result': ['SizedResult<GLint>']}, 'GetError': { @@ -1140,6 +1152,7 @@ _FUNCTION_INFO = { 'type': 'GETn', 'result': ['SizedResult<GLfloat>'], 'decoder_func': 'DoGetFloatv', + 'gl_test_func': 'glGetIntegerv', }, 'GetFramebufferAttachmentParameteriv': { 'type': 'GETn', @@ -2296,6 +2309,10 @@ class GENnHandler(TypeHandler): def WriteGLES2ImplementationHeader(self, func, file): """Overrriden from TypeHandler.""" code = """%(return_type)s %(name)s(%(typed_args)s) { + if (%(count_name)s < 0) { + SetGLError(GL_INVALID_VALUE, "gl%(name)s: n < 0"); + return; + } %(resource_type)s_id_handler_->MakeIds(0, %(args)s); helper_->%(name)sImmediate(%(args)s); } @@ -2306,7 +2323,8 @@ class GENnHandler(TypeHandler): 'name': func.original_name, 'typed_args': func.MakeTypedOriginalArgString(""), 'args': func.MakeOriginalArgString(""), - 'resource_type': func.name[3:-1].lower() + 'resource_type': func.name[3:-1].lower(), + 'count_name': func.GetOriginalArgs()[0].name, }) def WriteServiceUnitTest(self, func, file): @@ -2658,15 +2676,24 @@ TEST_F(%(test_name)s, %(name)sInvalidArgs) { """Overrriden from TypeHandler.""" impl_decl = func.GetInfo('impl_decl') if impl_decl == None or impl_decl == True: - file.Write("%s %s(%s) {\n" % - (func.return_type, func.original_name, - func.MakeTypedOriginalArgString(""))) - file.Write(" %s_id_handler_->FreeIds(%s);\n" % - (func.name[6:-1].lower(), func.MakeOriginalArgString(""))) - file.Write(" helper_->%sImmediate(%s);\n" % - (func.name, func.MakeOriginalArgString(""))) - file.Write("}\n") - file.Write("\n") + code = """%(return_type)s %(name)s(%(typed_args)s) { + if (%(count_name)s < 0) { + SetGLError(GL_INVALID_VALUE, "gl%(name)s: n < 0"); + return; + } + %(resource_type)s_id_handler_->FreeIds(%(args)s); + helper_->%(name)sImmediate(%(args)s); +} + +""" + file.Write(code % { + 'return_type': func.return_type, + 'name': func.original_name, + 'typed_args': func.MakeTypedOriginalArgString(""), + 'args': func.MakeOriginalArgString(""), + 'resource_type': func.name[6:-1].lower(), + 'count_name': func.GetOriginalArgs()[0].name, + }) def WriteImmediateCmdComputeSize(self, func, file): """Overrriden from TypeHandler.""" @@ -2788,11 +2815,7 @@ class GETnHandler(TypeHandler): arg.WriteGetCode(file) code = """ typedef %(func_name)s::Result Result; - GLsizei num_values = util_.GLGetNumValuesReturned(pname); - if (num_values == 0) { - SetGLError(GL_INVALID_ENUM, "gl%(func_name)s: invalid enum"); - return error::kNoError; - } + GLsizei num_values = GetNumValuesReturnedForGLGet(pname, &num_values); Result* result = GetSharedMemoryAs<Result*>( c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); %(last_arg_type)s params = result ? result->GetData() : NULL; @@ -2877,7 +2900,10 @@ TEST_F(%(test_name)s, %(name)sValidArgs) { if arg.name == 'pname': valid_pname = arg_value count += 1 - gl_arg_strings.append("result->GetData()") + if func.GetInfo('gl_test_func') == 'glGetIntegerv': + gl_arg_strings.append("_") + else: + gl_arg_strings.append("result->GetData()") self.WriteValidUnitTest(func, file, valid_test, { 'local_gl_args': ", ".join(gl_arg_strings), diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 73cd6ce..d7983ea 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -519,6 +519,9 @@ void GLES2RegisterSharedIds( GLuint namespace_id, GLsizei n, const GLuint* ids) { gles2::GetGLContext()->RegisterSharedIds(namespace_id, n, ids); } +void GLES2CommandBufferEnable(GLenum cap, GLboolean enable) { + gles2::GetGLContext()->CommandBufferEnable(cap, enable); +} #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 652579d..1cbc45f 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -1148,5 +1148,10 @@ c.Init(namespace_id, n, ids_shm_id, ids_shm_offset); } + void CommandBufferEnable(GLenum cap, GLboolean enable) { + gles2::CommandBufferEnable& c = GetCmdSpace<gles2::CommandBufferEnable>(); + c.Init(cap, enable); + } + #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 8e7867c..8d7c57f 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -1340,6 +1340,10 @@ void GLES2Implementation::BindBuffer(GLenum target, GLuint buffer) { } void GLES2Implementation::DeleteBuffers(GLsizei n, const GLuint* buffers) { + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "glDeleteBuffers: n < 0"); + return; + } buffer_id_handler_->FreeIds(n, buffers); for (GLsizei ii = 0; ii < n; ++ii) { if (buffers[ii] == bound_array_buffer_id_) { diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 63d0b53..ae826d8 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -167,6 +167,10 @@ void CullFace(GLenum mode) { } void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) { + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "glDeleteFramebuffers: n < 0"); + return; + } framebuffer_id_handler_->FreeIds(n, framebuffers); helper_->DeleteFramebuffersImmediate(n, framebuffers); } @@ -177,6 +181,10 @@ void DeleteProgram(GLuint program) { } void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) { + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "glDeleteRenderbuffers: n < 0"); + return; + } renderbuffer_id_handler_->FreeIds(n, renderbuffers); helper_->DeleteRenderbuffersImmediate(n, renderbuffers); } @@ -187,6 +195,10 @@ void DeleteShader(GLuint shader) { } void DeleteTextures(GLsizei n, const GLuint* textures) { + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "glDeleteTextures: n < 0"); + return; + } texture_id_handler_->FreeIds(n, textures); helper_->DeleteTexturesImmediate(n, textures); } @@ -240,6 +252,10 @@ void FrontFace(GLenum mode) { } void GenBuffers(GLsizei n, GLuint* buffers) { + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "glGenBuffers: n < 0"); + return; + } buffer_id_handler_->MakeIds(0, n, buffers); helper_->GenBuffersImmediate(n, buffers); } @@ -249,16 +265,28 @@ void GenerateMipmap(GLenum target) { } void GenFramebuffers(GLsizei n, GLuint* framebuffers) { + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "glGenFramebuffers: n < 0"); + return; + } framebuffer_id_handler_->MakeIds(0, n, framebuffers); helper_->GenFramebuffersImmediate(n, framebuffers); } void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) { + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "glGenRenderbuffers: n < 0"); + return; + } renderbuffer_id_handler_->MakeIds(0, n, renderbuffers); helper_->GenRenderbuffersImmediate(n, renderbuffers); } void GenTextures(GLsizei n, GLuint* textures) { + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "glGenTextures: n < 0"); + return; + } texture_id_handler_->MakeIds(0, n, textures); helper_->GenTexturesImmediate(n, textures); } @@ -762,5 +790,9 @@ void DeleteSharedIds(GLuint namespace_id, GLsizei n, const GLuint* ids); void RegisterSharedIds(GLuint namespace_id, GLsizei n, const GLuint* ids); +void CommandBufferEnable(GLenum cap, GLboolean enable) { + helper_->CommandBufferEnable(cap, enable); +} + #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 7e07dd7..46e04aa 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -8438,6 +8438,44 @@ COMPILE_ASSERT(offsetof(RegisterSharedIds, ids_shm_id) == 12, COMPILE_ASSERT(offsetof(RegisterSharedIds, ids_shm_offset) == 16, OffsetOf_RegisterSharedIds_ids_shm_offset_not_16); +struct CommandBufferEnable { + typedef CommandBufferEnable ValueType; + static const CommandId kCmdId = kCommandBufferEnable; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _cap, GLboolean _enable) { + SetHeader(); + cap = _cap; + enable = _enable; + } + + void* Set(void* cmd, GLenum _cap, GLboolean _enable) { + static_cast<ValueType*>(cmd)->Init(_cap, _enable); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32 cap; + uint32 enable; +}; + +COMPILE_ASSERT(sizeof(CommandBufferEnable) == 12, + Sizeof_CommandBufferEnable_is_not_12); +COMPILE_ASSERT(offsetof(CommandBufferEnable, header) == 0, + OffsetOf_CommandBufferEnable_header_not_0); +COMPILE_ASSERT(offsetof(CommandBufferEnable, cap) == 4, + OffsetOf_CommandBufferEnable_cap_not_4); +COMPILE_ASSERT(offsetof(CommandBufferEnable, enable) == 8, + OffsetOf_CommandBufferEnable_enable_not_8); + #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 4e003eb..c2a1a0e 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -3329,5 +3329,20 @@ TEST(GLES2FormatTest, RegisterSharedIds) { EXPECT_EQ(static_cast<uint32>(14), cmd.ids_shm_offset); } +TEST(GLES2FormatTest, CommandBufferEnable) { + CommandBufferEnable cmd = { { 0 } }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLboolean>(12)); + EXPECT_EQ(static_cast<uint32>(CommandBufferEnable::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<GLenum>(11), cmd.cap); + EXPECT_EQ(static_cast<GLboolean>(12), cmd.enable); +} + #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_TEST_AUTOGEN_H_ diff --git a/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h index ba87b28..7610364 100644 --- a/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h @@ -383,6 +383,8 @@ TEST(GLES2CommandIdTest, CommandIdsMatch) { GLES2_DeleteSharedIds_kCmdId_mismatch); COMPILE_ASSERT(RegisterSharedIds::kCmdId == 441, GLES2_RegisterSharedIds_kCmdId_mismatch); + COMPILE_ASSERT(CommandBufferEnable::kCmdId == 442, + GLES2_CommandBufferEnable_kCmdId_mismatch); } #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_ID_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 eebe3ff..2ffe5c6 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -194,6 +194,7 @@ OP(GenSharedIds) /* 439 */ \ OP(DeleteSharedIds) /* 440 */ \ OP(RegisterSharedIds) /* 441 */ \ + OP(CommandBufferEnable) /* 442 */ \ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this. diff --git a/gpu/command_buffer/docs/gles2_cmd_format_docs.txt b/gpu/command_buffer/docs/gles2_cmd_format_docs.txt index 73882c4..3a08c1a 100644 --- a/gpu/command_buffer/docs/gles2_cmd_format_docs.txt +++ b/gpu/command_buffer/docs/gles2_cmd_format_docs.txt @@ -2214,4 +2214,12 @@ struct RegisterSharedIds { uint32 ids_shm_offset; //!< uint32 }; +//! Command that enables or disables command buffer specific features. +struct CommandBufferEnable { + static const CommandId kCmdId = 442; + + CommandHeader header; + uint32 cap; //!< GLenum + uint32 enable; //!< GLboolean +}; diff --git a/gpu/command_buffer/service/buffer_manager.cc b/gpu/command_buffer/service/buffer_manager.cc index 6086819..c4c750e 100644 --- a/gpu/command_buffer/service/buffer_manager.cc +++ b/gpu/command_buffer/service/buffer_manager.cc @@ -32,12 +32,13 @@ void BufferManager::RemoveBufferInfo(GLuint client_id) { } } -void BufferManager::BufferInfo::SetSize(GLsizeiptr size) { +void BufferManager::BufferInfo::SetSize(GLsizeiptr size, bool shadow) { DCHECK(!IsDeleted()); - if (size != size_) { + if (size != size_ || shadow != shadowed_) { + shadowed_ = shadow; size_ = size; ClearCache(); - if (target_ == GL_ELEMENT_ARRAY_BUFFER) { + if (shadowed_) { shadow_.reset(new int8[size]); memset(shadow_.get(), 0, size); } @@ -51,7 +52,7 @@ bool BufferManager::BufferInfo::SetRange( offset + size > size_) { return false; } - if (target_ == GL_ELEMENT_ARRAY_BUFFER) { + if (shadowed_) { memcpy(shadow_.get() + offset, data, size); ClearCache(); } @@ -78,7 +79,6 @@ GLuint GetMaxValue(const void* data, GLuint offset, GLsizei count) { bool BufferManager::BufferInfo::GetMaxValueForRange( GLuint offset, GLsizei count, GLenum type, GLuint* max_value) { - DCHECK_EQ(target_, static_cast<GLenum>(GL_ELEMENT_ARRAY_BUFFER)); DCHECK(!IsDeleted()); Range range(offset, count, type); RangeToMaxValueMap::iterator it = range_set_.find(range); @@ -101,6 +101,10 @@ bool BufferManager::BufferInfo::GetMaxValueForRange( return false; } + if (!shadowed_) { + return false; + } + // Scan the range for the max value and store GLuint max_v = 0; switch (type) { @@ -143,6 +147,25 @@ bool BufferManager::GetClientId(GLuint service_id, GLuint* client_id) const { return false; } +void BufferManager::SetSize(BufferManager::BufferInfo* info, GLsizeiptr size) { + DCHECK(info); + info->SetSize(size, + info->target() == GL_ELEMENT_ARRAY_BUFFER || + allow_buffers_on_multiple_targets_); +} + +bool BufferManager::SetTarget(BufferManager::BufferInfo* info, GLenum target) { + // Check that we are not trying to bind it to a different target. + if (info->target() != 0 && info->target() != target && + !allow_buffers_on_multiple_targets_) { + return false; + } + if (info->target() == 0) { + info->set_target(target); + } + return true; +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/buffer_manager.h b/gpu/command_buffer/service/buffer_manager.h index d944532..bc0d1db 100644 --- a/gpu/command_buffer/service/buffer_manager.h +++ b/gpu/command_buffer/service/buffer_manager.h @@ -30,28 +30,18 @@ class BufferManager { explicit BufferInfo(GLuint service_id) : service_id_(service_id), target_(0), - size_(0) { + size_(0), + shadowed_(false) { } GLuint service_id() const { return service_id_; } - GLenum target() const { - return target_; - } - - void set_target(GLenum target) { - DCHECK_EQ(target_, 0u); // you can only set this once. - target_ = target; - } - GLsizeiptr size() const { return size_; } - void SetSize(GLsizeiptr size); - // Sets a range of data for this buffer. Returns false if the offset or size // is out of range. bool SetRange( @@ -70,6 +60,7 @@ class BufferManager { private: friend class BufferManager; + friend class BufferManagerTest; friend class base::RefCounted<BufferInfo>; // Represents a range in a buffer. @@ -102,12 +93,27 @@ class BufferManager { ~BufferInfo() { } + GLenum target() const { + return target_; + } + + void set_target(GLenum target) { + DCHECK_EQ(target_, 0u); // you can only set this once. + target_ = target; + } + + bool shadowed() const { + return shadowed_; + } + void MarkAsDeleted() { service_id_ = 0; shadow_.reset(); ClearCache(); } + void SetSize(GLsizeiptr size, bool shadow); + // Clears any cache of index ranges. void ClearCache(); @@ -122,8 +128,11 @@ class BufferManager { // Size of buffer. GLsizeiptr size_; + // Whether or not the data is shadowed. + bool shadowed_; + // A copy of the data in the buffer. This data is only kept if the target - // is GL_ELEMENT_BUFFER_ARRAY + // is backed_ = true. scoped_array<int8> shadow_; // A map of ranges to the highest value in that range of a certain type. @@ -131,7 +140,9 @@ class BufferManager { RangeToMaxValueMap range_set_; }; - BufferManager() { } + BufferManager() + : allow_buffers_on_multiple_targets_(false) { + } // Creates a BufferInfo for the given buffer. void CreateBufferInfo(GLuint client_id, GLuint service_id); @@ -145,12 +156,25 @@ class BufferManager { // Gets a client id for a given service id. bool GetClientId(GLuint service_id, GLuint* client_id) const; + // Sets the size of a buffer. + void SetSize(BufferInfo* info, GLsizeiptr size); + + // Sets the target of a buffer. Returns false if the target can not be set. + bool SetTarget(BufferInfo* info, GLenum target); + + void set_allow_buffers_on_multiple_targets(bool allow) { + allow_buffers_on_multiple_targets_ = allow; + } + private: // Info for each buffer in the system. // TODO(gman): Choose a faster container. typedef std::map<GLuint, BufferInfo::Ref> BufferInfoMap; BufferInfoMap buffer_infos_; + // Whether or not buffers can be bound to multiple targets. + bool allow_buffers_on_multiple_targets_; + DISALLOW_COPY_AND_ASSIGN(BufferManager); }; diff --git a/gpu/command_buffer/service/buffer_manager_unittest.cc b/gpu/command_buffer/service/buffer_manager_unittest.cc index 1c09ada..96a4f03 100644 --- a/gpu/command_buffer/service/buffer_manager_unittest.cc +++ b/gpu/command_buffer/service/buffer_manager_unittest.cc @@ -20,6 +20,10 @@ class BufferManagerTest : public testing::Test { virtual void TearDown() { } + GLenum GetTarget(const BufferManager::BufferInfo* info) const { + return info->target(); + } + BufferManager manager_; }; @@ -33,17 +37,17 @@ TEST_F(BufferManagerTest, Basic) { // Check buffer got created. BufferManager::BufferInfo* info1 = manager_.GetBufferInfo(kClientBuffer1Id); ASSERT_TRUE(info1 != NULL); - EXPECT_EQ(0u, info1->target()); + EXPECT_EQ(0u, GetTarget(info1)); EXPECT_EQ(0, info1->size()); EXPECT_FALSE(info1->IsDeleted()); EXPECT_EQ(kServiceBuffer1Id, info1->service_id()); GLuint client_id = 0; EXPECT_TRUE(manager_.GetClientId(info1->service_id(), &client_id)); EXPECT_EQ(kClientBuffer1Id, client_id); - info1->set_target(GL_ELEMENT_ARRAY_BUFFER); - EXPECT_EQ(static_cast<GLenum>(GL_ELEMENT_ARRAY_BUFFER), info1->target()); + manager_.SetTarget(info1, GL_ELEMENT_ARRAY_BUFFER); + EXPECT_EQ(static_cast<GLenum>(GL_ELEMENT_ARRAY_BUFFER), GetTarget(info1)); // Check we and set its size. - info1->SetSize(kBuffer1Size); + manager_.SetSize(info1, kBuffer1Size); EXPECT_EQ(kBuffer1Size, info1->size()); // Check we get nothing for a non-existent buffer. EXPECT_TRUE(manager_.GetBufferInfo(kClientBuffer2Id) == NULL); @@ -61,8 +65,8 @@ TEST_F(BufferManagerTest, SetRange) { manager_.CreateBufferInfo(kClientBufferId, kServiceBufferId); BufferManager::BufferInfo* info = manager_.GetBufferInfo(kClientBufferId); ASSERT_TRUE(info != NULL); - info->set_target(GL_ELEMENT_ARRAY_BUFFER); - info->SetSize(sizeof(data)); + manager_.SetTarget(info, GL_ELEMENT_ARRAY_BUFFER); + manager_.SetSize(info, sizeof(data)); EXPECT_TRUE(info->SetRange(0, sizeof(data), data)); EXPECT_TRUE(info->SetRange(sizeof(data), 0, data)); EXPECT_FALSE(info->SetRange(sizeof(data), 1, data)); @@ -77,8 +81,8 @@ TEST_F(BufferManagerTest, GetMaxValueForRangeUint8) { manager_.CreateBufferInfo(kClientBufferId, kServiceBufferId); BufferManager::BufferInfo* info = manager_.GetBufferInfo(kClientBufferId); ASSERT_TRUE(info != NULL); - info->set_target(GL_ELEMENT_ARRAY_BUFFER); - info->SetSize(sizeof(data)); + manager_.SetTarget(info, GL_ELEMENT_ARRAY_BUFFER); + manager_.SetSize(info, sizeof(data)); EXPECT_TRUE(info->SetRange(0, sizeof(data), data)); GLuint max_value; // Check entire range succeeds. @@ -107,8 +111,8 @@ TEST_F(BufferManagerTest, GetMaxValueForRangeUint16) { manager_.CreateBufferInfo(kClientBufferId, kServiceBufferId); BufferManager::BufferInfo* info = manager_.GetBufferInfo(kClientBufferId); ASSERT_TRUE(info != NULL); - info->set_target(GL_ELEMENT_ARRAY_BUFFER); - info->SetSize(sizeof(data)); + manager_.SetTarget(info, GL_ELEMENT_ARRAY_BUFFER); + manager_.SetSize(info, sizeof(data)); EXPECT_TRUE(info->SetRange(0, sizeof(data), data)); GLuint max_value; // Check entire range succeeds. @@ -139,8 +143,8 @@ TEST_F(BufferManagerTest, GetMaxValueForRangeUint32) { manager_.CreateBufferInfo(kClientBufferId, kServiceBufferId); BufferManager::BufferInfo* info = manager_.GetBufferInfo(kClientBufferId); ASSERT_TRUE(info != NULL); - info->set_target(GL_ELEMENT_ARRAY_BUFFER); - info->SetSize(sizeof(data)); + manager_.SetTarget(info, GL_ELEMENT_ARRAY_BUFFER); + manager_.SetSize(info, sizeof(data)); EXPECT_TRUE(info->SetRange(0, sizeof(data), data)); GLuint max_value; // Check entire range succeeds. diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 2242736..74b0385 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -30,6 +30,7 @@ #include "gpu/command_buffer/service/renderbuffer_manager.h" #include "gpu/command_buffer/service/shader_manager.h" #include "gpu/command_buffer/service/texture_manager.h" +#include "gpu/GLES2/gles2_command_buffer.h" // TODO(alokp): Remove GLES2_GPU_SERVICE_TRANSLATE_SHADER guard // as soon as translator is ready. @@ -672,6 +673,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // Wrapper for glCheckFramebufferStatus GLenum DoCheckFramebufferStatus(GLenum target); + // Helper for CommandBufferEnable cmd. + void DoCommandBufferEnable(GLenum pname, GLboolean enable); + // Wrapper for glCompileShader. void DoCompileShader(GLuint shader); @@ -773,6 +777,10 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // Wrapper for glValidateProgram. void DoValidateProgram(GLuint program_client_id); + // Gets the number of values that will be returned by glGetXXX. Returns + // false if pname is unknown. + bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values); + // Gets the GLError through our wrapper. GLenum GetGLError(); @@ -1242,6 +1250,7 @@ bool GLES2DecoderImpl::Initialize(gfx::GLContext* context, texture_units_[tt].bound_texture_cube_map = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP); } + GLuint ids[2]; glGenTextures(2, ids); // Make black textures for replacing non-renderable textures. @@ -1794,16 +1803,11 @@ void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) { } } if (info) { - // Check the buffer exists - // Check that we are not trying to bind it to a different target. - if ((info->target() != 0 && info->target() != target)) { + if (!buffer_manager()->SetTarget(info, target)) { SetGLError(GL_INVALID_OPERATION, "glBindBuffer: buffer bound to more than 1 target"); return; } - if (info->target() == 0) { - info->set_target(target); - } service_id = info->service_id(); } switch (target) { @@ -1944,32 +1948,41 @@ void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { bool GLES2DecoderImpl::GetHelper( GLenum pname, GLint* params, GLsizei* num_written) { - DCHECK(params); DCHECK(num_written); switch (pname) { #if !defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *num_written = 1; - *params = GL_RGBA; // TODO(gman): get correct format. + if (params) { + *params = GL_RGBA; // TODO(gman): get correct format. + } return true; case GL_IMPLEMENTATION_COLOR_READ_TYPE: *num_written = 1; - *params = GL_UNSIGNED_BYTE; // TODO(gman): get correct type. + if (params) { + *params = GL_UNSIGNED_BYTE; // TODO(gman): get correct type. + } return true; case GL_MAX_FRAGMENT_UNIFORM_VECTORS: - glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, params); *num_written = 1; - *params /= 4; + if (params) { + glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, params); + *params /= 4; + } return true; case GL_MAX_VARYING_VECTORS: - glGetIntegerv(GL_MAX_VARYING_FLOATS, params); *num_written = 1; - *params /= 4; + if (params) { + glGetIntegerv(GL_MAX_VARYING_FLOATS, params); + *params /= 4; + } return true; case GL_MAX_VERTEX_UNIFORM_VECTORS: - glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, params); *num_written = 1; - *params /= 4; + if (params) { + glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, params); + *params /= 4; + } return true; #endif case GL_COMPRESSED_TEXTURE_FORMATS: @@ -1978,76 +1991,94 @@ bool GLES2DecoderImpl::GetHelper( return true; case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *num_written = 1; - *params = 0; // We don't support compressed textures. + if (params) { + *params = 0; // We don't support compressed textures. + } return true; case GL_NUM_SHADER_BINARY_FORMATS: *num_written = 1; - *params = 0; // We don't support binary shader formats. + if (params) { + *params = 0; // We don't support binary shader formats. + } return true; case GL_SHADER_BINARY_FORMATS: *num_written = 0; return true; // We don't support binary shader format.s case GL_SHADER_COMPILER: *num_written = 1; - *params = GL_TRUE; + if (params) { + *params = GL_TRUE; + } return true; case GL_ARRAY_BUFFER_BINDING: *num_written = 1; - if (bound_array_buffer_) { - GLuint client_id = 0; - buffer_manager()->GetClientId(bound_array_buffer_->service_id(), - &client_id); - *params = client_id; - } else { - *params = 0; + if (params) { + if (bound_array_buffer_) { + GLuint client_id = 0; + buffer_manager()->GetClientId(bound_array_buffer_->service_id(), + &client_id); + *params = client_id; + } else { + *params = 0; + } } return true; case GL_ELEMENT_ARRAY_BUFFER_BINDING: *num_written = 1; - if (bound_element_array_buffer_) { - GLuint client_id = 0; - buffer_manager()->GetClientId(bound_element_array_buffer_->service_id(), - &client_id); - *params = client_id; - } else { - *params = 0; + if (params) { + if (bound_element_array_buffer_) { + GLuint client_id = 0; + buffer_manager()->GetClientId( + bound_element_array_buffer_->service_id(), + &client_id); + *params = client_id; + } else { + *params = 0; + } } return true; case GL_FRAMEBUFFER_BINDING: *num_written = 1; - if (bound_framebuffer_) { - GLuint client_id = 0; - framebuffer_manager()->GetClientId( - bound_framebuffer_->service_id(), &client_id); - *params = client_id; - } else { - *params = 0; + if (params) { + if (bound_framebuffer_) { + GLuint client_id = 0; + framebuffer_manager()->GetClientId( + bound_framebuffer_->service_id(), &client_id); + *params = client_id; + } else { + *params = 0; + } } return true; case GL_RENDERBUFFER_BINDING: *num_written = 1; - if (bound_renderbuffer_) { - GLuint client_id = 0; - renderbuffer_manager()->GetClientId( - bound_renderbuffer_->service_id(), &client_id); - *params = client_id; - } else { - *params = 0; + if (params) { + if (bound_renderbuffer_) { + GLuint client_id = 0; + renderbuffer_manager()->GetClientId( + bound_renderbuffer_->service_id(), &client_id); + *params = client_id; + } else { + *params = 0; + } } return true; case GL_CURRENT_PROGRAM: *num_written = 1; - if (current_program_) { - GLuint client_id = 0; - program_manager()->GetClientId( - current_program_->service_id(), &client_id); - *params = client_id; - } else { - *params = 0; + if (params) { + if (current_program_) { + GLuint client_id = 0; + program_manager()->GetClientId( + current_program_->service_id(), &client_id); + *params = client_id; + } else { + *params = 0; + } } return true; - case GL_TEXTURE_BINDING_2D: { - *num_written = 1; + case GL_TEXTURE_BINDING_2D: + *num_written = 1; + if (params) { TextureUnit& unit = texture_units_[active_texture_unit_]; if (unit.bound_texture_2d) { GLuint client_id = 0; @@ -2057,10 +2088,11 @@ bool GLES2DecoderImpl::GetHelper( } else { *params = 0; } - return true; } - case GL_TEXTURE_BINDING_CUBE_MAP: { - *num_written = 1; + return true; + case GL_TEXTURE_BINDING_CUBE_MAP: + *num_written = 1; + if (params) { TextureUnit& unit = texture_units_[active_texture_unit_]; if (unit.bound_texture_cube_map) { GLuint client_id = 0; @@ -2070,19 +2102,28 @@ bool GLES2DecoderImpl::GetHelper( } else { *params = 0; } - return true; } + return true; default: - return false; + *num_written = util_.GLGetNumValuesReturned(pname); + if (params) { + glGetIntegerv(pname, params); + } + return true; } } +bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet( + GLenum pname, GLsizei* num_values) { + return GetHelper(pname, NULL, num_values); +} + void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) { DCHECK(params); - GLint values[16]; - GLsizei num_written; - if (GetHelper(pname, &values[0], &num_written)) { - DCHECK_LE(static_cast<size_t>(num_written), arraysize(values)); + GLsizei num_written = 0; + if (GetHelper(pname, NULL, &num_written)) { + scoped_array<GLint> values(new GLint[num_written]); + GetHelper(pname, values.get(), &num_written); for (GLsizei ii = 0; ii < num_written; ++ii) { params[ii] = static_cast<GLboolean>(values[ii]); } @@ -2093,10 +2134,10 @@ void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) { void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) { DCHECK(params); - GLint values[16]; - GLsizei num_written; - if (GetHelper(pname, &values[0], &num_written)) { - DCHECK_LE(static_cast<size_t>(num_written), arraysize(values)); + GLsizei num_written = 0; + if (GetHelper(pname, NULL, &num_written)) { + scoped_array<GLint> values(new GLint[num_written]); + GetHelper(pname, values.get(), &num_written); for (GLsizei ii = 0; ii < num_written; ++ii) { params[ii] = static_cast<GLfloat>(values[ii]); } @@ -2722,10 +2763,6 @@ GLuint GLES2DecoderImpl::DoGetMaxValueInBuffer( // TODO(gman): Should this be a GL error or a command buffer error? SetGLError(GL_INVALID_VALUE, "GetMaxValueInBuffer: unknown buffer"); - } else if (info->target() != GL_ELEMENT_ARRAY_BUFFER) { - // TODO(gman): Should this be a GL error or a command buffer error? - SetGLError(GL_INVALID_OPERATION, - "GetMaxValueInBuffer: buffer not element array buffer"); } else { if (!info->GetMaxValueForRange(offset, count, type, &max_vertex_accessed)) { // TODO(gman): Should this be a GL error or a command buffer error? @@ -3352,7 +3389,7 @@ void GLES2DecoderImpl::DoBufferData( if (error != GL_NO_ERROR) { SetGLError(error, NULL); } else { - info->SetSize(size); + buffer_manager()->SetSize(info, size); info->SetRange(0, size, data); } } @@ -3744,6 +3781,7 @@ error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat( result->min_range = -31; result->max_range = 31; result->precision = 0; + break; case GL_LOW_FLOAT: case GL_MEDIUM_FLOAT: case GL_HIGH_FLOAT: @@ -3938,6 +3976,16 @@ error::Error GLES2DecoderImpl::HandleSwapBuffers( return error::kNoError; } +void GLES2DecoderImpl::DoCommandBufferEnable(GLenum pname, GLboolean enable) { + switch (pname) { + case GLES2_ALLOW_BUFFERS_ON_MULTIPLE_TARGETS: + buffer_manager()->set_allow_buffers_on_multiple_targets(enable != 0); + break; + default: + break; + } +} + // 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_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 29e6c52..f7e9c87 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -944,11 +944,7 @@ error::Error GLES2DecoderImpl::HandleGetBooleanv( uint32 immediate_data_size, const gles2::GetBooleanv& c) { GLenum pname = static_cast<GLenum>(c.pname); typedef GetBooleanv::Result Result; - GLsizei num_values = util_.GLGetNumValuesReturned(pname); - if (num_values == 0) { - SetGLError(GL_INVALID_ENUM, "glGetBooleanv: invalid enum"); - return error::kNoError; - } + GLsizei num_values = GetNumValuesReturnedForGLGet(pname, &num_values); Result* result = GetSharedMemoryAs<Result*>( c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); GLboolean* params = result ? result->GetData() : NULL; @@ -979,11 +975,7 @@ error::Error GLES2DecoderImpl::HandleGetBufferParameteriv( GLenum target = static_cast<GLenum>(c.target); GLenum pname = static_cast<GLenum>(c.pname); typedef GetBufferParameteriv::Result Result; - GLsizei num_values = util_.GLGetNumValuesReturned(pname); - if (num_values == 0) { - SetGLError(GL_INVALID_ENUM, "glGetBufferParameteriv: invalid enum"); - return error::kNoError; - } + GLsizei num_values = GetNumValuesReturnedForGLGet(pname, &num_values); Result* result = GetSharedMemoryAs<Result*>( c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); GLint* params = result ? result->GetData() : NULL; @@ -1031,11 +1023,7 @@ error::Error GLES2DecoderImpl::HandleGetFloatv( uint32 immediate_data_size, const gles2::GetFloatv& c) { GLenum pname = static_cast<GLenum>(c.pname); typedef GetFloatv::Result Result; - GLsizei num_values = util_.GLGetNumValuesReturned(pname); - if (num_values == 0) { - SetGLError(GL_INVALID_ENUM, "glGetFloatv: invalid enum"); - return error::kNoError; - } + GLsizei num_values = GetNumValuesReturnedForGLGet(pname, &num_values); Result* result = GetSharedMemoryAs<Result*>( c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); GLfloat* params = result ? result->GetData() : NULL; @@ -1068,13 +1056,7 @@ error::Error GLES2DecoderImpl::HandleGetFramebufferAttachmentParameteriv( GLenum attachment = static_cast<GLenum>(c.attachment); GLenum pname = static_cast<GLenum>(c.pname); typedef GetFramebufferAttachmentParameteriv::Result Result; - GLsizei num_values = util_.GLGetNumValuesReturned(pname); - if (num_values == 0) { - SetGLError( - GL_INVALID_ENUM, - "glGetFramebufferAttachmentParameteriv: invalid enum"); - return error::kNoError; - } + GLsizei num_values = GetNumValuesReturnedForGLGet(pname, &num_values); Result* result = GetSharedMemoryAs<Result*>( c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); GLint* params = result ? result->GetData() : NULL; @@ -1118,11 +1100,7 @@ error::Error GLES2DecoderImpl::HandleGetIntegerv( uint32 immediate_data_size, const gles2::GetIntegerv& c) { GLenum pname = static_cast<GLenum>(c.pname); typedef GetIntegerv::Result Result; - GLsizei num_values = util_.GLGetNumValuesReturned(pname); - if (num_values == 0) { - SetGLError(GL_INVALID_ENUM, "glGetIntegerv: invalid enum"); - return error::kNoError; - } + GLsizei num_values = GetNumValuesReturnedForGLGet(pname, &num_values); Result* result = GetSharedMemoryAs<Result*>( c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); GLint* params = result ? result->GetData() : NULL; @@ -1153,11 +1131,7 @@ error::Error GLES2DecoderImpl::HandleGetProgramiv( GLuint program = c.program; GLenum pname = static_cast<GLenum>(c.pname); typedef GetProgramiv::Result Result; - GLsizei num_values = util_.GLGetNumValuesReturned(pname); - if (num_values == 0) { - SetGLError(GL_INVALID_ENUM, "glGetProgramiv: invalid enum"); - return error::kNoError; - } + GLsizei num_values = GetNumValuesReturnedForGLGet(pname, &num_values); Result* result = GetSharedMemoryAs<Result*>( c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); GLint* params = result ? result->GetData() : NULL; @@ -1188,11 +1162,7 @@ error::Error GLES2DecoderImpl::HandleGetRenderbufferParameteriv( GLenum target = static_cast<GLenum>(c.target); GLenum pname = static_cast<GLenum>(c.pname); typedef GetRenderbufferParameteriv::Result Result; - GLsizei num_values = util_.GLGetNumValuesReturned(pname); - if (num_values == 0) { - SetGLError(GL_INVALID_ENUM, "glGetRenderbufferParameteriv: invalid enum"); - return error::kNoError; - } + GLsizei num_values = GetNumValuesReturnedForGLGet(pname, &num_values); Result* result = GetSharedMemoryAs<Result*>( c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); GLint* params = result ? result->GetData() : NULL; @@ -1231,11 +1201,7 @@ error::Error GLES2DecoderImpl::HandleGetShaderiv( GLuint shader = c.shader; GLenum pname = static_cast<GLenum>(c.pname); typedef GetShaderiv::Result Result; - GLsizei num_values = util_.GLGetNumValuesReturned(pname); - if (num_values == 0) { - SetGLError(GL_INVALID_ENUM, "glGetShaderiv: invalid enum"); - return error::kNoError; - } + GLsizei num_values = GetNumValuesReturnedForGLGet(pname, &num_values); Result* result = GetSharedMemoryAs<Result*>( c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); GLint* params = result ? result->GetData() : NULL; @@ -1266,11 +1232,7 @@ error::Error GLES2DecoderImpl::HandleGetTexParameterfv( GLenum target = static_cast<GLenum>(c.target); GLenum pname = static_cast<GLenum>(c.pname); typedef GetTexParameterfv::Result Result; - GLsizei num_values = util_.GLGetNumValuesReturned(pname); - if (num_values == 0) { - SetGLError(GL_INVALID_ENUM, "glGetTexParameterfv: invalid enum"); - return error::kNoError; - } + GLsizei num_values = GetNumValuesReturnedForGLGet(pname, &num_values); Result* result = GetSharedMemoryAs<Result*>( c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); GLfloat* params = result ? result->GetData() : NULL; @@ -1305,11 +1267,7 @@ error::Error GLES2DecoderImpl::HandleGetTexParameteriv( GLenum target = static_cast<GLenum>(c.target); GLenum pname = static_cast<GLenum>(c.pname); typedef GetTexParameteriv::Result Result; - GLsizei num_values = util_.GLGetNumValuesReturned(pname); - if (num_values == 0) { - SetGLError(GL_INVALID_ENUM, "glGetTexParameteriv: invalid enum"); - return error::kNoError; - } + GLsizei num_values = GetNumValuesReturnedForGLGet(pname, &num_values); Result* result = GetSharedMemoryAs<Result*>( c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); GLint* params = result ? result->GetData() : NULL; @@ -1344,11 +1302,7 @@ error::Error GLES2DecoderImpl::HandleGetVertexAttribfv( GLuint index = static_cast<GLuint>(c.index); GLenum pname = static_cast<GLenum>(c.pname); typedef GetVertexAttribfv::Result Result; - GLsizei num_values = util_.GLGetNumValuesReturned(pname); - if (num_values == 0) { - SetGLError(GL_INVALID_ENUM, "glGetVertexAttribfv: invalid enum"); - return error::kNoError; - } + GLsizei num_values = GetNumValuesReturnedForGLGet(pname, &num_values); Result* result = GetSharedMemoryAs<Result*>( c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); GLfloat* params = result ? result->GetData() : NULL; @@ -1379,11 +1333,7 @@ error::Error GLES2DecoderImpl::HandleGetVertexAttribiv( GLuint index = static_cast<GLuint>(c.index); GLenum pname = static_cast<GLenum>(c.pname); typedef GetVertexAttribiv::Result Result; - GLsizei num_values = util_.GLGetNumValuesReturned(pname); - if (num_values == 0) { - SetGLError(GL_INVALID_ENUM, "glGetVertexAttribiv: invalid enum"); - return error::kNoError; - } + GLsizei num_values = GetNumValuesReturnedForGLGet(pname, &num_values); Result* result = GetSharedMemoryAs<Result*>( c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values)); GLint* params = result ? result->GetData() : NULL; @@ -2771,5 +2721,17 @@ error::Error GLES2DecoderImpl::HandleGetMaxValueInBuffer( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleCommandBufferEnable( + uint32 immediate_data_size, const gles2::CommandBufferEnable& c) { + GLenum cap = static_cast<GLenum>(c.cap); + GLboolean enable = static_cast<GLboolean>(c.enable); + if (!ValidateGLenumCommandBufferState(cap)) { + SetGLError(GL_INVALID_ENUM, "glCommandBufferEnable: cap GL_INVALID_ENUM"); + return error::kNoError; + } + DoCommandBufferEnable(cap, enable); + return error::kNoError; +} + #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_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 ede9af9..2fd1b54 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 @@ -1096,7 +1096,7 @@ TEST_F(GLES2DecoderTest1, GetBooleanvValidArgs) { SpecializedSetup<GetBooleanv, 0>(); typedef GetBooleanv::Result Result; Result* result = static_cast<Result*>(shared_memory_address_); - EXPECT_CALL(*gl_, GetBooleanv(GL_ACTIVE_TEXTURE, result->GetData())); + EXPECT_CALL(*gl_, GetIntegerv(GL_ACTIVE_TEXTURE, _)); result->size = 0; GetBooleanv cmd; cmd.Init(GL_ACTIVE_TEXTURE, shared_memory_id_, shared_memory_offset_); @@ -1108,7 +1108,7 @@ TEST_F(GLES2DecoderTest1, GetBooleanvValidArgs) { } TEST_F(GLES2DecoderTest1, GetBooleanvInvalidArgs0_0) { - EXPECT_CALL(*gl_, GetBooleanv(_, _)).Times(0); + EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0); SpecializedSetup<GetBooleanv, 0>(); GetBooleanv::Result* result = static_cast<GetBooleanv::Result*>(shared_memory_address_); @@ -1121,7 +1121,7 @@ TEST_F(GLES2DecoderTest1, GetBooleanvInvalidArgs0_0) { } TEST_F(GLES2DecoderTest1, GetBooleanvInvalidArgs1_0) { - EXPECT_CALL(*gl_, GetBooleanv(_, _)).Times(0); + EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0); SpecializedSetup<GetBooleanv, 0>(); GetBooleanv::Result* result = static_cast<GetBooleanv::Result*>(shared_memory_address_); @@ -1133,7 +1133,7 @@ TEST_F(GLES2DecoderTest1, GetBooleanvInvalidArgs1_0) { } TEST_F(GLES2DecoderTest1, GetBooleanvInvalidArgs1_1) { - EXPECT_CALL(*gl_, GetBooleanv(_, _)).Times(0); + EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0); SpecializedSetup<GetBooleanv, 0>(); GetBooleanv::Result* result = static_cast<GetBooleanv::Result*>(shared_memory_address_); @@ -1250,7 +1250,7 @@ TEST_F(GLES2DecoderTest1, GetFloatvValidArgs) { SpecializedSetup<GetFloatv, 0>(); typedef GetFloatv::Result Result; Result* result = static_cast<Result*>(shared_memory_address_); - EXPECT_CALL(*gl_, GetFloatv(GL_ACTIVE_TEXTURE, result->GetData())); + EXPECT_CALL(*gl_, GetIntegerv(GL_ACTIVE_TEXTURE, _)); result->size = 0; GetFloatv cmd; cmd.Init(GL_ACTIVE_TEXTURE, shared_memory_id_, shared_memory_offset_); @@ -1262,7 +1262,7 @@ TEST_F(GLES2DecoderTest1, GetFloatvValidArgs) { } TEST_F(GLES2DecoderTest1, GetFloatvInvalidArgs0_0) { - EXPECT_CALL(*gl_, GetFloatv(_, _)).Times(0); + EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0); SpecializedSetup<GetFloatv, 0>(); GetFloatv::Result* result = static_cast<GetFloatv::Result*>(shared_memory_address_); @@ -1275,7 +1275,7 @@ TEST_F(GLES2DecoderTest1, GetFloatvInvalidArgs0_0) { } TEST_F(GLES2DecoderTest1, GetFloatvInvalidArgs1_0) { - EXPECT_CALL(*gl_, GetFloatv(_, _)).Times(0); + EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0); SpecializedSetup<GetFloatv, 0>(); GetFloatv::Result* result = static_cast<GetFloatv::Result*>(shared_memory_address_); @@ -1287,7 +1287,7 @@ TEST_F(GLES2DecoderTest1, GetFloatvInvalidArgs1_0) { } TEST_F(GLES2DecoderTest1, GetFloatvInvalidArgs1_1) { - EXPECT_CALL(*gl_, GetFloatv(_, _)).Times(0); + EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0); SpecializedSetup<GetFloatv, 0>(); GetFloatv::Result* result = static_cast<GetFloatv::Result*>(shared_memory_address_); @@ -1821,5 +1821,7 @@ TEST_F(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_1) { // TODO(gman): GetUniformLocation +// TODO(gman): GetUniformLocationImmediate + #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_1_AUTOGEN_H_ 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 6bc3097..a7453ca 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 @@ -8,8 +8,6 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ -// TODO(gman): GetUniformLocationImmediate - // TODO(gman): GetUniformLocationBucket @@ -1626,5 +1624,13 @@ TEST_F(GLES2DecoderTest2, ViewportInvalidArgs3_0) { // TODO(gman): RegisterSharedIds + +TEST_F(GLES2DecoderTest2, CommandBufferEnableValidArgs) { + SpecializedSetup<CommandBufferEnable, 0>(); + CommandBufferEnable cmd; + cmd.Init(GLES2_ALLOW_BUFFERS_ON_MULTIPLE_TARGETS, 2); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h index 8920f31..b7781b6 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -18,6 +18,7 @@ #include "gpu/command_buffer/service/renderbuffer_manager.h" #include "gpu/command_buffer/service/shader_manager.h" #include "gpu/command_buffer/service/texture_manager.h" +#include "gpu/GLES2/gles2_command_buffer.h" #include "testing/gtest/include/gtest/gtest.h" namespace gpu { diff --git a/gpu/command_buffer/service/gles2_cmd_validation.cc b/gpu/command_buffer/service/gles2_cmd_validation.cc index d5359b3..19af905 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation.cc +++ b/gpu/command_buffer/service/gles2_cmd_validation.cc @@ -9,6 +9,7 @@ // some of the GLenum definitions exist only in GLES2 and not in Desktop // GL. #include <GLES2/gl2types.h> +#include <GLES2/gles2_command_buffer.h> namespace gpu { namespace gles2 { diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h index 203c6cb8..c7ec2aa 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h @@ -13,6 +13,7 @@ bool ValidateGLenumBufferTarget(GLenum value); bool ValidateGLenumBufferUsage(GLenum value); bool ValidateGLenumCapability(GLenum value); bool ValidateGLenumCmpFunction(GLenum value); +bool ValidateGLenumCommandBufferState(GLenum value); bool ValidateGLenumDrawMode(GLenum value); bool ValidateGLenumDstBlendFactor(GLenum value); bool ValidateGLenumEquation(GLenum value); diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h index eb09130..6f3b56c 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h @@ -82,6 +82,15 @@ bool ValidateGLenumCmpFunction(GLenum value) { } } +bool ValidateGLenumCommandBufferState(GLenum value) { + switch (value) { + case GLES2_ALLOW_BUFFERS_ON_MULTIPLE_TARGETS: + return true; + default: + return false; + } +} + bool ValidateGLenumDrawMode(GLenum value) { switch (value) { case GL_POINTS: |