diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-05 05:16:23 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-05 05:16:23 +0000 |
commit | 3b6ec20aec909735d1f8b69c1088f256fe36c2a4 (patch) | |
tree | 39042b6f8402b8b7aac4d8bb6a2a8f565fd137ca /gpu/command_buffer | |
parent | a6eb5232d2608cd0773bbe559757bd52c7f53670 (diff) | |
download | chromium_src-3b6ec20aec909735d1f8b69c1088f256fe36c2a4.zip chromium_src-3b6ec20aec909735d1f8b69c1088f256fe36c2a4.tar.gz chromium_src-3b6ec20aec909735d1f8b69c1088f256fe36c2a4.tar.bz2 |
Reverting previous CL.
Sure would be nice if the trybots actually worked
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/668136
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40715 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer')
-rwxr-xr-x | gpu/command_buffer/build_gles2_cmd_buffer.py | 99 | ||||
-rw-r--r-- | gpu/command_buffer/common/gles2_cmd_utils.h | 5 | ||||
-rw-r--r-- | gpu/command_buffer/service/buffer_manager.cc | 95 | ||||
-rw-r--r-- | gpu/command_buffer/service/buffer_manager.h | 79 | ||||
-rw-r--r-- | gpu/command_buffer/service/buffer_manager_unittest.cc | 83 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 112 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_autogen.h | 4 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc | 47 |
8 files changed, 117 insertions, 407 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index af2f9b0..36dd9dd 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -849,7 +849,7 @@ _FUNCTION_INFO = { 'BindRenderbuffer': {'decoder_func': 'glBindRenderbufferEXT'}, 'BindTexture': {'decoder_func': 'DoBindTexture'}, 'BufferData': {'type': 'Manual', 'immediate': True}, - 'BufferSubData': {'type': 'Data', 'decoder_func': 'DoBufferSubData'}, + 'BufferSubData': {'type': 'Data'}, 'CheckFramebufferStatus': {'decoder_func': 'glCheckFramebufferStatusEXT'}, 'ClearDepthf': {'decoder_func': 'glClearDepth'}, 'CompileShader': {'decoder_func': 'DoCompileShader', 'unit_test': False}, @@ -1715,19 +1715,20 @@ class DataHandler(TypeHandler): name = func.name if name.endswith("Immediate"): name = name[0:-9] - if name == 'BufferData' or name == 'BufferSubData': + if name == 'BufferData': file.Write(" uint32 data_size = size;\n") - elif (name == 'CompressedTexImage2D' or - name == 'CompressedTexSubImage2D'): + elif name == 'BufferSubData': + file.Write(" uint32 data_size = size;\n") + elif name == 'CompressedTexImage2D': file.Write(" uint32 data_size = imageSize;\n") - elif name == 'TexImage2D' or name == 'TexSubImage2D': - code = """ uint32 data_size; - if (!GLES2Util::ComputeImageDataSize( - width, height, format, type, unpack_alignment_, &data_size)) { - return error::kOutOfBounds; - } -""" - file.Write(code) + elif name == 'CompressedTexSubImage2D': + file.Write(" uint32 data_size = imageSize;\n") + elif name == 'TexImage2D': + file.Write(" uint32 data_size = GLES2Util::ComputeImageDataSize(\n") + file.Write(" width, height, format, type, unpack_alignment_);\n") + elif name == 'TexSubImage2D': + file.Write(" uint32 data_size = GLES2Util::ComputeImageDataSize(\n") + file.Write(" width, height, format, type, unpack_alignment_);\n") else: file.Write("// uint32 data_size = 0; // TODO(gman): get correct size!\n") @@ -1818,12 +1819,7 @@ class GENnHandler(TypeHandler): def WriteGetDataSizeCode(self, func, file): """Overrriden from TypeHandler.""" - code = """ uint32 data_size; - if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { - return error::kOutOfBounds; - } -""" - file.Write(code) + file.Write(" uint32 data_size = n * sizeof(GLuint);\n") def WriteHandlerImplementation (self, func, file): """Overrriden from TypeHandler.""" @@ -2076,12 +2072,7 @@ class DELnHandler(TypeHandler): def WriteGetDataSizeCode(self, func, file): """Overrriden from TypeHandler.""" - code = """ uint32 data_size; - if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { - return error::kOutOfBounds; - } -""" - file.Write(code) + file.Write(" uint32 data_size = n * sizeof(GLuint);\n") def WriteServiceUnitTest(self, func, file): """Overrriden from TypeHandler.""" @@ -2292,17 +2283,11 @@ class GETnHandler(TypeHandler): for arg in all_but_last_args: arg.WriteGetCode(file) - code = """ - %(last_arg_type)s params; - GLsizei num_values = util_.GLGetNumValuesReturned(pname); - uint32 params_size; - if (!SafeMultiplyUint32(num_values, sizeof(*params), ¶ms_size)) { - return error::kOutOfBounds; - } - params = GetSharedMemoryAs<%(last_arg_type)s>( - c.params_shm_id, c.params_shm_offset, params_size); -""" - file.Write(code % {'last_arg_type': last_arg.type}) + file.Write(" %s params;\n" % last_arg.type) + file.Write(" GLsizei num_values = util_.GLGetNumValuesReturned(pname);\n") + file.Write(" uint32 params_size = num_values * sizeof(*params);\n") + file.Write(" params = GetSharedMemoryAs<%s>(\n" % last_arg.type) + file.Write(" c.params_shm_id, c.params_shm_offset, params_size);\n") func.WriteHandlerValidation(file) func.WriteHandlerImplementation(file) file.Write(" return error::kNoError;\n") @@ -2381,16 +2366,9 @@ TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { def WriteGetDataSizeCode(self, func, file): """Overrriden from TypeHandler.""" - code = """ uint32 data_size; - if (!ComputeDataSize(1, sizeof(%s), %d, &data_size)) { - return error::kOutOfBounds; - } -""" - file.Write(code % (func.info.data_type, func.info.count)) - if func.is_immediate: - file.Write(" if (data_size > immediate_data_size) {\n") - file.Write(" return error::kOutOfBounds;\n") - file.Write(" }\n") + file.Write(" uint32 data_size = ComputeImmediateDataSize(" + "immediate_data_size, 1, sizeof(%s), %d);\n" % + (func.info.data_type, func.info.count)) def WriteGLES2ImplementationHeader(self, func, file): """Overrriden from TypeHandler.""" @@ -2559,16 +2537,9 @@ TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { def WriteGetDataSizeCode(self, func, file): """Overrriden from TypeHandler.""" - code = """ uint32 data_size; - if (!ComputeDataSize(1, sizeof(%s), %d, &data_size)) { - return error::kOutOfBounds; - } -""" - file.Write(code % (func.info.data_type, func.info.count)) - if func.is_immediate: - file.Write(" if (data_size > immediate_data_size) {\n") - file.Write(" return error::kOutOfBounds;\n") - file.Write(" }\n") + file.Write(" uint32 data_size = ComputeImmediateDataSize(" + "immediate_data_size, 1, sizeof(%s), %d);\n" % + (func.info.data_type, func.info.count)) def WriteGLES2ImplementationHeader(self, func, file): """Overrriden from TypeHandler.""" @@ -3154,17 +3125,15 @@ class STRnHandler(TypeHandler): code = """%(return_type)s %(func_name)s(%(args)s) { helper_->SetBucketSize(kResultBucketId, 0); helper_->%(func_name)s(%(id_name)s, kResultBucketId); - if (bufsize > 0) { - std::string str; - if (GetBucketAsString(kResultBucketId, &str)) { - GLsizei max_size = - std::min(static_cast<size_t>(%(bufsize_name)s) - 1, str.size()); - if (%(length_name)s != NULL) { - *%(length_name)s = max_size; - } - memcpy(%(dest_name)s, str.c_str(), max_size); - %(dest_name)s[max_size] = '\\0'; + std::string str; + if (GetBucketAsString(kResultBucketId, &str)) { + GLsizei max_size = + std::min(static_cast<size_t>(%(bufsize_name)s) - 1, str.size()); + if (%(length_name)s != NULL) { + *%(length_name)s = max_size; } + memcpy(%(dest_name)s, str.c_str(), max_size); + %(dest_name)s[max_size] = '\\0'; } } """ diff --git a/gpu/command_buffer/common/gles2_cmd_utils.h b/gpu/command_buffer/common/gles2_cmd_utils.h index 318d2d8..c5cd792 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils.h +++ b/gpu/command_buffer/common/gles2_cmd_utils.h @@ -18,13 +18,12 @@ namespace gles2 { // returns true. template <typename T> inline bool SafeMultiply(T a, T b, T* dst) { + *dst = 0; if (b == 0) { - *dst = 0; return true; } T v = a * b; if (v / b != a) { - *dst = 0; return false; } *dst = v; @@ -39,8 +38,8 @@ inline bool SafeMultiplyUint32(uint32 a, uint32 b, uint32* dst) { // Does an add checking for overflow. If there was no overflow returns true. template <typename T> inline bool SafeAdd(T a, T b, T* dst) { + *dst = 0; if (a + b < a) { - *dst = 0; return false; } *dst = a + b; diff --git a/gpu/command_buffer/service/buffer_manager.cc b/gpu/command_buffer/service/buffer_manager.cc index 9b58e42..2dfbc15 100644 --- a/gpu/command_buffer/service/buffer_manager.cc +++ b/gpu/command_buffer/service/buffer_manager.cc @@ -4,7 +4,6 @@ #include "gpu/command_buffer/service/buffer_manager.h" #include "base/logging.h" -#include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" namespace gpu { @@ -32,96 +31,10 @@ void BufferManager::RemoveBufferInfo(GLuint buffer_id) { } } -void BufferManager::BufferInfo::SetSize(GLsizeiptr size) { - DCHECK(!IsDeleted()); - if (size != size_) { - size_ = size; - ClearCache(); - if (target_ == GL_ELEMENT_ARRAY_BUFFER) { - shadow_.reset(new int8[size]); - memset(shadow_.get(), 0, size); - } - } -} - -bool BufferManager::BufferInfo::SetRange( - GLintptr offset, GLsizeiptr size, const GLvoid * data) { - DCHECK(!IsDeleted()); - if (offset + size < offset || - offset + size > size_) { - return false; - } - if (target_ == GL_ELEMENT_ARRAY_BUFFER) { - memcpy(shadow_.get() + offset, data, size); - ClearCache(); - } - return true; -} - -void BufferManager::BufferInfo::ClearCache() { - range_set_.clear(); -} - -template <typename T> -GLuint GetMaxValue(const void* data, GLuint offset, GLsizei count) { - GLuint max_value = 0; - const T* element = reinterpret_cast<const T*>( - static_cast<const int8*>(data) + offset); - const T* end = element + count; - for (; element < end; ++element) { - if (*element > max_value) { - max_value = *element; - } - } - return max_value; -} - -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); - if (it != range_set_.end()) { - *max_value = it->second; - return true; - } - - uint32 size; - if (!SafeMultiplyUint32( - count, GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type), &size)) { - return false; - } - - if (!SafeAddUint32(offset, size, &size)) { - return false; - } - - if (size > static_cast<uint32>(size_)) { - return false; - } - - // Scan the range for the max value and store - GLuint max_v = 0; - switch (type) { - case GL_UNSIGNED_BYTE: - max_v = GetMaxValue<uint8>(shadow_.get(), offset, count); - break; - case GL_UNSIGNED_SHORT: - // Check we are not accessing an odd byte for a 2 byte value. - if ((offset & 1) != 0) { - return false; - } - max_v = GetMaxValue<uint16>(shadow_.get(), offset, count); - break; - default: - NOTREACHED(); // should never get here by validation. - break; - } - std::pair<RangeToMaxValueMap::iterator, bool> result = - range_set_.insert(std::make_pair(range, max_v)); - *max_value = max_v; - return true; +GLuint BufferManager::BufferInfo::GetMaxValueForRange( + GLuint offset, GLsizei count, GLenum type) { + // TODO(gman): Scan the values in the given range and cache their results. + return 0u; } } // namespace gles2 diff --git a/gpu/command_buffer/service/buffer_manager.h b/gpu/command_buffer/service/buffer_manager.h index 4afdaa0..e278a85 100644 --- a/gpu/command_buffer/service/buffer_manager.h +++ b/gpu/command_buffer/service/buffer_manager.h @@ -7,9 +7,7 @@ #include <map> #include "base/basictypes.h" -#include "base/logging.h" #include "base/ref_counted.h" -#include "base/scoped_ptr.h" #include "gpu/command_buffer/service/gl_utils.h" namespace gpu { @@ -29,7 +27,6 @@ class BufferManager { explicit BufferInfo(GLuint buffer_id) : buffer_id_(buffer_id), - target_(0), size_(0) { } @@ -37,32 +34,17 @@ class BufferManager { return buffer_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( - GLintptr offset, GLsizeiptr size, const GLvoid * data); + void set_size(GLsizeiptr size) { + size_ = size; + } - // Gets the maximum value in the buffer for the given range interpreted as - // the given type. Returns false if offset and count are out of range. - // offset is in bytes. - // count is in elements of type. - bool GetMaxValueForRange(GLuint offset, GLsizei count, GLenum type, - GLuint* max_value); + // Returns the maximum value in the buffer for the given range + // interpreted as the given type. + GLuint GetMaxValueForRange(GLuint offset, GLsizei count, GLenum type); bool IsDeleted() { return buffer_id_ == 0; @@ -72,63 +54,14 @@ class BufferManager { friend class BufferManager; friend class base::RefCounted<BufferInfo>; - // Represents a range in a buffer. - class Range { - public: - Range(GLuint offset, GLsizei count, GLenum type) - : offset_(offset), - count_(count), - type_(type) { - } - - // A less functor provided for std::map so it can find ranges. - struct Less { - bool operator() (const Range& lhs, const Range& rhs) { - if (lhs.offset_ != rhs.offset_) { - return lhs.offset_ < rhs.offset_; - } - if (lhs.count_ != rhs.count_) { - return lhs.count_ < rhs.count_; - } - return lhs.type_ < rhs.type_; - } - }; - - private: - GLuint offset_; - GLsizei count_; - GLenum type_; - }; - ~BufferInfo() { } void MarkAsDeleted() { buffer_id_ = 0; - shadow_.reset(); - ClearCache(); } - // Clears any cache of index ranges. - void ClearCache(); - - // Service side buffer id. GLuint buffer_id_; - - // The type of buffer. 0 = unset, GL_BUFFER_ARRAY = vertex data, - // GL_ELEMENT_BUFFER_ARRAY = index data. - // Once set a buffer can not be used for something else. - GLenum target_; - - // Size of buffer. GLsizeiptr size_; - - // A copy of the data in the buffer. This data is only kept if the target - // is GL_ELEMENT_BUFFER_ARRAY - scoped_array<int8> shadow_; - - // A map of ranges to the highest value in that range of a certain type. - typedef std::map<Range, GLuint, Range::Less> RangeToMaxValueMap; - RangeToMaxValueMap range_set_; }; BufferManager() { } diff --git a/gpu/command_buffer/service/buffer_manager_unittest.cc b/gpu/command_buffer/service/buffer_manager_unittest.cc index df58915..2b121d8 100644 --- a/gpu/command_buffer/service/buffer_manager_unittest.cc +++ b/gpu/command_buffer/service/buffer_manager_unittest.cc @@ -32,14 +32,8 @@ TEST_F(BufferManagerTest, Basic) { // Check buffer got created. BufferManager::BufferInfo* info1 = manager_.GetBufferInfo(kBuffer1Id); ASSERT_TRUE(info1 != NULL); - EXPECT_EQ(0u, info1->target()); - EXPECT_EQ(0, info1->size()); - EXPECT_FALSE(info1->IsDeleted()); - EXPECT_EQ(kBuffer1Id, info1->buffer_id()); - info1->set_target(GL_ELEMENT_ARRAY_BUFFER); - EXPECT_EQ(GL_ELEMENT_ARRAY_BUFFER, info1->target()); // Check we and set its size. - info1->SetSize(kBuffer1Size); + info1->set_size(kBuffer1Size); EXPECT_EQ(kBuffer1Size, info1->size()); // Check we get nothing for a non-existent buffer. EXPECT_TRUE(manager_.GetBufferInfo(kBuffer2Id) == NULL); @@ -50,80 +44,7 @@ TEST_F(BufferManagerTest, Basic) { EXPECT_TRUE(manager_.GetBufferInfo(kBuffer1Id) == NULL); } -TEST_F(BufferManagerTest, SetRange) { - const GLuint kBufferId = 1; - const uint8 data[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; - const uint8 new_data[] = {100, 120, 110}; - manager_.CreateBufferInfo(kBufferId); - BufferManager::BufferInfo* info = manager_.GetBufferInfo(kBufferId); - ASSERT_TRUE(info != NULL); - info->set_target(GL_ELEMENT_ARRAY_BUFFER); - info->SetSize(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)); - EXPECT_FALSE(info->SetRange(0, sizeof(data) + 1, data)); -} - -TEST_F(BufferManagerTest, GetMaxValueForRangeUint8) { - const GLuint kBufferId = 1; - const uint8 data[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; - const uint8 new_data[] = {100, 120, 110}; - manager_.CreateBufferInfo(kBufferId); - BufferManager::BufferInfo* info = manager_.GetBufferInfo(kBufferId); - ASSERT_TRUE(info != NULL); - info->set_target(GL_ELEMENT_ARRAY_BUFFER); - info->SetSize(sizeof(data)); - EXPECT_TRUE(info->SetRange(0, sizeof(data), data)); - GLuint max_value; - // Check entire range succeeds. - EXPECT_TRUE(info->GetMaxValueForRange(0, 10, GL_UNSIGNED_BYTE, &max_value)); - EXPECT_EQ(10u, max_value); - // Check sub range succeeds. - EXPECT_TRUE(info->GetMaxValueForRange(4, 3, GL_UNSIGNED_BYTE, &max_value)); - EXPECT_EQ(6u, max_value); - // Check changing sub range succeeds. - EXPECT_TRUE(info->SetRange(4, sizeof(new_data), new_data)); - EXPECT_TRUE(info->GetMaxValueForRange(4, 3, GL_UNSIGNED_BYTE, &max_value)); - EXPECT_EQ(120u, max_value); - max_value = 0; - EXPECT_TRUE(info->GetMaxValueForRange(0, 10, GL_UNSIGNED_BYTE, &max_value)); - EXPECT_EQ(120u, max_value); - // Check out of range fails. - EXPECT_FALSE(info->GetMaxValueForRange(0, 11, GL_UNSIGNED_BYTE, &max_value)); - EXPECT_FALSE(info->GetMaxValueForRange(10, 1, GL_UNSIGNED_BYTE, &max_value)); -} - -TEST_F(BufferManagerTest, GetMaxValueForRangeUint16) { - const GLuint kBufferId = 1; - const uint16 data[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; - const uint16 new_data[] = {100, 120, 110}; - manager_.CreateBufferInfo(kBufferId); - BufferManager::BufferInfo* info = manager_.GetBufferInfo(kBufferId); - ASSERT_TRUE(info != NULL); - info->set_target(GL_ELEMENT_ARRAY_BUFFER); - info->SetSize(sizeof(data)); - EXPECT_TRUE(info->SetRange(0, sizeof(data), data)); - GLuint max_value; - // Check entire range succeeds. - EXPECT_TRUE(info->GetMaxValueForRange(0, 10, GL_UNSIGNED_SHORT, &max_value)); - EXPECT_EQ(10u, max_value); - // Check odd offset fails for GL_UNSIGNED_SHORT. - EXPECT_FALSE(info->GetMaxValueForRange(1, 10, GL_UNSIGNED_SHORT, &max_value)); - // Check sub range succeeds. - EXPECT_TRUE(info->GetMaxValueForRange(8, 3, GL_UNSIGNED_SHORT, &max_value)); - EXPECT_EQ(6u, max_value); - // Check changing sub range succeeds. - EXPECT_TRUE(info->SetRange(8, sizeof(new_data), new_data)); - EXPECT_TRUE(info->GetMaxValueForRange(8, 3, GL_UNSIGNED_SHORT, &max_value)); - EXPECT_EQ(120u, max_value); - max_value = 0; - EXPECT_TRUE(info->GetMaxValueForRange(0, 10, GL_UNSIGNED_SHORT, &max_value)); - EXPECT_EQ(120u, max_value); - // Check out of range fails. - EXPECT_FALSE(info->GetMaxValueForRange(0, 11, GL_UNSIGNED_SHORT, &max_value)); - EXPECT_FALSE(info->GetMaxValueForRange(20, 1, GL_UNSIGNED_SHORT, &max_value)); -} +// TODO(gman): Test GetMaxValueForRange. } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index dbb49e9..54cef89 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -434,14 +434,6 @@ class GLES2DecoderImpl : public GLES2Decoder { // Wrapper for glBindTexture since we need to track the current targets. void DoBindTexture(GLenum target, GLuint texture); - // Wrapper for BufferData. - void DoBufferData( - GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage); - - // Wrapper for BufferSubData. - void DoBufferSubData( - GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data); - // Wrapper for glCompileShader. void DoCompileShader(GLuint shader); @@ -1511,15 +1503,10 @@ void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint buffer) { BufferManager::BufferInfo* info = NULL; if (buffer) { info = GetBufferInfo(buffer); - // Check the buffer exists - // Check that we are not trying to bind it to a different target. - if (!info || (info->target() != 0 && info->target() != target)) { + if (!info) { SetGLError(GL_INVALID_OPERATION); return; } - if (info->target() == 0) { - info->set_target(target); - } } switch (target) { case GL_ARRAY_BUFFER: @@ -1932,19 +1919,28 @@ error::Error GLES2DecoderImpl::HandleDrawElements( !ValidateGLenumIndexType(type)) { SetGLError(GL_INVALID_ENUM); } else { - GLuint max_vertex_accessed; - if (!bound_element_array_buffer_->GetMaxValueForRange( - offset, count, type, &max_vertex_accessed)) { + GLsizeiptr buffer_size = bound_element_array_buffer_->size(); + if (offset > buffer_size) { SetGLError(GL_INVALID_OPERATION); } else { - if (IsDrawValid(max_vertex_accessed)) { - bool has_non_renderable_textures; - SetBlackTextureForNonRenderableTextures( - &has_non_renderable_textures); + GLsizei usable_size = buffer_size - offset; + GLsizei num_elements = + usable_size / GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type); + if (count > num_elements) { + SetGLError(GL_INVALID_OPERATION); + } else { const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); - glDrawElements(mode, count, type, indices); - if (has_non_renderable_textures) { - RestoreStateForNonRenderableTextures(); + GLuint max_vertex_accessed = + bound_element_array_buffer_->GetMaxValueForRange( + offset, count, type); + if (IsDrawValid(max_vertex_accessed)) { + bool has_non_renderable_textures; + SetBlackTextureForNonRenderableTextures( + &has_non_renderable_textures); + glDrawElements(mode, count, type, indices); + if (has_non_renderable_textures) { + RestoreStateForNonRenderableTextures(); + } } } } @@ -2276,21 +2272,33 @@ error::Error GLES2DecoderImpl::HandleGetString( return error::kNoError; } -void GLES2DecoderImpl::DoBufferData( - GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) { +error::Error GLES2DecoderImpl::HandleBufferData( + uint32 immediate_data_size, const gles2::BufferData& c) { + GLenum target = static_cast<GLenum>(c.target); + GLsizeiptr size = static_cast<GLsizeiptr>(c.size); + uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); + uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); + GLenum usage = static_cast<GLenum>(c.usage); + const void* data = NULL; + if (data_shm_id != 0 || data_shm_offset != 0) { + data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size); + if (!data) { + return error::kOutOfBounds; + } + } if (!ValidateGLenumBufferTarget(target) || !ValidateGLenumBufferUsage(usage)) { SetGLError(GL_INVALID_ENUM); - return; + return error::kNoError; } if (size < 0) { SetGLError(GL_INVALID_VALUE); - DoBufferData(target, size, data, usage); + return error::kNoError; } BufferManager::BufferInfo* info = GetBufferInfoForTarget(target); if (!info) { SetGLError(GL_INVALID_OPERATION); - DoBufferData(target, size, data, usage); + return error::kNoError; } // Clear the buffer to 0 if no initial data was passed in. scoped_array<int8> zero; @@ -2305,26 +2313,8 @@ void GLES2DecoderImpl::DoBufferData( if (error != GL_NO_ERROR) { SetGLError(error); } else { - info->SetSize(size); - info->SetRange(0, size, data); + info->set_size(size); } -} - -error::Error GLES2DecoderImpl::HandleBufferData( - uint32 immediate_data_size, const gles2::BufferData& c) { - GLenum target = static_cast<GLenum>(c.target); - GLsizeiptr size = static_cast<GLsizeiptr>(c.size); - uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); - uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); - GLenum usage = static_cast<GLenum>(c.usage); - const void* data = NULL; - if (data_shm_id != 0 || data_shm_offset != 0) { - data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size); - if (!data) { - return error::kOutOfBounds; - } - } - DoBufferData(target, size, data, usage); return error::kNoError; } @@ -2338,21 +2328,29 @@ error::Error GLES2DecoderImpl::HandleBufferDataImmediate( return error::kOutOfBounds; } GLenum usage = static_cast<GLenum>(c.usage); - DoBufferData(target, size, data, usage); - return error::kNoError; -} - -void GLES2DecoderImpl::DoBufferSubData( - GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) { + if (!ValidateGLenumBufferTarget(target) || + !ValidateGLenumBufferUsage(usage)) { + SetGLError(GL_INVALID_ENUM); + return error::kNoError; + } + if (size < 0) { + SetGLError(GL_INVALID_VALUE); + return error::kNoError; + } BufferManager::BufferInfo* info = GetBufferInfoForTarget(target); if (!info) { SetGLError(GL_INVALID_OPERATION); + return error::kNoError; } - if (!info->SetRange(offset, size, data)) { - SetGLError(GL_INVALID_VALUE); + CopyRealGLErrorsToWrapper(); + glBufferData(target, size, data, usage); + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + SetGLError(error); } else { - glBufferSubData(target, offset, size, data); + info->set_size(size); } + return error::kNoError; } error::Error GLES2DecoderImpl::DoCompressedTexImage2D( diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index eb66e7f..025e0b3 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -231,7 +231,7 @@ error::Error GLES2DecoderImpl::HandleBufferSubData( if (data == NULL) { return error::kOutOfBounds; } - DoBufferSubData(target, offset, size, data); + glBufferSubData(target, offset, size, data); return error::kNoError; } @@ -254,7 +254,7 @@ error::Error GLES2DecoderImpl::HandleBufferSubDataImmediate( if (data == NULL) { return error::kOutOfBounds; } - DoBufferSubData(target, offset, size, data); + glBufferSubData(target, offset, size, data); return error::kNoError; } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 9228165..5f96cd5 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -194,12 +194,12 @@ TEST_F(GLES2DecoderWithShaderTest, DrawElementsNoAttributesSucceeds) { SetupIndexBuffer(); EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT, - BufferOffset(kValidIndexRangeStart * 2))) + BufferOffset(kValidIndexRangeStart))) .Times(1) .RetiresOnSaturation(); DrawElements cmd; cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT, - kValidIndexRangeStart * 2); + kValidIndexRangeStart); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } @@ -212,7 +212,7 @@ TEST_F(GLES2DecoderWithShaderTest, DrawElementsMissingAttributesFails) { .Times(0); DrawElements cmd; cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT, - kValidIndexRangeStart * 2); + kValidIndexRangeStart); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } @@ -225,12 +225,12 @@ TEST_F(GLES2DecoderWithShaderTest, DrawElementsValidAttributesSucceeds) { EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT, - BufferOffset(kValidIndexRangeStart * 2))) + BufferOffset(kValidIndexRangeStart))) .Times(1) .RetiresOnSaturation(); DrawElements cmd; cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT, - kValidIndexRangeStart * 2); + kValidIndexRangeStart); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } @@ -245,7 +245,7 @@ TEST_F(GLES2DecoderWithShaderTest, DrawElementsDeletedBufferFails) { .Times(0); DrawElements cmd; cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT, - kValidIndexRangeStart * 2); + kValidIndexRangeStart); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } @@ -260,7 +260,7 @@ TEST_F(GLES2DecoderWithShaderTest, DrawElementsDeletedProgramSucceedsNoGLCall) { .Times(0); DrawElements cmd; cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT, - kValidIndexRangeStart * 2); + kValidIndexRangeStart); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } @@ -274,7 +274,7 @@ TEST_F(GLES2DecoderWithShaderTest, DrawElementsWithInvalidModeFails) { .Times(0); DrawElements cmd; cmd.Init(GL_QUADS, kValidIndexRangeCount, GL_UNSIGNED_SHORT, - kValidIndexRangeStart * 2); + kValidIndexRangeStart); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); cmd.Init(GL_POLYGON, kValidIndexRangeCount, GL_UNSIGNED_SHORT, @@ -291,7 +291,7 @@ TEST_F(GLES2DecoderWithShaderTest, DrawElementsInvalidCountFails) { // Try start > 0 EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0); DrawElements cmd; - cmd.Init(GL_TRIANGLES, kNumIndices, GL_UNSIGNED_SHORT, 2); + cmd.Init(GL_TRIANGLES, kNumIndices, GL_UNSIGNED_SHORT, 1); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); EXPECT_EQ(GL_NO_ERROR, GetGLError()); @@ -303,6 +303,7 @@ TEST_F(GLES2DecoderWithShaderTest, DrawElementsInvalidCountFails) { EXPECT_EQ(GL_NO_ERROR, GetGLError()); } +#if 0 // TODO(gman): Turn on this test once buffer validation is in TEST_F(GLES2DecoderWithShaderTest, DrawElementsOutOfRangeIndicesFails) { SetupVertexBuffer(); SetupIndexBuffer(); @@ -311,24 +312,12 @@ TEST_F(GLES2DecoderWithShaderTest, DrawElementsOutOfRangeIndicesFails) { EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0); DrawElements cmd; cmd.Init(GL_TRIANGLES, kInvalidIndexRangeCount, GL_UNSIGNED_SHORT, - kInvalidIndexRangeStart * 2); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} - -TEST_F(GLES2DecoderWithShaderTest, DrawElementsOddOffsetForUint16Fails) { - SetupVertexBuffer(); - SetupIndexBuffer(); - DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0); - - EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0); - DrawElements cmd; - cmd.Init(GL_TRIANGLES, kInvalidIndexRangeCount, GL_UNSIGNED_SHORT, 1); + kInvalidIndexRangeStart); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } +#endif TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervSucceeds) { const float dummy = 0; @@ -1001,18 +990,6 @@ TEST_F(GLES2DecoderWithShaderTest, Uniform1ivImmediateValidArgs) { ExecuteImmediateCmd(cmd, sizeof(temp))); } -TEST_F(GLES2DecoderWithShaderTest, BindBufferToDifferentTargetFails) { - // Bind the buffer to GL_ARRAY_BUFFER - DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); - // Attempt to rebind to GL_ELEMENT_ARRAY_BUFFER - // NOTE: Real GLES2 does not have this restriction but WebGL and we do. - EXPECT_CALL(*gl_, BindBuffer(_, _)) - .Times(0); - BindBuffer cmd; - cmd.Init(GL_ELEMENT_ARRAY_BUFFER, client_buffer_id_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); -} // TODO(gman): BindAttribLocation |