summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-05 05:16:23 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-05 05:16:23 +0000
commit3b6ec20aec909735d1f8b69c1088f256fe36c2a4 (patch)
tree39042b6f8402b8b7aac4d8bb6a2a8f565fd137ca /gpu/command_buffer
parenta6eb5232d2608cd0773bbe559757bd52c7f53670 (diff)
downloadchromium_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-xgpu/command_buffer/build_gles2_cmd_buffer.py99
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils.h5
-rw-r--r--gpu/command_buffer/service/buffer_manager.cc95
-rw-r--r--gpu/command_buffer/service/buffer_manager.h79
-rw-r--r--gpu/command_buffer/service/buffer_manager_unittest.cc83
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc112
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h4
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc47
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), &params_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