summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-07 23:35:31 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-07 23:35:31 +0000
commit9e64440a70e0a18ff5b6edcbf10652feb2954b39 (patch)
treec2012f5a29786e7dfd2cdd638bc7f0c1e6da2083 /gpu/command_buffer
parent891ca0f165421a6d748df275058832d2e9ebecab (diff)
downloadchromium_src-9e64440a70e0a18ff5b6edcbf10652feb2954b39.zip
chromium_src-9e64440a70e0a18ff5b6edcbf10652feb2954b39.tar.gz
chromium_src-9e64440a70e0a18ff5b6edcbf10652feb2954b39.tar.bz2
This CL adds the option to support buffers that are bound
to more than one target. We had originally decided that this would be an disallowed. glBindBuffer(GL_ARRAY_BUFFER, some_buffer_id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, some_buffer_id); Unfortunately the GLES2 conformance tests require this behavior. This CL makes this behavior possible but it has to be turned on because it means all buffers have to have CPU side backing (not just ELEMENT_ARRAY_BUFFERs) and it means a slowdown for dynamic vertex related stuff like skinning because an extra copy has to be made every time they are updated. So, by default it will be off but we'll come up with some way to turn it on. Al's suggestion is to use eglCreateContext with a custom intialization attribute. My #1 question: What about the name of the command, the name of the constant and the filename the constant is in. Any thoughts? TEST=none BUG=none Review URL: http://codereview.chromium.org/1992008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46756 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer')
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py53
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h3
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper_autogen.h5
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc4
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h32
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_autogen.h38
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_test_autogen.h15
-rw-r--r--gpu/command_buffer/common/gles2_cmd_id_test_autogen.h2
-rw-r--r--gpu/command_buffer/common/gles2_cmd_ids_autogen.h1
-rw-r--r--gpu/command_buffer/docs/gles2_cmd_format_docs.txt8
-rw-r--r--gpu/command_buffer/service/buffer_manager.cc33
-rw-r--r--gpu/command_buffer/service/buffer_manager.h52
-rw-r--r--gpu/command_buffer/service/buffer_manager_unittest.cc28
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc177
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h86
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h2
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h10
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation.cc1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation_autogen.h1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h9
21 files changed, 385 insertions, 176 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 9b90b38..a4f4588 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'},
@@ -2296,6 +2307,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 +2321,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 +2674,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 +2813,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;
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..f3eaaae 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,93 @@ 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 +2087,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,13 +2101,22 @@ 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];
@@ -2722,10 +2762,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 +3388,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 +3780,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 +3975,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..718a6ca 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
@@ -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: